Add the feature to allows advanced user to provided extended data associarted with image data, used for scale factor saving, rich link metadata saving, etc
This commit is contained in:
parent
74526bdde4
commit
892a7ad892
|
@ -89,6 +89,12 @@
|
|||
325C46272233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C46242233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
325C46282233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C46252233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m */; };
|
||||
325C46292233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C46252233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m */; };
|
||||
325F7CC623893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 325F7CC423893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
325F7CC723893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 325F7CC523893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.m */; };
|
||||
325F7CCA238942AB00AEDFCC /* NSData+ExtendedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 325F7CC8238942AB00AEDFCC /* NSData+ExtendedData.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
325F7CCB238942AB00AEDFCC /* NSData+ExtendedData.m in Sources */ = {isa = PBXBuildFile; fileRef = 325F7CC9238942AB00AEDFCC /* NSData+ExtendedData.m */; };
|
||||
325F7CCC2389463D00AEDFCC /* NSData+ExtendedData.m in Sources */ = {isa = PBXBuildFile; fileRef = 325F7CC9238942AB00AEDFCC /* NSData+ExtendedData.m */; };
|
||||
325F7CCD2389467800AEDFCC /* NSData+ExtendedData.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 325F7CC8238942AB00AEDFCC /* NSData+ExtendedData.h */; };
|
||||
326E2F2E236F0B23006F847F /* SDAnimatedImagePlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 326E2F2C236F0B23006F847F /* SDAnimatedImagePlayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
326E2F2F236F0B23006F847F /* SDAnimatedImagePlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 326E2F2D236F0B23006F847F /* SDAnimatedImagePlayer.m */; };
|
||||
326E2F30236F0B23006F847F /* SDAnimatedImagePlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 326E2F2D236F0B23006F847F /* SDAnimatedImagePlayer.m */; };
|
||||
|
@ -298,6 +304,7 @@
|
|||
dstPath = include/SDWebImage;
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
325F7CCD2389467800AEDFCC /* NSData+ExtendedData.h in Copy Headers */,
|
||||
326E2F36236F1E30006F847F /* SDAnimatedImagePlayer.h in Copy Headers */,
|
||||
3250C9F12355E3DF0093A896 /* SDWebImageDownloaderDecryptor.h in Copy Headers */,
|
||||
325427662355783C0042BAA4 /* SDWebImageDownloaderResponseModifier.h in Copy Headers */,
|
||||
|
@ -407,6 +414,10 @@
|
|||
325C461F2233A02E004CAE11 /* UIColor+HexString.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIColor+HexString.m"; sourceTree = "<group>"; };
|
||||
325C46242233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+RoundedCorners.h"; sourceTree = "<group>"; };
|
||||
325C46252233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+RoundedCorners.m"; sourceTree = "<group>"; };
|
||||
325F7CC423893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSFileManager+ExtendedAttributes.h"; sourceTree = "<group>"; };
|
||||
325F7CC523893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSFileManager+ExtendedAttributes.m"; sourceTree = "<group>"; };
|
||||
325F7CC8238942AB00AEDFCC /* NSData+ExtendedData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSData+ExtendedData.h"; path = "Core/NSData+ExtendedData.h"; sourceTree = "<group>"; };
|
||||
325F7CC9238942AB00AEDFCC /* NSData+ExtendedData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "NSData+ExtendedData.m"; path = "Core/NSData+ExtendedData.m"; sourceTree = "<group>"; };
|
||||
326E2F2C236F0B23006F847F /* SDAnimatedImagePlayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImagePlayer.h; path = Core/SDAnimatedImagePlayer.h; sourceTree = "<group>"; };
|
||||
326E2F2D236F0B23006F847F /* SDAnimatedImagePlayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImagePlayer.m; path = Core/SDAnimatedImagePlayer.m; sourceTree = "<group>"; };
|
||||
326E2F31236F1D58006F847F /* SDDeviceHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDDeviceHelper.h; sourceTree = "<group>"; };
|
||||
|
@ -635,6 +646,8 @@
|
|||
325C461F2233A02E004CAE11 /* UIColor+HexString.m */,
|
||||
325C46242233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h */,
|
||||
325C46252233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m */,
|
||||
325F7CC423893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.h */,
|
||||
325F7CC523893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.m */,
|
||||
329F123F223FAD3400B309FD /* SDInternalMacros.h */,
|
||||
329F123E223FAD3400B309FD /* SDInternalMacros.m */,
|
||||
329F1235223FAA3B00B309FD /* SDmetamacros.h */,
|
||||
|
@ -744,6 +757,8 @@
|
|||
children = (
|
||||
5D5B9140188EE8DD006D06BD /* NSData+ImageContentType.h */,
|
||||
5D5B9141188EE8DD006D06BD /* NSData+ImageContentType.m */,
|
||||
325F7CC8238942AB00AEDFCC /* NSData+ExtendedData.h */,
|
||||
325F7CC9238942AB00AEDFCC /* NSData+ExtendedData.m */,
|
||||
A18A6CC5172DC28500419892 /* UIImage+GIF.h */,
|
||||
A18A6CC6172DC28500419892 /* UIImage+GIF.m */,
|
||||
329A18571FFF5DFD008C9A2F /* UIImage+Metadata.h */,
|
||||
|
@ -849,6 +864,7 @@
|
|||
3257EAFA21898AED0097B271 /* SDImageGraphics.h in Headers */,
|
||||
32D3CDD121DDE87300C4DB49 /* UIImage+MemoryCacheCost.h in Headers */,
|
||||
328BB6AC2081FEE500760D6C /* SDWebImageCacheSerializer.h in Headers */,
|
||||
325F7CCA238942AB00AEDFCC /* NSData+ExtendedData.h in Headers */,
|
||||
325C46272233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h in Headers */,
|
||||
321B378F2083290E00C0EA77 /* SDImageLoadersManager.h in Headers */,
|
||||
329A185B1FFF5DFD008C9A2F /* UIImage+Metadata.h in Headers */,
|
||||
|
@ -906,6 +922,7 @@
|
|||
32C0FDE32013426C001B8F2D /* SDWebImageIndicator.h in Headers */,
|
||||
32F7C0712030114C00873181 /* SDImageTransformer.h in Headers */,
|
||||
32E67311235765B500DB4987 /* SDDisplayLink.h in Headers */,
|
||||
325F7CC623893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.h in Headers */,
|
||||
4A2CAE2D1AB4BB7500B6BC39 /* UIImage+GIF.h in Headers */,
|
||||
4A2CAE291AB4BB7500B6BC39 /* NSData+ImageContentType.h in Headers */,
|
||||
328BB69E2081FED200760D6C /* SDWebImageCacheKeyFilter.h in Headers */,
|
||||
|
@ -1098,6 +1115,7 @@
|
|||
3257EAFD21898AED0097B271 /* SDImageGraphics.m in Sources */,
|
||||
3290FA0C1FA478AF0047D20C /* SDImageFrame.m in Sources */,
|
||||
325C46232233A02E004CAE11 /* UIColor+HexString.m in Sources */,
|
||||
325F7CCB238942AB00AEDFCC /* NSData+ExtendedData.m in Sources */,
|
||||
321E60C61F38E91700405457 /* UIImage+ForceDecode.m in Sources */,
|
||||
3244062E2296C5F400A36084 /* SDWebImageOptionsProcessor.m in Sources */,
|
||||
3250C9F02355D9DA0093A896 /* SDWebImageDownloaderDecryptor.m in Sources */,
|
||||
|
@ -1127,6 +1145,7 @@
|
|||
321E609C1F38E8ED00405457 /* SDImageIOCoder.m in Sources */,
|
||||
4A2CAE261AB4BB7000B6BC39 /* SDWebImagePrefetcher.m in Sources */,
|
||||
328BB6C92082581100760D6C /* SDDiskCache.m in Sources */,
|
||||
325F7CC723893B2E00AEDFCC /* NSFileManager+ExtendedAttributes.m in Sources */,
|
||||
3248475F201775F600AF9E5A /* SDAnimatedImageView.m in Sources */,
|
||||
32D1222C2080B2EB003685A3 /* SDImageCachesManager.m in Sources */,
|
||||
32B9B53F206ED4230026769D /* SDWebImageDownloaderConfig.m in Sources */,
|
||||
|
@ -1198,6 +1217,7 @@
|
|||
5376130D155AD0D5005750A4 /* SDWebImagePrefetcher.m in Sources */,
|
||||
328BB6C72082581100760D6C /* SDDiskCache.m in Sources */,
|
||||
3248475D201775F600AF9E5A /* SDAnimatedImageView.m in Sources */,
|
||||
325F7CCC2389463D00AEDFCC /* NSData+ExtendedData.m in Sources */,
|
||||
32D1222A2080B2EB003685A3 /* SDImageCachesManager.m in Sources */,
|
||||
32B9B53D206ED4230026769D /* SDWebImageDownloaderConfig.m in Sources */,
|
||||
43A9186B1D8308FE00B3925F /* SDImageCacheConfig.m in Sources */,
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
* (c) Fabrice Aneche
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "SDWebImageCompat.h"
|
||||
|
||||
@interface NSData (ExtendedData)
|
||||
|
||||
/**
|
||||
Read and Write the extended data to the image data. Which can hold some extra metadata like Image's scale factor, URL rich link, date, etc.
|
||||
The extended data will be write to disk cache as well as the image data. The disk cache preserve both of the data and extended data with the same cache key.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) NSData *sd_extendedData;
|
||||
|
||||
@end
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
* (c) Fabrice Aneche
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "NSData+ExtendedData.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation NSData (ExtendedData)
|
||||
|
||||
- (NSData *)sd_extendedData {
|
||||
return objc_getAssociatedObject(self, @selector(sd_extendedData));
|
||||
}
|
||||
|
||||
- (void)setSd_extendedData:(NSData *)sd_extendedData {
|
||||
objc_setAssociatedObject(self, @selector(sd_extendedData), sd_extendedData, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
@end
|
|
@ -54,6 +54,26 @@
|
|||
*/
|
||||
- (void)setData:(nullable NSData *)data forKey:(nonnull NSString *)key;
|
||||
|
||||
/**
|
||||
Returns the extended data associated with a given key.
|
||||
This method may blocks the calling thread until file read finished.
|
||||
|
||||
@param key A string identifying the data. If nil, just return nil.
|
||||
@return The value associated with key, or nil if no value is associated with key.
|
||||
*/
|
||||
- (nullable NSData *)extendedDataForKey:(nonnull NSString *)key;
|
||||
|
||||
/**
|
||||
Set extended data with a given key.
|
||||
|
||||
@discussion You can set any extended data to exist cache key. Without override the exist disk file data.
|
||||
on UNIX, the common way for this is to use the Extended file attributes (xattr)
|
||||
|
||||
@param extendedData The extended data (pass nil to remove).
|
||||
@param key The key with which to associate the value. If nil, this method has no effect.
|
||||
*/
|
||||
- (void)setExtendedData:(nullable NSData *)extendedData forKey:(nonnull NSString *)key;
|
||||
|
||||
/**
|
||||
Removes the value of the specified key in the cache.
|
||||
This method may blocks the calling thread until file delete finished.
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
|
||||
#import "SDDiskCache.h"
|
||||
#import "SDImageCacheConfig.h"
|
||||
#import "NSFileManager+ExtendedAttributes.h"
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
|
||||
static NSString * const SDDiskCacheExtendedAttributeName = @"com.hackemist.SDDiskCache";
|
||||
|
||||
@interface SDDiskCache ()
|
||||
|
||||
@property (nonatomic, copy) NSString *diskCachePath;
|
||||
|
@ -95,6 +98,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (NSData *)extendedDataForKey:(NSString *)key {
|
||||
NSParameterAssert(key);
|
||||
|
||||
// get cache Path for image key
|
||||
NSString *cachePathForKey = [self cachePathForKey:key];
|
||||
|
||||
NSData *extendedData = [self.fileManager extendedAttribute:SDDiskCacheExtendedAttributeName atPath:cachePathForKey traverseLink:NO error:nil];
|
||||
|
||||
return extendedData;
|
||||
}
|
||||
|
||||
- (void)setExtendedData:(NSData *)extendedData forKey:(NSString *)key {
|
||||
NSParameterAssert(key);
|
||||
// get cache Path for image key
|
||||
NSString *cachePathForKey = [self cachePathForKey:key];
|
||||
|
||||
if (!extendedData) {
|
||||
// Remove
|
||||
[self.fileManager removeExtendedAttribute:SDDiskCacheExtendedAttributeName atPath:cachePathForKey traverseLink:NO error:nil];
|
||||
} else {
|
||||
// Override
|
||||
[self.fileManager setExtendedAttribute:SDDiskCacheExtendedAttributeName value:extendedData atPath:cachePathForKey traverseLink:NO overwrite:YES error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeDataForKey:(NSString *)key {
|
||||
NSParameterAssert(key);
|
||||
NSString *filePath = [self cachePathForKey:key];
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#import "SDAnimatedImage.h"
|
||||
#import "UIImage+MemoryCacheCost.h"
|
||||
#import "UIImage+Metadata.h"
|
||||
#import "NSData+ExtendedData.h"
|
||||
|
||||
@interface SDImageCache ()
|
||||
|
||||
|
@ -238,6 +239,10 @@
|
|||
}
|
||||
|
||||
[self.diskCache setData:imageData forKey:key];
|
||||
NSData *extendedData = imageData.sd_extendedData;
|
||||
if (extendedData) {
|
||||
[self.diskCache setExtendedData:extendedData forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Query and Retrieve Ops
|
||||
|
@ -320,6 +325,11 @@
|
|||
|
||||
NSData *data = [self.diskCache dataForKey:key];
|
||||
if (data) {
|
||||
// Check extended data
|
||||
NSData *extendedData = [self.diskCache extendedDataForKey:key];
|
||||
if (extendedData) {
|
||||
data.sd_extendedData = extendedData;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@ typedef NSData * _Nullable(^SDWebImageCacheSerializerBlock)(UIImage * _Nonnull i
|
|||
*/
|
||||
@protocol SDWebImageCacheSerializer <NSObject>
|
||||
|
||||
/// Provide the image data associated to the image and store to disk cache
|
||||
/// @param image The loaded image
|
||||
/// @param data The original loaded image data
|
||||
/// @param imageURL The image URL
|
||||
- (nullable NSData *)cacheDataWithImage:(nonnull UIImage *)image originalData:(nullable NSData *)data imageURL:(nullable NSURL *)imageURL;
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// NSFileManager+ExtendedAttributes.h
|
||||
// NSFileManager+ExtendedAttributes
|
||||
//
|
||||
// Created by Jesús A. Álvarez on 2008-12-17.
|
||||
// Copyright 2008-2009 namedfork.net. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSFileManager (ExtendedAttributes)
|
||||
|
||||
- (NSArray*)extendedAttributeNamesAtPath:(NSString*)path traverseLink:(BOOL)follow error:(NSError**)err;
|
||||
- (BOOL)hasExtendedAttribute:(NSString*)name atPath:(NSString*)path traverseLink:(BOOL)follow error:(NSError**)err;
|
||||
- (NSData*)extendedAttribute:(NSString*)name atPath:(NSString*)path traverseLink:(BOOL)follow error:(NSError**)err;
|
||||
- (BOOL)setExtendedAttribute:(NSString*)name value:(NSData*)value atPath:(NSString*)path traverseLink:(BOOL)follow overwrite:(BOOL)overwrite error:(NSError**)err;
|
||||
- (BOOL)removeExtendedAttribute:(NSString*)name atPath:(NSString*)path traverseLink:(BOOL)follow error:(NSError**)err;
|
||||
|
||||
@end
|
|
@ -0,0 +1,128 @@
|
|||
//
|
||||
// NSFileManager+ExtendedAttributes.m
|
||||
// NSFileManager+ExtendedAttributes
|
||||
//
|
||||
// Created by Jesús A. Álvarez on 2008-12-17.
|
||||
// Copyright 2008-2009 namedfork.net. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSFileManager+ExtendedAttributes.h"
|
||||
#import <sys/xattr.h>
|
||||
|
||||
@implementation NSFileManager (ExtendedAttributes)
|
||||
|
||||
- (NSArray*)extendedAttributeNamesAtPath:(NSString*)path traverseLink:(BOOL)follow error:(NSError**)err {
|
||||
int flags = follow? 0 : XATTR_NOFOLLOW;
|
||||
|
||||
// get size of name list
|
||||
ssize_t nameBuffLen = listxattr([path fileSystemRepresentation], NULL, 0, flags);
|
||||
if (nameBuffLen == -1) {
|
||||
if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSString stringWithUTF8String:strerror(errno)], @"error",
|
||||
@"listxattr", @"function",
|
||||
path, @":path",
|
||||
[NSNumber numberWithBool:follow], @":traverseLink",
|
||||
nil]
|
||||
];
|
||||
return nil;
|
||||
} else if (nameBuffLen == 0) return [NSArray array];
|
||||
|
||||
// get name list
|
||||
NSMutableData *nameBuff = [NSMutableData dataWithLength:nameBuffLen];
|
||||
listxattr([path fileSystemRepresentation], [nameBuff mutableBytes], nameBuffLen, flags);
|
||||
|
||||
// convert to array
|
||||
NSMutableArray * names = [NSMutableArray arrayWithCapacity:5];
|
||||
char *nextName, *endOfNames = [nameBuff mutableBytes] + nameBuffLen;
|
||||
for(nextName = [nameBuff mutableBytes]; nextName < endOfNames; nextName += 1+strlen(nextName))
|
||||
[names addObject:[NSString stringWithUTF8String:nextName]];
|
||||
return [NSArray arrayWithArray:names];
|
||||
}
|
||||
|
||||
- (BOOL)hasExtendedAttribute:(NSString*)name atPath:(NSString*)path traverseLink:(BOOL)follow error:(NSError**)err {
|
||||
int flags = follow? 0 : XATTR_NOFOLLOW;
|
||||
|
||||
// get size of name list
|
||||
ssize_t nameBuffLen = listxattr([path fileSystemRepresentation], NULL, 0, flags);
|
||||
if (nameBuffLen == -1) {
|
||||
if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSString stringWithUTF8String:strerror(errno)], @"error",
|
||||
@"listxattr", @"function",
|
||||
path, @":path",
|
||||
[NSNumber numberWithBool:follow], @":traverseLink",
|
||||
nil]
|
||||
];
|
||||
return NO;
|
||||
} else if (nameBuffLen == 0) return NO;
|
||||
|
||||
// get name list
|
||||
NSMutableData *nameBuff = [NSMutableData dataWithLength:nameBuffLen];
|
||||
listxattr([path fileSystemRepresentation], [nameBuff mutableBytes], nameBuffLen, flags);
|
||||
|
||||
// find our name
|
||||
char *nextName, *endOfNames = [nameBuff mutableBytes] + nameBuffLen;
|
||||
for(nextName = [nameBuff mutableBytes]; nextName < endOfNames; nextName += 1+strlen(nextName))
|
||||
if (strcmp(nextName, [name UTF8String]) == 0) return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSData*)extendedAttribute:(NSString*)name atPath:(NSString*)path traverseLink:(BOOL)follow error:(NSError**)err {
|
||||
int flags = follow? 0 : XATTR_NOFOLLOW;
|
||||
// get length
|
||||
ssize_t attrLen = getxattr([path fileSystemRepresentation], [name UTF8String], NULL, 0, 0, flags);
|
||||
if (attrLen == -1) {
|
||||
if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSString stringWithUTF8String:strerror(errno)], @"error",
|
||||
@"getxattr", @"function",
|
||||
name, @":name",
|
||||
path, @":path",
|
||||
[NSNumber numberWithBool:follow], @":traverseLink",
|
||||
nil]
|
||||
];
|
||||
return nil;
|
||||
}
|
||||
|
||||
// get attribute data
|
||||
NSMutableData * attrData = [NSMutableData dataWithLength:attrLen];
|
||||
getxattr([path fileSystemRepresentation], [name UTF8String], [attrData mutableBytes], attrLen, 0, flags);
|
||||
return attrData;
|
||||
}
|
||||
|
||||
- (BOOL)setExtendedAttribute:(NSString*)name value:(NSData*)value atPath:(NSString*)path traverseLink:(BOOL)follow overwrite:(BOOL)overwrite error:(NSError**)err {
|
||||
int flags = (follow? 0 : XATTR_NOFOLLOW) | (overwrite? 0 : XATTR_CREATE);
|
||||
if (0 == setxattr([path fileSystemRepresentation], [name UTF8String], [value bytes], [value length], 0, flags)) return YES;
|
||||
// error
|
||||
if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSString stringWithUTF8String:strerror(errno)], @"error",
|
||||
@"setxattr", @"function",
|
||||
name, @":name",
|
||||
[NSNumber numberWithUnsignedInteger:[value length]], @":value.length",
|
||||
path, @":path",
|
||||
[NSNumber numberWithBool:follow], @":traverseLink",
|
||||
[NSNumber numberWithBool:overwrite], @":overwrite",
|
||||
nil]
|
||||
];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)removeExtendedAttribute:(NSString*)name atPath:(NSString*)path traverseLink:(BOOL)follow error:(NSError**)err {
|
||||
int flags = (follow? 0 : XATTR_NOFOLLOW);
|
||||
if (0 == removexattr([path fileSystemRepresentation], [name UTF8String], flags)) return YES;
|
||||
// error
|
||||
if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSString stringWithUTF8String:strerror(errno)], @"error",
|
||||
@"removexattr", @"function",
|
||||
name, @":name",
|
||||
path, @":path",
|
||||
[NSNumber numberWithBool:follow], @":traverseLink",
|
||||
nil]
|
||||
];
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -67,6 +67,7 @@ FOUNDATION_EXPORT const unsigned char WebImageVersionString[];
|
|||
#import <SDWebImage/UIImage+GIF.h>
|
||||
#import <SDWebImage/UIImage+ForceDecode.h>
|
||||
#import <SDWebImage/NSData+ImageContentType.h>
|
||||
#import <SDWebImage/NSData+ExtendedData.h>
|
||||
#import <SDWebImage/SDWebImageDefine.h>
|
||||
#import <SDWebImage/SDWebImageError.h>
|
||||
#import <SDWebImage/SDWebImageOptionsProcessor.h>
|
||||
|
|
Loading…
Reference in New Issue