10 #include <sys/xattr.h>
36 if ((sz_list < 0) || (sz_list > 64 * 1024)) {
38 }
else if (sz_list == 0) {
42 list =
reinterpret_cast<char *
>(alloca(sz_list));
46 }
else if (sz_list == 0) {
51 vector<string> keys =
SplitString(
string(list, sz_list),
'\0');
56 for (
unsigned i = 0; i < keys.size(); ++i) {
59 const ssize_t sz_value =
63 result->
Set(keys[i],
string(value, sz_value));
70 const unsigned size) {
78 memcpy(&header, inbuf,
sizeof(header));
81 unsigned pos =
sizeof(header);
82 for (
unsigned i = 0; i < header.
num_xattrs; ++i) {
84 unsigned size_preamble =
86 if (size - pos < size_preamble)
88 memcpy(&entry, inbuf + pos, size_preamble);
89 if (size - pos < entry.
GetSize())
91 if (entry.
GetSize() == size_preamble)
94 memcpy(entry.
data, inbuf + pos, entry.
GetSize() - size_preamble);
95 pos += entry.
GetSize() - size_preamble;
105 return xattrs_.find(key) != xattrs_.end();
111 const map<string, string>::const_iterator iter = xattrs_.find(key);
112 if (iter != xattrs_.end()) {
113 *value = iter->second;
121 vector<string> result;
122 for (map<string, string>::const_iterator i = xattrs_.begin(),
123 iEnd = xattrs_.end();
126 result.push_back(i->first);
141 if (!merge_with.empty()) {
142 vector<string> merge_list =
SplitString(merge_with,
'\0');
143 for (
unsigned i = 0; i < merge_list.size(); ++i) {
144 if (merge_list[i].empty())
146 if (xattrs_.find(merge_list[i]) == xattrs_.end()) {
147 result += merge_list[i];
148 result.push_back(
'\0');
152 for (map<string, string>::const_iterator i = xattrs_.begin(),
153 iEnd = xattrs_.end();
157 result.push_back(
'\0');
166 if (key.length() > 256)
168 if (key.find(
'\0') != string::npos)
170 if (value.length() > 256)
173 const map<string, string>::iterator iter = xattrs_.find(key);
174 if (iter != xattrs_.end()) {
175 iter->second = value;
177 if (xattrs_.size() >= 256)
179 xattrs_[key] = value;
186 const map<string, string>::iterator iter = xattrs_.find(key);
187 if (iter != xattrs_.end()) {
201 const std::vector<std::string> *blacklist)
const {
202 if (xattrs_.empty()) {
209 uint32_t packed_size =
sizeof(header);
213 smalloc(header.num_xattrs *
sizeof(
XattrEntry)));
214 unsigned ientries = 0;
215 for (map<string, string>::const_iterator it_att = xattrs_.begin(),
216 it_att_end = xattrs_.end();
217 it_att != it_att_end;
220 if (blacklist != NULL) {
222 for (
unsigned i_bl = 0; i_bl < blacklist->size(); ++i_bl) {
223 if (
HasPrefix(it_att->first, (*blacklist)[i_bl],
233 new (entries + ientries)
XattrEntry(it_att->first, it_att->second);
234 packed_size += entries[ientries].
GetSize();
247 header.num_xattrs = ientries;
249 *outbuf =
reinterpret_cast<unsigned char *
>(smalloc(packed_size));
250 memcpy(*outbuf, &header,
sizeof(header));
251 unsigned pos =
sizeof(header);
252 for (
unsigned i = 0; i < header.num_xattrs; ++i) {
253 memcpy(*outbuf + pos, &entries[i], entries[i].GetSize());
267 return string(data, len_key);
272 return sizeof(len_key) +
sizeof(len_value) + uint16_t(len_key)
273 + uint16_t(len_value);
280 return string(&data[len_key], len_value);
285 : len_key(key.
size()), len_value(value.
size()) {
std::string ListKeysPosix(const std::string &merge_with) const
bool Set(const std::string &key, const std::string &value)
assert((mem||(size==0))&&"Out Of Memory")
bool Get(const std::string &key, std::string *value) const
vector< string > SplitString(const string &str, char delim)
std::string GetValue() const
void Serialize(unsigned char **outbuf, unsigned *size, const std::vector< std::string > *blacklist=NULL) const
bool Has(const std::string &key) const
std::string GetKey() const
bool HasPrefix(const string &str, const string &prefix, const bool ignore_case)
static XattrList * Deserialize(const unsigned char *inbuf, const unsigned size)
static XattrList * CreateFromFile(const std::string &path)
static const uint8_t kVersion
std::vector< std::string > ListKeys() const
bool Remove(const std::string &key)