added files via upload

This commit is contained in:
Balackburn
2023-06-27 09:54:41 +02:00
commit 2ff6aac218
1420 changed files with 88898 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
OSCache
version 1.2.1, Decembet 18th, 2015
Copyright (C) 2014 Charcoal Design
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.

View File

@@ -0,0 +1,57 @@
//
// OSCache.h
//
// Version 1.2.1
//
// Created by Nick Lockwood on 01/01/2014.
// Copyright (C) 2014 Charcoal Design
//
// Distributed under the permissive zlib License
// Get the latest version from here:
//
// https://github.com/nicklockwood/OSCache
//
// 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.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface OSCache <KeyType, ObjectType> : NSCache <NSFastEnumeration>
@property (nonatomic, readonly) NSUInteger count;
@property (nonatomic, readonly) NSUInteger totalCost;
- (id)objectForKeyedSubscript:(KeyType <NSCopying>)key;
- (void)setObject:(ObjectType)obj forKeyedSubscript:(KeyType <NSCopying>)key;
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(KeyType key, ObjectType obj, BOOL *stop))block;
@end
@protocol OSCacheDelegate <NSCacheDelegate>
@optional
- (BOOL)cache:(OSCache *)cache shouldEvictObject:(id)entry;
- (void)cache:(OSCache *)cache willEvictObject:(id)entry;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,409 @@
//
// OSCache.m
//
// Version 1.2.1
//
// Created by Nick Lockwood on 01/01/2014.
// Copyright (C) 2014 Charcoal Design
//
// Distributed under the permissive zlib License
// Get the latest version from here:
//
// https://github.com/nicklockwood/OSCache
//
// 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.
//
#import "OSCache.h"
#import <TargetConditionals.h>
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#endif
#import <Availability.h>
#if !__has_feature(objc_arc)
#error This class requires automatic reference counting
#endif
#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis"
#pragma GCC diagnostic ignored "-Wdirect-ivar-access"
#pragma GCC diagnostic ignored "-Wgnu"
@interface OSCacheEntry : NSObject
@property (nonatomic, strong) NSObject *object;
@property (nonatomic, assign) NSUInteger cost;
@property (nonatomic, assign) NSInteger sequenceNumber;
@end
@implementation OSCacheEntry
@end
@interface OSCache_Private : NSObject
@property (nonatomic, unsafe_unretained) id<OSCacheDelegate> delegate;
@property (nonatomic, assign) NSUInteger countLimit;
@property (nonatomic, assign) NSUInteger totalCostLimit;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSMutableDictionary *cache;
@property (nonatomic, assign) NSUInteger totalCost;
@property (nonatomic, assign) NSInteger sequenceNumber;
@end
@implementation OSCache_Private
{
BOOL _delegateRespondsToWillEvictObject;
BOOL _delegateRespondsToShouldEvictObject;
BOOL _currentlyCleaning;
NSMutableArray *_entryPool;
NSLock *_lock;
}
- (instancetype)init
{
if ((self = [super init]))
{
//create storage
_cache = [[NSMutableDictionary alloc] init];
_entryPool = [[NSMutableArray alloc] init];
_lock = [[NSLock alloc] init];
_totalCost = 0;
#if TARGET_OS_IPHONE
//clean up in the event of a memory warning
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cleanUpAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
#endif
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)setDelegate:(id<OSCacheDelegate>)delegate
{
_delegate = delegate;
_delegateRespondsToShouldEvictObject = [delegate respondsToSelector:@selector(cache:shouldEvictObject:)];
_delegateRespondsToWillEvictObject = [delegate respondsToSelector:@selector(cache:willEvictObject:)];
}
- (void)setCountLimit:(NSUInteger)countLimit
{
[_lock lock];
_countLimit = countLimit;
[_lock unlock];
[self cleanUp:NO];
}
- (void)setTotalCostLimit:(NSUInteger)totalCostLimit
{
[_lock lock];
_totalCostLimit = totalCostLimit;
[_lock unlock];
[self cleanUp:NO];
}
- (NSUInteger)count
{
return [_cache count];
}
- (void)cleanUp:(BOOL)keepEntries
{
[_lock lock];
NSUInteger maxCount = _countLimit ?: INT_MAX;
NSUInteger maxCost = _totalCostLimit ?: INT_MAX;
NSUInteger totalCount = _cache.count;
NSMutableArray *keys = [_cache.allKeys mutableCopy];
while (totalCount > maxCount || _totalCost > maxCost)
{
NSInteger lowestSequenceNumber = INT_MAX;
OSCacheEntry *lowestEntry = nil;
id lowestKey = nil;
//remove oldest items until within limit
for (id key in keys)
{
OSCacheEntry *entry = _cache[key];
if (entry.sequenceNumber < lowestSequenceNumber)
{
lowestSequenceNumber = entry.sequenceNumber;
lowestEntry = entry;
lowestKey = key;
}
}
if (lowestKey)
{
[keys removeObject:lowestKey];
if (!_delegateRespondsToShouldEvictObject ||
[_delegate cache:(OSCache *)self shouldEvictObject:lowestEntry.object])
{
if (_delegateRespondsToWillEvictObject)
{
_currentlyCleaning = YES;
[self.delegate cache:(OSCache *)self willEvictObject:lowestEntry.object];
_currentlyCleaning = NO;
}
[_cache removeObjectForKey:lowestKey];
_totalCost -= lowestEntry.cost;
totalCount --;
if (keepEntries)
{
[_entryPool addObject:lowestEntry];
lowestEntry.object = nil;
}
}
}
}
[_lock unlock];
}
- (void)cleanUpAllObjects
{
[_lock lock];
if (_delegateRespondsToShouldEvictObject || _delegateRespondsToWillEvictObject)
{
NSArray *keys = [_cache allKeys];
if (_delegateRespondsToShouldEvictObject)
{
//sort, oldest first (in case we want to use that information in our eviction test)
keys = [keys sortedArrayUsingComparator:^NSComparisonResult(id key1, id key2) {
OSCacheEntry *entry1 = self->_cache[key1];
OSCacheEntry *entry2 = self->_cache[key2];
return (NSComparisonResult)MIN(1, MAX(-1, entry1.sequenceNumber - entry2.sequenceNumber));
}];
}
//remove all items individually
for (id key in keys)
{
OSCacheEntry *entry = _cache[key];
if (!_delegateRespondsToShouldEvictObject || [_delegate cache:(OSCache *)self shouldEvictObject:entry.object])
{
if (_delegateRespondsToWillEvictObject)
{
_currentlyCleaning = YES;
[_delegate cache:(OSCache *)self willEvictObject:entry.object];
_currentlyCleaning = NO;
}
[_cache removeObjectForKey:key];
_totalCost -= entry.cost;
}
}
}
else
{
_totalCost = 0;
[_cache removeAllObjects];
_sequenceNumber = 0;
}
[_lock unlock];
}
- (void)resequence
{
//sort, oldest first
NSArray *entries = [[_cache allValues] sortedArrayUsingComparator:^NSComparisonResult(OSCacheEntry *entry1, OSCacheEntry *entry2) {
return (NSComparisonResult)MIN(1, MAX(-1, entry1.sequenceNumber - entry2.sequenceNumber));
}];
//renumber items
NSInteger index = 0;
for (OSCacheEntry *entry in entries)
{
entry.sequenceNumber = index++;
}
}
- (id)objectForKey:(id)key
{
[_lock lock];
OSCacheEntry *entry = _cache[key];
entry.sequenceNumber = _sequenceNumber++;
if (_sequenceNumber < 0)
{
[self resequence];
}
id object = entry.object;
[_lock unlock];
return object;
}
- (id)objectForKeyedSubscript:(id<NSCopying>)key
{
return [self objectForKey:key];
}
- (void)setObject:(id)obj forKey:(id)key
{
[self setObject:obj forKey:key cost:0];
}
- (void)setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key
{
[self setObject:obj forKey:key cost:0];
}
- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g
{
if (!obj)
{
[self removeObjectForKey:key];
return;
}
NSAssert(!_currentlyCleaning, @"It is not possible to modify cache from within the implementation of this delegate method.");
[_lock lock];
_totalCost -= [_cache[key] cost];
_totalCost += g;
OSCacheEntry *entry = _cache[key];
if (!entry) {
entry = [[OSCacheEntry alloc] init];
_cache[key] = entry;
}
entry.object = obj;
entry.cost = g;
entry.sequenceNumber = _sequenceNumber++;
if (_sequenceNumber < 0)
{
[self resequence];
}
[_lock unlock];
[self cleanUp:YES];
}
- (void)removeObjectForKey:(id)key
{
NSAssert(!_currentlyCleaning, @"It is not possible to modify cache from within the implementation of this delegate method.");
[_lock lock];
OSCacheEntry *entry = _cache[key];
if (entry) {
_totalCost -= entry.cost;
entry.object = nil;
[_entryPool addObject:entry];
[_cache removeObjectForKey:key];
}
[_lock unlock];
}
- (void)removeAllObjects
{
NSAssert(!_currentlyCleaning, @"It is not possible to modify cache from within the implementation of this delegate method.");
[_lock lock];
_totalCost = 0;
_sequenceNumber = 0;
for (OSCacheEntry *entry in _cache.allValues)
{
entry.object = nil;
[_entryPool addObject:entry];
}
[_cache removeAllObjects];
[_lock unlock];
}
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
objects:(id __unsafe_unretained [])buffer
count:(NSUInteger)len
{
[_lock lock];
NSUInteger count = [_cache countByEnumeratingWithState:state objects:buffer count:len];
[_lock unlock];
return count;
}
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))block
{
if (block)
{
[_lock lock];
[_cache enumerateKeysAndObjectsUsingBlock:^(id key, OSCacheEntry *entry, BOOL *stop) {
block(key, entry.object, stop);
}];
[_lock unlock];
}
}
//handle unimplemented methods
- (BOOL)isKindOfClass:(Class)aClass
{
//pretend that we're an NSCache if anyone asks
if (aClass == [OSCache class] || aClass == [NSCache class])
{
return YES;
}
return [super isKindOfClass:aClass];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
//protect against calls to unimplemented NSCache methods
NSMethodSignature *signature = [super methodSignatureForSelector:selector];
if (!signature)
{
signature = [NSCache instanceMethodSignatureForSelector:selector];
}
return signature;
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
[invocation invokeWithTarget:nil];
#pragma clang diagnostic pop
}
@end
@implementation OSCache
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
return (OSCache *)[OSCache_Private allocWithZone:zone];
}
- (id)objectForKeyedSubscript:(__unused id<NSCopying>)key { return nil; }
- (void)setObject:(__unused id)obj forKeyedSubscript:(__unused id<NSCopying>)key {}
- (void)enumerateKeysAndObjectsUsingBlock:(__unused void (^)(id, id, BOOL *))block { }
- (NSUInteger)countByEnumeratingWithState:(__unused NSFastEnumerationState *)state
objects:(__unused __unsafe_unretained id [])buffer
count:(__unused NSUInteger)len { return 0; }
@end