Index: src/OFFileIRIHandler.m ================================================================== --- src/OFFileIRIHandler.m +++ src/OFFileIRIHandler.m @@ -1562,7 +1562,31 @@ objc_autoreleasePoolPop(pool); return [data autorelease]; } + +- (void)setExtendedAttributeData: (OFData *)data + forName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI +{ + void *pool = objc_autoreleasePoolPush(); + OFString *path = IRI.fileSystemRepresentation; + OFStringEncoding encoding = [OFLocale encoding]; + + if (lsetxattr([path cStringWithEncoding: encoding], + [name cStringWithEncoding: encoding], data.items, + data.count * data.itemSize, 0) != 0) { + int errNo = errno; + + /* TODO: Add an attribute (prefix?) for extended attributes? */ + @throw [OFSetItemAttributesFailedException + exceptionWithIRI: IRI + attributes: [OFDictionary dictionary] + failedAttribute: @"" + errNo: errNo]; + } + + objc_autoreleasePoolPop(pool); +} #endif @end Index: src/OFFileManager.h ================================================================== --- src/OFFileManager.h +++ src/OFFileManager.h @@ -684,24 +684,26 @@ - (void)createSymbolicLinkAtIRI: (OFIRI *)IRI withDestinationPath: (OFString *)target; #ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES /** - * @brief Returns the extended attribute with the specified name for the + * @brief Returns the extended attribute data for the specified name for the * specified path. * * @param name The name of the extended attribute * @param path The path of the item to return the extended attribute from * @throw OFGetItemAttributesFailedException Getting the extended attribute * failed + * @throw OFNotImplementedException Getting extended attributes is not + * implemented for the specified item */ -- (OFData *)extendedAttributeForName: (OFString *)name - ofItemAtPath: (OFString *)path; +- (OFData *)extendedAttributeDataForName: (OFString *)name + ofItemAtPath: (OFString *)path; #endif /** - * @brief Returns the extended attribute with the specified name for the + * @brief Returns the extended attribute data for the specified name for the * specified IRI. * * This method is not available for all IRIs. * * @param name The name of the extended attribute @@ -708,13 +710,55 @@ * @param IRI The IRI of the item to return the extended attribute from * @throw OFGetItemAttributesFailedException Getting the extended attribute * failed * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme + * @throw OFNotImplementedException Getting extended attributes is not + * implemented for the specified item + */ +- (OFData *)extendedAttributeDataForName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI; + +#ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES +/** + * @brief Sets the extended attribute data for the specified name for the + * specified IRI. + * + * This method is not available for all IRIS. + * + * @param data The data for the extended attribute + * @param name The name of the extended attribute + * @param path The path of the item to set the extended attribute on + * @throw OFSetItemAttributesFailedException Setting the extended attribute + * failed + * @throw OFNotImplementedException Setting extended attributes is not + * implemented for the specified item + */ +- (void)setExtendedAttributeData: (OFData *)data + forName: (OFString *)name + ofItemAtPath: (OFString *)path; +#endif + +/** + * @brief Sets the extended attribute data for the specified name for the + * specified IRI. + * + * This method is not available for all IRIS. + * + * @param data The data for the extended attribute + * @param name The name of the extended attribute + * @param IRI The IRI of the item to set the extended attribute on + * @throw OFSetItemAttributesFailedException Setting the extended attribute + * failed + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's + * scheme + * @throw OFNotImplementedException Setting extended attributes is not + * implemented for the specified item */ -- (OFData *)extendedAttributeForName: (OFString *)name - ofItemAtIRI: (OFIRI *)IRI; +- (void)setExtendedAttributeData: (OFData *)data + forName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI; @end @interface OFDictionary (FileAttributes) /** * @brief The @ref OFFileSize key from the dictionary. Index: src/OFFileManager.m ================================================================== --- src/OFFileManager.m +++ src/OFFileManager.m @@ -197,12 +197,12 @@ { void *pool = objc_autoreleasePoolPush(); OFIRI *ret; ret = [OFIRI fileIRIWithPath: self.currentDirectoryPath]; + ret = [ret retain]; - [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } #endif @@ -224,12 +224,11 @@ { void *pool = objc_autoreleasePoolPush(); OFFileAttributes ret; ret = [self attributesOfItemAtIRI: [OFIRI fileIRIWithPath: path]]; - - [ret retain]; + ret = [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @@ -454,11 +453,11 @@ for (OFIRI *IRI in IRIs) [ret addObject: IRI.lastPathComponent]; [ret makeImmutable]; - [ret retain]; + ret = [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @@ -484,11 +483,11 @@ objc_autoreleasePoolPop(pool2); } [ret makeImmutable]; - [ret retain]; + ret = [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @@ -888,37 +887,69 @@ withDestinationPath: target]; objc_autoreleasePoolPop(pool); } #endif -- (OFData *)extendedAttributeForName: (OFString *)name ofItemAtIRI: (OFIRI *)IRI +- (OFData *)extendedAttributeDataForName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI +{ + OFIRIHandler *IRIHandler; + + if (IRI == nil) + @throw [OFInvalidArgumentException exception]; + + if ((IRIHandler = [OFIRIHandler handlerForIRI: IRI]) == nil) + @throw [OFUnsupportedProtocolException exceptionWithIRI: IRI]; + + return [IRIHandler extendedAttributeDataForName: name ofItemAtIRI: IRI]; +} + +#ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES +- (OFData *)extendedAttributeDataForName: (OFString *)name + ofItemAtPath: (OFString *)path +{ + void *pool = objc_autoreleasePoolPush(); + OFData *ret; + + ret = [self + extendedAttributeDataForName: name + ofItemAtIRI: [OFIRI fileIRIWithPath: path]]; + ret = [ret retain]; + + objc_autoreleasePoolPop(pool); + + return [ret autorelease]; +} +#endif + +- (void)setExtendedAttributeData: (OFData *)data + forName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI { OFIRIHandler *IRIHandler; if (IRI == nil) @throw [OFInvalidArgumentException exception]; if ((IRIHandler = [OFIRIHandler handlerForIRI: IRI]) == nil) @throw [OFUnsupportedProtocolException exceptionWithIRI: IRI]; - return [IRIHandler extendedAttributeForName: name ofItemAtIRI: IRI]; + [IRIHandler setExtendedAttributeData: data + forName: name + ofItemAtIRI: IRI]; } #ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES -- (OFData *)extendedAttributeForName: (OFString *)name - ofItemAtPath: (OFString *)path +- (void)setExtendedAttributeData: (OFData *)data + forName: (OFString *)name + ofItemAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); - OFData *ret; - - ret = [self extendedAttributeForName: name - ofItemAtIRI: [OFIRI fileIRIWithPath: path]]; - [ret retain]; - + [self setExtendedAttributeData: data + forName: name + ofItemAtIRI: [OFIRI fileIRIWithPath: path]]; objc_autoreleasePoolPop(pool); - - return [ret autorelease]; } #endif @end @implementation OFDefaultFileManager Index: src/OFIRIHandler.h ================================================================== --- src/OFIRIHandler.h +++ src/OFIRIHandler.h @@ -148,11 +148,11 @@ * @@throw OFSetItemAttributesFailedException Failed to set the attributes of * the item * @throw OFUnsupportedProtocolException The handler cannot handle the IRI's * scheme * @throw OFNotImplementedException Setting one or more of the specified - * attributes is not implpemented for the + * attributes is not implemented for the * specified item */ - (void)setAttributes: (OFFileAttributes)attributes ofItemAtIRI: (OFIRI *)IRI; /** @@ -301,11 +301,33 @@ * * @param name The name of the extended attribute * @param IRI The IRI of the item to return the extended attribute from * @throw OFGetItemAttributesFailedException Getting the extended attribute * failed + * @throw OFNotImplementedException Getting extended attributes is not + * implemented for the specified item + */ +- (OFData *)extendedAttributeDataForName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI; + +/** + * @brief Sets the extended attribute data for the specified name for the + * specified IRI. + * + * This method is not available for all IRIS. + * + * @param data The data for the extended attribute + * @param name The name of the extended attribute + * @param IRI The IRI of the item to set the extended attribute on + * @throw OFSetItemAttributesFailedException Setting the extended attribute + * failed + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's + * scheme + * @throw OFNotImplementedException Setting extended attributes is not + * implemented for the specified item */ -- (OFData *)extendedAttributeForName: (OFString *)name - ofItemAtIRI: (OFIRI *)IRI; +- (void)setExtendedAttributeData: (OFData *)data + forName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI; @end OF_ASSUME_NONNULL_END Index: src/OFIRIHandler.m ================================================================== --- src/OFIRIHandler.m +++ src/OFIRIHandler.m @@ -212,10 +212,18 @@ - (bool)moveItemAtIRI: (OFIRI *)source toIRI: (OFIRI *)destination { return false; } -- (OFData *)extendedAttributeForName: (OFString *)name ofItemAtIRI: (OFIRI *)IRI +- (OFData *)extendedAttributeDataForName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (void)setExtendedAttributeData: (OFData *)data + forName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI { - return nil; + OF_UNRECOGNIZED_SELECTOR } @end