@@ -1,7 +1,7 @@ /* - * Copyright (c) 2008-2022 Jonathan Schleifer + * Copyright (c) 2008-2024 Jonathan Schleifer * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in @@ -19,34 +19,39 @@ OF_ASSUME_NONNULL_BEGIN /** @file */ #ifdef OF_HAVE_FILES -# if defined(OF_HAVE_CHMOD) && !defined(OF_AMIGAOS) +# if (defined(OF_HAVE_CHMOD) && !defined(OF_AMIGAOS)) || defined(DOXYGEN) # define OF_FILE_MANAGER_SUPPORTS_PERMISSIONS # endif -# if defined(OF_HAVE_CHOWN) && !defined(OF_AMIGAOS) +# if (defined(OF_HAVE_CHOWN) && !defined(OF_AMIGAOS)) || defined(DOXYGEN) # define OF_FILE_MANAGER_SUPPORTS_OWNER # endif -# if (defined(OF_HAVE_LINK) && !defined(OF_AMIGAOS)) || defined(OF_WINDOWS) +# if (defined(OF_HAVE_LINK) && !defined(OF_AMIGAOS)) || defined(OF_WINDOWS) || \ + defined(DOXYGEN) # define OF_FILE_MANAGER_SUPPORTS_LINKS # endif -# if (defined(OF_HAVE_SYMLINK) && !defined(OF_AMIGAOS)) || defined(OF_WINDOWS) +# if (defined(OF_HAVE_SYMLINK) && !defined(OF_AMIGAOS)) || \ + defined(OF_WINDOWS) || defined(DOXYGEN) # define OF_FILE_MANAGER_SUPPORTS_SYMLINKS +# endif +# if defined(OF_LINUX) || defined(OF_MACOS) || defined(DOXYGEN) +# define OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES # endif #endif @class OFArray OF_GENERIC(ObjectType); @class OFConstantString; @class OFDate; +@class OFIRI; @class OFString; -@class OFURI; /** * @brief A key for a file attribute in the file attributes dictionary. * - * Possible keys for file URIs are: + * Possible keys for file IRIs are: * * * @ref OFFileSize * * @ref OFFileType * * @ref OFFilePOSIXPermissions * * @ref OFFileOwnerAccountID @@ -56,19 +61,20 @@ * * @ref OFFileLastAccessDate * * @ref OFFileModificationDate * * @ref OFFileStatusChangeDate * * @ref OFFileCreationDate * * @ref OFFileSymbolicLinkDestination + * * @ref OFFileExtendedAttributesNames * - * Other URI schemes might not have all keys and might have keys not listed. + * Other IRI schemes might not have all keys and might have keys not listed. */ typedef OFConstantString *OFFileAttributeKey; /** * @brief The type of a file. * - * Possibles values for file URIs are: + * Possibles values for file IRIs are: * * * @ref OFFileTypeRegular * * @ref OFFileTypeDirectory * * @ref OFFileTypeSymbolicLink * * @ref OFFileTypeFIFO @@ -75,11 +81,11 @@ * * @ref OFFileTypeCharacterSpecial * * @ref OFFileTypeBlockSpecial * * @ref OFFileTypeSocket * * @ref OFFileTypeUnknown * - * Other URI schemes might not have all types and might have types not listed. + * Other IRI schemes might not have all types and might have types not listed. */ typedef OFConstantString *OFFileAttributeType; /** * @brief A dictionary mapping keys of type @ref OFFileAttributeKey to their @@ -186,17 +192,26 @@ * via @ref OFDictionary#fileCreationDate. */ extern const OFFileAttributeKey OFFileCreationDate; /** - * @brief The destination of a symbolic link as an OFString. + * @brief The destination of a symbolic link as an @ref OFString. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileSymbolicLinkDestination. */ extern const OFFileAttributeKey OFFileSymbolicLinkDestination; +/** + * @brief The names of the extended attributes as an @ref OFArray of + * @ref OFString. + * + * For convenience, a category on @ref OFDictionary is provided to access this + * via @ref OFDictionary#fileExtendedAttributesNames. + */ +extern const OFFileAttributeKey OFFileExtendedAttributesNames; + /** * @brief A regular file. */ extern const OFFileAttributeType OFFileTypeRegular; @@ -263,15 +278,15 @@ * @throw OFGetCurrentDirectoryFailedException Couldn't get current directory */ @property (readonly, nonatomic) OFString *currentDirectoryPath; /** - * @brief The URI of the current working directory. + * @brief The IRI of the current working directory. * * @throw OFGetCurrentDirectoryFailedException Couldn't get current directory */ -@property (readonly, nonatomic) OFURI *currentDirectoryURI; +@property (readonly, nonatomic) OFIRI *currentDirectoryIRI; #endif /** * @brief Returns the default file manager. */ @@ -289,21 +304,21 @@ */ - (OFFileAttributes)attributesOfItemAtPath: (OFString *)path; #endif /** - * @brief Returns the attributes for the item at the specified URI. + * @brief Returns the attributes for the item at the specified IRI. * - * @param URI The URI to return the attributes for - * @return A dictionary of attributes for the specified URI, with the keys of + * @param IRI The IRI to return the attributes for + * @return A dictionary of attributes for the specified IRI, with the keys of * type @ref OFFileAttributeKey * @throw OFGetItemAttributesFailedException Failed to get the attributes of * the item - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme */ -- (OFFileAttributes)attributesOfItemAtURI: (OFURI *)URI; +- (OFFileAttributes)attributesOfItemAtIRI: (OFIRI *)IRI; #ifdef OF_HAVE_FILES /** * @brief Sets the attributes for the item at the specified path. * @@ -320,25 +335,25 @@ - (void)setAttributes: (OFFileAttributes)attributes ofItemAtPath: (OFString *)path; #endif /** - * @brief Sets the attributes for the item at the specified URI. + * @brief Sets the attributes for the item at the specified IRI. * * All attributes not part of the dictionary are left unchanged. * - * @param attributes The attributes to set for the specified URI - * @param URI The URI of the item to set the attributes for + * @param attributes The attributes to set for the specified IRI + * @param IRI The IRI of the item to set the attributes for * @throw OFSetItemAttributesFailedException Failed to set the attributes of * the item - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme * @throw OFNotImplementedException Setting one or more of the specified * attributes is not implemented for the * specified item */ -- (void)setAttributes: (OFFileAttributes)attributes ofItemAtURI: (OFURI *)URI; +- (void)setAttributes: (OFFileAttributes)attributes ofItemAtIRI: (OFIRI *)IRI; #ifdef OF_HAVE_FILES /** * @brief Checks whether a file exists at the specified path. * @@ -347,18 +362,18 @@ */ - (bool)fileExistsAtPath: (OFString *)path; #endif /** - * @brief Checks whether a file exists at the specified URI. + * @brief Checks whether a file exists at the specified IRI. * - * @param URI The URI to check - * @return A boolean whether there is a file at the specified URI - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @param IRI The IRI to check + * @return A boolean whether there is a file at the specified IRI + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme */ -- (bool)fileExistsAtURI: (OFURI *)URI; +- (bool)fileExistsAtIRI: (OFIRI *)IRI; #ifdef OF_HAVE_FILES /** * @brief Checks whether a directory exists at the specified path. * @@ -367,18 +382,18 @@ */ - (bool)directoryExistsAtPath: (OFString *)path; #endif /** - * @brief Checks whether a directory exists at the specified URI. + * @brief Checks whether a directory exists at the specified IRI. * - * @param URI The URI to check - * @return A boolean whether there is a directory at the specified URI - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @param IRI The IRI to check + * @return A boolean whether there is a directory at the specified IRI + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme */ -- (bool)directoryExistsAtURI: (OFURI *)URI; +- (bool)directoryExistsAtIRI: (OFIRI *)IRI; #ifdef OF_HAVE_FILES /** * @brief Creates a directory at the specified path. * @@ -398,30 +413,30 @@ - (void)createDirectoryAtPath: (OFString *)path createParents: (bool)createParents; #endif /** - * @brief Creates a directory at the specified URI. + * @brief Creates a directory at the specified IRI. * - * @param URI The URI of the directory to create + * @param IRI The IRI of the directory to create * @throw OFCreateDirectoryFailedException Creating the directory failed - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme */ -- (void)createDirectoryAtURI: (OFURI *)URI; +- (void)createDirectoryAtIRI: (OFIRI *)IRI; /** - * @brief Creates a directory at the specified URI. + * @brief Creates a directory at the specified IRI. * - * @param URI The URI of the directory to create + * @param IRI The IRI of the directory to create * @param createParents Whether to create the parents of the directory * @throw OFCreateDirectoryFailedException Creating the directory or one of its * parents failed - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme */ -- (void)createDirectoryAtURI: (OFURI *)URI createParents: (bool)createParents; +- (void)createDirectoryAtIRI: (OFIRI *)IRI createParents: (bool)createParents; #ifdef OF_HAVE_FILES /** * @brief Returns an array with the items in the specified directory. * @@ -434,23 +449,23 @@ */ - (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path; #endif /** - * @brief Returns an array with the URIs of the items in the specified + * @brief Returns an array with the IRIs of the items in the specified * directory. * * @note `.` and `..` are not part of the returned array. * - * @param URI The URI to the directory whose items should be returned - * @return An array with the URIs of the items in the specified directory + * @param IRI The IRI to the directory whose items should be returned + * @return An array with the IRIs of the items in the specified directory * @throw OFOpenItemFailedException Opening the directory failed * @throw OFReadFailedException Reading from the directory failed - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme */ -- (OFArray OF_GENERIC(OFURI *) *)contentsOfDirectoryAtURI: (OFURI *)URI; +- (OFArray OF_GENERIC(OFIRI *) *)contentsOfDirectoryAtIRI: (OFIRI *)IRI; #ifdef OF_HAVE_FILES /** * @brief Returns an array with all subpaths of the specified directory. * @@ -472,15 +487,15 @@ - (void)changeCurrentDirectoryPath: (OFString *)path; /** * @brief Changes the current working directory. * - * @param URI The new directory to change to + * @param IRI The new directory to change to * @throw OFChangeCurrentDirectoryFailedException Changing the current working * directory failed */ -- (void)changeCurrentDirectoryURI: (OFURI *)URI; +- (void)changeCurrentDirectoryIRI: (OFIRI *)IRI; /** * @brief Copies a file, directory or symbolic link (if supported by the OS). * * The destination path must be a full path, which means it must include the @@ -500,26 +515,26 @@ #endif /** * @brief Copies a file, directory or symbolic link (if supported by the OS). * - * The destination URI must have a full path, which means it must include the + * The destination IRI must have a full path, which means it must include the * name of the item. * * If an item already exists, the copy operation fails. This is also the case * if a directory is copied and an item already exists in the destination * directory. * * @param source The file, directory or symbolic link to copy - * @param destination The destination URI + * @param destination The destination IRI * @throw OFCopyItemFailedException Copying failed * @throw OFCreateDirectoryFailedException Creating a destination directory * failed * @throw OFUnsupportedProtocolException No handler is registered for either of - * the URI's scheme + * the IRI's scheme */ -- (void)copyItemAtURI: (OFURI *)source toURI: (OFURI *)destination; +- (void)copyItemAtIRI: (OFIRI *)source toIRI: (OFIRI *)destination; #ifdef OF_HAVE_FILES /** * @brief Moves an item. * @@ -545,16 +560,16 @@ #endif /** * @brief Moves an item. * - * The destination URI must have a full path, which means it must include the + * The destination IRI must have a full path, which means it must include the * name of the item. * * If the destination is on a different logical device or uses a different * scheme, the source will be copied to the destination using - * @ref copyItemAtURI:toURI: and the source removed using @ref removeItemAtURI:. + * @ref copyItemAtIRI:toIRI: and the source removed using @ref removeItemAtIRI:. * * @param source The item to rename * @param destination The new name for the item * @throw OFMoveItemFailedException Moving failed * @throw OFCopyItemFailedException Copying (to move between different devices) @@ -563,13 +578,13 @@ * destination (to move between different * devices) failed * @throw OFCreateDirectoryFailedException Creating a destination directory * failed * @throw OFUnsupportedProtocolException No handler is registered for either of - * the URI's scheme + * the IRI's scheme */ -- (void)moveItemAtURI: (OFURI *)source toURI: (OFURI *)destination; +- (void)moveItemAtIRI: (OFIRI *)source toIRI: (OFIRI *)destination; #ifdef OF_HAVE_FILES /** * @brief Removes the item at the specified path. * @@ -580,20 +595,20 @@ */ - (void)removeItemAtPath: (OFString *)path; #endif /** - * @brief Removes the item at the specified URI. + * @brief Removes the item at the specified IRI. * - * If the item at the specified URI is a directory, it is removed recursively. + * If the item at the specified IRI is a directory, it is removed recursively. * - * @param URI The URI to the item which should be removed + * @param IRI The IRI to the item which should be removed * @throw OFRemoveItemFailedException Removing the item failed - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme */ -- (void)removeItemAtURI: (OFURI *)URI; +- (void)removeItemAtIRI: (OFIRI *)IRI; #ifdef OF_FILE_MANAGER_SUPPORTS_LINKS /** * @brief Creates a hard link for the specified item. * @@ -604,32 +619,32 @@ * * @param source The path to the item for which a link should be created * @param destination The path to the item which should link to the source * @throw OFLinkItemFailedException Linking the item failed * @throw OFNotImplementedException Hardlinks are not implemented for the - * specified URI + * specified IRI */ - (void)linkItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif /** * @brief Creates a hard link for the specified item. * - * The destination URI must have a full path, which means it must include the + * The destination IRI must have a full path, which means it must include the * name of the item. * - * This method is not available for all URIs. + * This method is not available for all IRIs. * - * @param source The URI to the item for which a link should be created - * @param destination The URI to the item which should link to the source + * @param source The IRI to the item for which a link should be created + * @param destination The IRI to the item which should link to the source * @throw OFLinkItemFailedException Linking the item failed - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme * @throw OFNotImplementedException Hardlinks are not implemented for the - * specified URI + * specified IRI */ -- (void)linkItemAtURI: (OFURI *)source toURI: (OFURI *)destination; +- (void)linkItemAtIRI: (OFIRI *)source toIRI: (OFIRI *)destination; #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS /** * @brief Creates a symbolic link for an item. * @@ -643,34 +658,147 @@ * * @param path The path to the item which should symbolically link to the target * @param target The target of the symbolic link * @throw OFCreateSymbolicLinkFailedException Creating the symbolic link failed * @throw OFNotImplementedException Symbolic links are not implemented for the - * specified URI + * specified IRI */ - (void)createSymbolicLinkAtPath: (OFString *)path withDestinationPath: (OFString *)target; #endif /** * @brief Creates a symbolic link for an item. * - * The destination URI must have a full path, which means it must include the + * The destination IRI must have a full path, which means it must include the * name of the item. * - * This method is not available for all URIs. + * This method is not available for all IRIs. * - * @note On Windows, this requires at least Windows Vista and administrator - * privileges! + * @note For file IRIs on Windows, this requires at least Windows Vista and + * administrator privileges! * - * @param URI The URI to the item which should symbolically link to the target + * @param IRI The IRI to the item which should symbolically link to the target * @param target The target of the symbolic link - * @throw OFUnsupportedProtocolException No handler is registered for the URI's + * @throw OFOFCreateSymbolicLinkFailedException Creating a symbolic link failed + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's * scheme */ -- (void)createSymbolicLinkAtURI: (OFURI *)URI +- (void)createSymbolicLinkAtIRI: (OFIRI *)IRI withDestinationPath: (OFString *)target; + +#ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES +/** + * @brief Returns the extended attribute data for the specified name of the + * item at the specified path. + * + * This method is not available on some systems. + * + * @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 *)extendedAttributeDataForName: (OFString *)name + ofItemAtPath: (OFString *)path; +#endif + +/** + * @brief Returns the extended attribute data for the specified name of the + * item at the specified IRI. + * + * This method is not available for all IRIs. + * + * @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 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 of the item + * at the specified path. + * + * This method is not available on some systems. + * + * @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 of the item + * at 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 + */ +- (void)setExtendedAttributeData: (OFData *)data + forName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI; + +#ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES +/** + * @brief Removes the extended attribute for the specified name wof the item at + * the specified path. + * + * This method is not available on some systems. + * + * @param name The name of the extended attribute to remove + * @param path The path of the item to remove the extended attribute from + * @throw OFSetItemAttributesFailedException Removing the extended attribute + * failed + * @throw OFNotImplementedException Removing extended attributes is not + * implemented for the specified item + */ +- (void)removeExtendedAttributeForName: (OFString *)name + ofItemAtPath: (OFString *)path; +#endif + +/** + * @brief Removes the extended attribute for the specified name wof the item at + * the specified IRI. + * + * This method is not available for all IRIs. + * + * @param name The name of the extended attribute to remove + * @param IRI The IRI of the item to remove the extended attribute from + * @throw OFSetItemAttributesFailedException Removing the extended attribute + * failed + * @throw OFUnsupportedProtocolException No handler is registered for the IRI's + * scheme + * @throw OFNotImplementedException Removing extended attributes is not + * implemented for the specified item + */ +- (void)removeExtendedAttributeForName: (OFString *)name + ofItemAtIRI: (OFIRI *)IRI; @end @interface OFDictionary (FileAttributes) /** * @brief The @ref OFFileSize key from the dictionary. @@ -753,8 +881,16 @@ * @brief The @ref OFFileSymbolicLinkDestination key from the dictionary. * * @throw OFUndefinedKeyException The key is missing */ @property (readonly, nonatomic) OFString *fileSymbolicLinkDestination; + +/** + * @brief The @ref OFFileExtendedAttributesNames key from the dictionary. + * + * @throw OFUndefinedKeyException The key is missing + */ +@property (readonly, nonatomic) + OFArray OF_GENERIC(OFString *) *fileExtendedAttributesNames; @end OF_ASSUME_NONNULL_END