From 83b9d5c682b21d88133f24da0f94dd56bd79e687 Mon Sep 17 00:00:00 2001
From: 单军华
Date: Thu, 19 Jul 2018 13:38:55 +0800
Subject: [PATCH] change

---
 screendisplay/Pods/YYCache/YYCache/YYDiskCache.m |  458 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 458 insertions(+), 0 deletions(-)

diff --git a/screendisplay/Pods/YYCache/YYCache/YYDiskCache.m b/screendisplay/Pods/YYCache/YYCache/YYDiskCache.m
new file mode 100644
index 0000000..735cc5d
--- /dev/null
+++ b/screendisplay/Pods/YYCache/YYCache/YYDiskCache.m
@@ -0,0 +1,458 @@
+//
+//  YYDiskCache.m
+//  YYCache <https://github.com/ibireme/YYCache>
+//
+//  Created by ibireme on 15/2/11.
+//  Copyright (c) 2015 ibireme.
+//
+//  This source code is licensed under the MIT-style license found in the
+//  LICENSE file in the root directory of this source tree.
+//
+
+#import "YYDiskCache.h"
+#import "YYKVStorage.h"
+#import <UIKit/UIKit.h>
+#import <CommonCrypto/CommonCrypto.h>
+#import <objc/runtime.h>
+#import <time.h>
+
+#define Lock() dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER)
+#define Unlock() dispatch_semaphore_signal(self->_lock)
+
+static const int extended_data_key;
+
+/// Free disk space in bytes.
+static int64_t _YYDiskSpaceFree() {
+    NSError *error = nil;
+    NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
+    if (error) return -1;
+    int64_t space =  [[attrs objectForKey:NSFileSystemFreeSize] longLongValue];
+    if (space < 0) space = -1;
+    return space;
+}
+
+/// String's md5 hash.
+static NSString *_YYNSStringMD5(NSString *string) {
+    if (!string) return nil;
+    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
+    unsigned char result[CC_MD5_DIGEST_LENGTH];
+    CC_MD5(data.bytes, (CC_LONG)data.length, result);
+    return [NSString stringWithFormat:
+                @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+                result[0],  result[1],  result[2],  result[3],
+                result[4],  result[5],  result[6],  result[7],
+                result[8],  result[9],  result[10], result[11],
+                result[12], result[13], result[14], result[15]
+            ];
+}
+
+/// weak reference for all instances
+static NSMapTable *_globalInstances;
+static dispatch_semaphore_t _globalInstancesLock;
+
+static void _YYDiskCacheInitGlobal() {
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        _globalInstancesLock = dispatch_semaphore_create(1);
+        _globalInstances = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0];
+    });
+}
+
+static YYDiskCache *_YYDiskCacheGetGlobal(NSString *path) {
+    if (path.length == 0) return nil;
+    _YYDiskCacheInitGlobal();
+    dispatch_semaphore_wait(_globalInstancesLock, DISPATCH_TIME_FOREVER);
+    id cache = [_globalInstances objectForKey:path];
+    dispatch_semaphore_signal(_globalInstancesLock);
+    return cache;
+}
+
+static void _YYDiskCacheSetGlobal(YYDiskCache *cache) {
+    if (cache.path.length == 0) return;
+    _YYDiskCacheInitGlobal();
+    dispatch_semaphore_wait(_globalInstancesLock, DISPATCH_TIME_FOREVER);
+    [_globalInstances setObject:cache forKey:cache.path];
+    dispatch_semaphore_signal(_globalInstancesLock);
+}
+
+
+
+@implementation YYDiskCache {
+    YYKVStorage *_kv;
+    dispatch_semaphore_t _lock;
+    dispatch_queue_t _queue;
+}
+
+- (void)_trimRecursively {
+    __weak typeof(self) _self = self;
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_autoTrimInterval * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
+        __strong typeof(_self) self = _self;
+        if (!self) return;
+        [self _trimInBackground];
+        [self _trimRecursively];
+    });
+}
+
+- (void)_trimInBackground {
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        if (!self) return;
+        Lock();
+        [self _trimToCost:self.costLimit];
+        [self _trimToCount:self.countLimit];
+        [self _trimToAge:self.ageLimit];
+        [self _trimToFreeDiskSpace:self.freeDiskSpaceLimit];
+        Unlock();
+    });
+}
+
+- (void)_trimToCost:(NSUInteger)costLimit {
+    if (costLimit >= INT_MAX) return;
+    [_kv removeItemsToFitSize:(int)costLimit];
+    
+}
+
+- (void)_trimToCount:(NSUInteger)countLimit {
+    if (countLimit >= INT_MAX) return;
+    [_kv removeItemsToFitCount:(int)countLimit];
+}
+
+- (void)_trimToAge:(NSTimeInterval)ageLimit {
+    if (ageLimit <= 0) {
+        [_kv removeAllItems];
+        return;
+    }
+    long timestamp = time(NULL);
+    if (timestamp <= ageLimit) return;
+    long age = timestamp - ageLimit;
+    if (age >= INT_MAX) return;
+    [_kv removeItemsEarlierThanTime:(int)age];
+}
+
+- (void)_trimToFreeDiskSpace:(NSUInteger)targetFreeDiskSpace {
+    if (targetFreeDiskSpace == 0) return;
+    int64_t totalBytes = [_kv getItemsSize];
+    if (totalBytes <= 0) return;
+    int64_t diskFreeBytes = _YYDiskSpaceFree();
+    if (diskFreeBytes < 0) return;
+    int64_t needTrimBytes = targetFreeDiskSpace - diskFreeBytes;
+    if (needTrimBytes <= 0) return;
+    int64_t costLimit = totalBytes - needTrimBytes;
+    if (costLimit < 0) costLimit = 0;
+    [self _trimToCost:(int)costLimit];
+}
+
+- (NSString *)_filenameForKey:(NSString *)key {
+    NSString *filename = nil;
+    if (_customFileNameBlock) filename = _customFileNameBlock(key);
+    if (!filename) filename = _YYNSStringMD5(key);
+    return filename;
+}
+
+- (void)_appWillBeTerminated {
+    Lock();
+    _kv = nil;
+    Unlock();
+}
+
+#pragma mark - public
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil];
+}
+
+- (instancetype)init {
+    @throw [NSException exceptionWithName:@"YYDiskCache init error" reason:@"YYDiskCache must be initialized with a path. Use 'initWithPath:' or 'initWithPath:inlineThreshold:' instead." userInfo:nil];
+    return [self initWithPath:@"" inlineThreshold:0];
+}
+
+- (instancetype)initWithPath:(NSString *)path {
+    return [self initWithPath:path inlineThreshold:1024 * 20]; // 20KB
+}
+
+- (instancetype)initWithPath:(NSString *)path
+             inlineThreshold:(NSUInteger)threshold {
+    self = [super init];
+    if (!self) return nil;
+    
+    YYDiskCache *globalCache = _YYDiskCacheGetGlobal(path);
+    if (globalCache) return globalCache;
+    
+    YYKVStorageType type;
+    if (threshold == 0) {
+        type = YYKVStorageTypeFile;
+    } else if (threshold == NSUIntegerMax) {
+        type = YYKVStorageTypeSQLite;
+    } else {
+        type = YYKVStorageTypeMixed;
+    }
+    
+    YYKVStorage *kv = [[YYKVStorage alloc] initWithPath:path type:type];
+    if (!kv) return nil;
+    
+    _kv = kv;
+    _path = path;
+    _lock = dispatch_semaphore_create(1);
+    _queue = dispatch_queue_create("com.ibireme.cache.disk", DISPATCH_QUEUE_CONCURRENT);
+    _inlineThreshold = threshold;
+    _countLimit = NSUIntegerMax;
+    _costLimit = NSUIntegerMax;
+    _ageLimit = DBL_MAX;
+    _freeDiskSpaceLimit = 0;
+    _autoTrimInterval = 60;
+    
+    [self _trimRecursively];
+    _YYDiskCacheSetGlobal(self);
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appWillBeTerminated) name:UIApplicationWillTerminateNotification object:nil];
+    return self;
+}
+
+- (BOOL)containsObjectForKey:(NSString *)key {
+    if (!key) return NO;
+    Lock();
+    BOOL contains = [_kv itemExistsForKey:key];
+    Unlock();
+    return contains;
+}
+
+- (void)containsObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key, BOOL contains))block {
+    if (!block) return;
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        BOOL contains = [self containsObjectForKey:key];
+        block(key, contains);
+    });
+}
+
+- (id<NSCoding>)objectForKey:(NSString *)key {
+    if (!key) return nil;
+    Lock();
+    YYKVStorageItem *item = [_kv getItemForKey:key];
+    Unlock();
+    if (!item.value) return nil;
+    
+    id object = nil;
+    if (_customUnarchiveBlock) {
+        object = _customUnarchiveBlock(item.value);
+    } else {
+        @try {
+            object = [NSKeyedUnarchiver unarchiveObjectWithData:item.value];
+        }
+        @catch (NSException *exception) {
+            // nothing to do...
+        }
+    }
+    if (object && item.extendedData) {
+        [YYDiskCache setExtendedData:item.extendedData toObject:object];
+    }
+    return object;
+}
+
+- (void)objectForKey:(NSString *)key withBlock:(void(^)(NSString *key, id<NSCoding> object))block {
+    if (!block) return;
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        id<NSCoding> object = [self objectForKey:key];
+        block(key, object);
+    });
+}
+
+- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key {
+    if (!key) return;
+    if (!object) {
+        [self removeObjectForKey:key];
+        return;
+    }
+    
+    NSData *extendedData = [YYDiskCache getExtendedDataFromObject:object];
+    NSData *value = nil;
+    if (_customArchiveBlock) {
+        value = _customArchiveBlock(object);
+    } else {
+        @try {
+            value = [NSKeyedArchiver archivedDataWithRootObject:object];
+        }
+        @catch (NSException *exception) {
+            // nothing to do...
+        }
+    }
+    if (!value) return;
+    NSString *filename = nil;
+    if (_kv.type != YYKVStorageTypeSQLite) {
+        if (value.length > _inlineThreshold) {
+            filename = [self _filenameForKey:key];
+        }
+    }
+    
+    Lock();
+    [_kv saveItemWithKey:key value:value filename:filename extendedData:extendedData];
+    Unlock();
+}
+
+- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key withBlock:(void(^)(void))block {
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        [self setObject:object forKey:key];
+        if (block) block();
+    });
+}
+
+- (void)removeObjectForKey:(NSString *)key {
+    if (!key) return;
+    Lock();
+    [_kv removeItemForKey:key];
+    Unlock();
+}
+
+- (void)removeObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key))block {
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        [self removeObjectForKey:key];
+        if (block) block(key);
+    });
+}
+
+- (void)removeAllObjects {
+    Lock();
+    [_kv removeAllItems];
+    Unlock();
+}
+
+- (void)removeAllObjectsWithBlock:(void(^)(void))block {
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        [self removeAllObjects];
+        if (block) block();
+    });
+}
+
+- (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress
+                                 endBlock:(void(^)(BOOL error))end {
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        if (!self) {
+            if (end) end(YES);
+            return;
+        }
+        Lock();
+        [_kv removeAllItemsWithProgressBlock:progress endBlock:end];
+        Unlock();
+    });
+}
+
+- (NSInteger)totalCount {
+    Lock();
+    int count = [_kv getItemsCount];
+    Unlock();
+    return count;
+}
+
+- (void)totalCountWithBlock:(void(^)(NSInteger totalCount))block {
+    if (!block) return;
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        NSInteger totalCount = [self totalCount];
+        block(totalCount);
+    });
+}
+
+- (NSInteger)totalCost {
+    Lock();
+    int count = [_kv getItemsSize];
+    Unlock();
+    return count;
+}
+
+- (void)totalCostWithBlock:(void(^)(NSInteger totalCost))block {
+    if (!block) return;
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        NSInteger totalCost = [self totalCost];
+        block(totalCost);
+    });
+}
+
+- (void)trimToCount:(NSUInteger)count {
+    Lock();
+    [self _trimToCount:count];
+    Unlock();
+}
+
+- (void)trimToCount:(NSUInteger)count withBlock:(void(^)(void))block {
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        [self trimToCount:count];
+        if (block) block();
+    });
+}
+
+- (void)trimToCost:(NSUInteger)cost {
+    Lock();
+    [self _trimToCost:cost];
+    Unlock();
+}
+
+- (void)trimToCost:(NSUInteger)cost withBlock:(void(^)(void))block {
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        [self trimToCost:cost];
+        if (block) block();
+    });
+}
+
+- (void)trimToAge:(NSTimeInterval)age {
+    Lock();
+    [self _trimToAge:age];
+    Unlock();
+}
+
+- (void)trimToAge:(NSTimeInterval)age withBlock:(void(^)(void))block {
+    __weak typeof(self) _self = self;
+    dispatch_async(_queue, ^{
+        __strong typeof(_self) self = _self;
+        [self trimToAge:age];
+        if (block) block();
+    });
+}
+
++ (NSData *)getExtendedDataFromObject:(id)object {
+    if (!object) return nil;
+    return (NSData *)objc_getAssociatedObject(object, &extended_data_key);
+}
+
++ (void)setExtendedData:(NSData *)extendedData toObject:(id)object {
+    if (!object) return;
+    objc_setAssociatedObject(object, &extended_data_key, extendedData, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (NSString *)description {
+    if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@:%@)", self.class, self, _name, _path];
+    else return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _path];
+}
+
+- (BOOL)errorLogsEnabled {
+    Lock();
+    BOOL enabled = _kv.errorLogsEnabled;
+    Unlock();
+    return enabled;
+}
+
+- (void)setErrorLogsEnabled:(BOOL)errorLogsEnabled {
+    Lock();
+    _kv.errorLogsEnabled = errorLogsEnabled;
+    Unlock();
+}
+
+@end

--
Gitblit v1.8.0