Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 0ed4c83d27
Fetching contributors…

Cannot retrieve contributors at this time

205 lines (170 sloc) 7.66 kb
//
// UKXattrMetadataStore.m
// BubbleBrowser
//
// Created by Uli Kusterer on 12.03.06.
// Copyright 2006 Uli Kusterer.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#import "UKXattrMetadataStore.h"
#import <sys/xattr.h>
@implementation UKXattrMetadataStore
// -----------------------------------------------------------------------------
// allKeysAtPath:traverseLink:
// Return an NSArray of NSStrings containing all xattr names currently set
// for the file at the specified path.
// If travLnk == YES, it follows symlinks.
// -----------------------------------------------------------------------------
+(NSArray*) allKeysAtPath: (NSString*)path traverseLink:(BOOL)travLnk
{
NSMutableArray* allKeys = [NSMutableArray array];
size_t dataSize = listxattr( [path fileSystemRepresentation],
NULL, ULONG_MAX,
(travLnk ? 0 : XATTR_NOFOLLOW) );
if( dataSize == ULONG_MAX )
return allKeys; // Empty list.
NSMutableData* listBuffer = [NSMutableData dataWithLength: dataSize];
dataSize = listxattr( [path fileSystemRepresentation],
[listBuffer mutableBytes], [listBuffer length],
(travLnk ? 0 : XATTR_NOFOLLOW) );
char* nameStart = [listBuffer mutableBytes];
int x;
for( x = 0; x < dataSize; x++ )
{
if( ((char*)[listBuffer mutableBytes])[x] == 0 ) // End of string.
{
NSString* str = [NSString stringWithUTF8String: nameStart];
nameStart = [listBuffer mutableBytes] +x +1;
[allKeys addObject: str];
}
}
return allKeys;
}
// -----------------------------------------------------------------------------
// setData:forKey:atPath:traverseLink:
// Set the xattr with name key to a block of raw binary data.
// path is the file whose xattr you want to set.
// If travLnk == YES, it follows symlinks.
// -----------------------------------------------------------------------------
+(void) setData: (NSData*)data forKey: (NSString*)key atPath: (NSString*)path traverseLink:(BOOL)travLnk
{
setxattr( [path fileSystemRepresentation], [key UTF8String],
[data bytes], [data length],
0, (travLnk ? 0 : XATTR_NOFOLLOW) );
}
// -----------------------------------------------------------------------------
// setObject:forKey:atPath:traverseLink:
// Set the xattr with name key to an XML property list representation of
// the specified object (or object graph).
// path is the file whose xattr you want to set.
// If travLnk == YES, it follows symlinks.
// -----------------------------------------------------------------------------
+(void) setObject: (id)obj forKey: (NSString*)key atPath: (NSString*)path traverseLink:(BOOL)travLnk
{
// Serialize our objects into a property list XML string:
NSString* errMsg = nil;
NSData* plistData = [NSPropertyListSerialization dataFromPropertyList: obj
format: NSPropertyListXMLFormat_v1_0
errorDescription: &errMsg];
if( errMsg )
{
[errMsg autorelease];
[NSException raise: @"UKXattrMetastoreCantSerialize" format: @"%@", errMsg];
}
else
[[self class] setData: plistData forKey: key atPath: path traverseLink: travLnk];
}
// -----------------------------------------------------------------------------
// setString:forKey:atPath:traverseLink:
// Set the xattr with name key to an XML property list representation of
// the specified object (or object graph).
// path is the file whose xattr you want to set.
// If travLnk == YES, it follows symlinks.
// -----------------------------------------------------------------------------
+(void) setString: (NSString*)str forKey: (NSString*)key atPath: (NSString*)path traverseLink:(BOOL)travLnk
{
NSData* data = [str dataUsingEncoding: NSUTF8StringEncoding];
if( !data )
[NSException raise: NSCharacterConversionException format: @"Couldn't convert string to UTF8 for xattr storage."];
[[self class] setData: data forKey: key atPath: path traverseLink: travLnk];
}
// -----------------------------------------------------------------------------
// dataForKey:atPath:traverseLink:
// Retrieve the xattr with name key as a raw block of data.
// path is the file whose xattr you want to set.
// If travLnk == YES, it follows symlinks.
// -----------------------------------------------------------------------------
+(NSMutableData*) dataForKey: (NSString*)key atPath: (NSString*)path traverseLink:(BOOL)travLnk
{
size_t dataSize = getxattr( [path fileSystemRepresentation], [key UTF8String],
NULL, ULONG_MAX, 0, (travLnk ? 0 : XATTR_NOFOLLOW) );
if( dataSize == ULONG_MAX )
return nil;
NSMutableData* data = [NSMutableData dataWithLength: dataSize];
getxattr( [path fileSystemRepresentation], [key UTF8String],
[data mutableBytes], [data length], 0, (travLnk ? 0 : XATTR_NOFOLLOW) );
return data;
}
// -----------------------------------------------------------------------------
// objectForKey:atPath:traverseLink:
// Retrieve the xattr with name key, which is an XML property list
// and unserialize it back into an object or object graph.
// path is the file whose xattr you want to set.
// If travLnk == YES, it follows symlinks.
// -----------------------------------------------------------------------------
+(id) objectForKey: (NSString*)key atPath: (NSString*)path traverseLink:(BOOL)travLnk
{
NSString* errMsg = nil;
NSMutableData* data = [[self class] dataForKey: key atPath: path traverseLink: travLnk];
if( !data )
return nil;
NSPropertyListFormat outFormat = NSPropertyListXMLFormat_v1_0;
id obj = [NSPropertyListSerialization propertyListFromData: data
mutabilityOption: NSPropertyListImmutable
format: &outFormat
errorDescription: &errMsg];
if( errMsg )
{
[errMsg autorelease];
[NSException raise: @"UKXattrMetastoreCantUnserialize" format: @"%@", errMsg];
}
return obj;
}
// -----------------------------------------------------------------------------
// stringForKey:atPath:traverseLink:
// Retrieve the xattr with name key, which is an XML property list
// and unserialize it back into an object or object graph.
// path is the file whose xattr you want to set.
// If travLnk == YES, it follows symlinks.
// -----------------------------------------------------------------------------
+(id) stringForKey: (NSString*)key atPath: (NSString*)path traverseLink:(BOOL)travLnk
{
NSMutableData* data = [[self class] dataForKey: key atPath: path traverseLink: travLnk];
if( !data )
return nil;
return [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease];
}
@end
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4*/
Jump to Line
Something went wrong with that request. Please try again.