Pushr (master) :  summary log tree commit diff
path: root/ExtendedAttributes.m blob: 776e8d22c1b0fc3687ae61d43b21ccd8cadc5ae6
1//
2// ExtendedAttributes.m, based on UKXattrMetadataStore.m
3//
4// License: MIT <http://opensource.org/licenses/mit-license.php>
5//
6// Modified by Chris Lee <clee@mg8.org>
7// Originally created by Uli Kusterer on 12.03.06.
8// Copyright 2006 Uli Kusterer. All rights reserved.
9//
10
11#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
12// -----------------------------------------------------------------------------
13// Headers:
14// -----------------------------------------------------------------------------
15
16#import "ExtendedAttributes.h"
17#import <sys/xattr.h>
18
19
20@implementation ExtendedAttributes
21
22// -----------------------------------------------------------------------------
23// allKeysAtPath:
24// Return an NSArray of NSStrings containing all xattr names currently set
25// for the file at the specified path.
26// -----------------------------------------------------------------------------
27
28+ (NSArray *)allKeysAtPath: (NSString *)path
29{
30 NSMutableArray* allKeys = [NSMutableArray array];
31 size_t dataSize = listxattr([path fileSystemRepresentation], NULL, ULONG_MAX, 0);
32 if (dataSize == ULONG_MAX)
33 return allKeys; // Empty list.
34
35 NSMutableData* listBuffer = [NSMutableData dataWithLength: dataSize];
36 dataSize = listxattr([path fileSystemRepresentation], [listBuffer mutableBytes], [listBuffer length], 0);
37 char* nameStart = [listBuffer mutableBytes];
38 int x;
39 for (x = 0; x < dataSize; x++) {
40 if (((char*)[listBuffer mutableBytes])[x] == 0) {
41 NSString* str = [NSString stringWithUTF8String: nameStart];
42 nameStart = [listBuffer mutableBytes] + x + 1;
43 [allKeys addObject: str];
44 }
45 }
46
47 return allKeys;
48}
49
50
51// -----------------------------------------------------------------------------
52// setData:forKey:atPath:
53// Set the xattr with name key to a block of raw binary data.
54// path is the file whose xattr you want to set.
55// -----------------------------------------------------------------------------
56
57+ (void)setData: (NSData *)data forKey: (NSString *)key atPath: (NSString *)path
58{
59 setxattr([path fileSystemRepresentation], [key UTF8String], [data bytes], [data length], 0, 0);
60}
61
62
63// -----------------------------------------------------------------------------
64// setObject:forKey:atPath:
65// Set the xattr with name key to an XML property list representation of
66// the specified object (or object graph).
67// path is the file whose xattr you want to set.
68// -----------------------------------------------------------------------------
69
70+ (void)setObject: (id)obj forKey: (NSString *)key atPath: (NSString *)path
71{
72 // Serialize our objects into a property list XML string:
73 NSString* errMsg = nil;
74 NSData* plistData = [NSPropertyListSerialization dataFromPropertyList: obj
75 format: NSPropertyListXMLFormat_v1_0
76 errorDescription: &errMsg];
77 if (errMsg) {
78 [errMsg autorelease];
79 [NSException raise: @"UKXattrMetastoreCantSerialize" format: @"%@", errMsg];
80 }
81 else
82 [[self class] setData: plistData forKey: key atPath: path];
83}
84
85
86// -----------------------------------------------------------------------------
87// setString:forKey:atPath:
88// Set the xattr with name key to an XML property list representation of
89// the specified object (or object graph).
90// path is the file whose xattr you want to set.
91// -----------------------------------------------------------------------------
92
93+ (void)setString: (NSString *)str forKey: (NSString *)key atPath: (NSString *)path
94{
95 NSData *data = [str dataUsingEncoding: NSUTF8StringEncoding];
96
97 if (!data)
98 [NSException raise: NSCharacterConversionException format: @"Couldn't convert string to UTF8 for xattr storage."];
99
100 [[self class] setData: data forKey: key atPath: path];
101}
102
103
104// -----------------------------------------------------------------------------
105// dataForKey:atPath:
106// Retrieve the xattr with name key as a raw block of data.
107// path is the file whose xattr you want to set.
108// -----------------------------------------------------------------------------
109
110+ (NSMutableData *)dataForKey: (NSString *)key atPath: (NSString *)path
111{
112 size_t dataSize = getxattr([path fileSystemRepresentation], [key UTF8String], NULL, ULONG_MAX, 0, 0);
113 if (dataSize == ULONG_MAX)
114 return nil;
115 NSMutableData *data = [NSMutableData dataWithLength: dataSize];
116 getxattr([path fileSystemRepresentation], [key UTF8String], [data mutableBytes], [data length], 0, 0);
117 return data;
118}
119
120
121// -----------------------------------------------------------------------------
122// objectForKey:atPath:
123// Retrieve the xattr with name key, which is an XML property list
124// and unserialize it back into an object or object graph.
125// path is the file whose xattr you want to set.
126// -----------------------------------------------------------------------------
127
128+ (id)objectForKey: (NSString *)key atPath: (NSString *)path
129{
130 NSString *errMsg = nil;
131 NSMutableData *data = [[self class] dataForKey: key atPath: path];
132 NSPropertyListFormat outFormat = NSPropertyListXMLFormat_v1_0;
133 id obj = [NSPropertyListSerialization propertyListFromData: data mutabilityOption: NSPropertyListImmutable format: &outFormat errorDescription: &errMsg];
134 if (errMsg) {
135 [errMsg autorelease];
136 [NSException raise: @"UKXattrMetastoreCantUnserialize" format: @"%@", errMsg];
137 }
138
139 return obj;
140}
141
142
143// -----------------------------------------------------------------------------
144// stringForKey:atPath:
145// Retrieve the xattr with name key, which is an XML property list
146// and unserialize it back into an object or object graph.
147// path is the file whose xattr you want to set.
148// -----------------------------------------------------------------------------
149
150+ (id)stringForKey: (NSString *)key atPath: (NSString *)path
151{
152 NSMutableData *data = [[self class] dataForKey: key atPath: path];
153 return [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease];
154}
155
156
157@end
158
159#endif /*MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4*/
160