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) {
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) {
85 if (size - pos < size_preamble)
87 memcpy(&entry, inbuf + pos, size_preamble);
88 if (size - pos < entry.
GetSize())
90 if (entry.
GetSize() == size_preamble)
93 memcpy(entry.
data, inbuf + pos, entry.
GetSize() - size_preamble);
94 pos += entry.
GetSize() - size_preamble;
104 return xattrs_.find(key) != xattrs_.end();
110 map<string, string>::const_iterator iter = xattrs_.find(key);
111 if (iter != xattrs_.end()) {
112 *value = iter->second;
120 vector<string> result;
121 for (map<string, string>::const_iterator i = xattrs_.begin(),
122 iEnd = xattrs_.end();
125 result.push_back(i->first);
140 if (!merge_with.empty()) {
141 vector<string> merge_list =
SplitString(merge_with,
'\0');
142 for (
unsigned i = 0; i < merge_list.size(); ++i) {
143 if (merge_list[i].empty())
145 if (xattrs_.find(merge_list[i]) == xattrs_.end()) {
146 result += merge_list[i];
147 result.push_back(
'\0');
151 for (map<string, string>::const_iterator i = xattrs_.begin(),
152 iEnd = xattrs_.end();
156 result.push_back(
'\0');
165 if (key.length() > 256)
167 if (key.find(
'\0') != string::npos)
169 if (value.length() > 256)
172 map<string, string>::iterator iter = xattrs_.find(key);
173 if (iter != xattrs_.end()) {
174 iter->second = value;
176 if (xattrs_.size() >= 256)
178 xattrs_[key] = value;
185 map<string, string>::iterator iter = xattrs_.find(key);
186 if (iter != xattrs_.end()) {
200 const std::vector<std::string> *blacklist)
const {
201 if (xattrs_.empty()) {
208 uint32_t packed_size =
sizeof(header);
212 smalloc(header.num_xattrs *
sizeof(
XattrEntry)));
213 unsigned ientries = 0;
214 for (map<string, string>::const_iterator it_att = xattrs_.begin(),
215 it_att_end = xattrs_.end();
216 it_att != it_att_end;
219 if (blacklist != NULL) {
221 for (
unsigned i_bl = 0; i_bl < blacklist->size(); ++i_bl) {
222 if (
HasPrefix(it_att->first, (*blacklist)[i_bl],
232 new (entries + ientries)
XattrEntry(it_att->first, it_att->second);
233 packed_size += entries[ientries].
GetSize();
246 header.num_xattrs = ientries;
248 *outbuf =
reinterpret_cast<unsigned char *
>(smalloc(packed_size));
249 memcpy(*outbuf, &header,
sizeof(header));
250 unsigned pos =
sizeof(header);
251 for (
unsigned i = 0; i < header.num_xattrs; ++i) {
252 memcpy(*outbuf + pos, &entries[i], entries[i].GetSize());
266 return string(data, len_key);
271 return sizeof(len_key) +
sizeof(len_value) + uint16_t(len_key)
272 + uint16_t(len_value);
279 return string(&data[len_key], len_value);
284 : 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)