// // MCDownloadReceipt.m // MCDownloadManager // // Created by M.C on 17/4/6. (QQ:714080794 Gmail:chaoma0609@gmail.com) // Copyright © 2017年 qikeyun. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #import "MCDownloadReceipt.h" #import extern NSString * cacheFolder(); static unsigned long long fileSizeForPath(NSString *path) { signed long long fileSize = 0; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:path]) { NSError *error = nil; NSDictionary *fileDict = [fileManager attributesOfItemAtPath:path error:&error]; if (!error && fileDict) { fileSize = [fileDict fileSize]; } } return fileSize; } static NSString * getMD5String(NSString *str) { if (str == nil) return nil; const char *cstring = str.UTF8String; unsigned char bytes[CC_MD5_DIGEST_LENGTH]; CC_MD5(cstring, (CC_LONG)strlen(cstring), bytes); NSMutableString *md5String = [NSMutableString string]; for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { [md5String appendFormat:@"%02x", bytes[i]]; } return md5String; } @interface MCDownloadReceipt() @property (nonatomic, assign) MCDownloadState state; @property (nonatomic, copy) NSString *url; @property (nonatomic, copy) NSString *filePath; @property (nonatomic, copy) NSString *filename; @property (nonatomic, copy) NSString *truename; @property (nonatomic, strong) NSProgress *progress; @property (assign, nonatomic) long long totalBytesWritten; @end @implementation MCDownloadReceipt - (NSString *)filePath { NSString *path = [cacheFolder() stringByAppendingPathComponent:self.filename]; if (![path isEqualToString:_filePath] ) { if (_filePath && ![[NSFileManager defaultManager] fileExistsAtPath:_filePath]) { NSString *dir = [_filePath stringByDeletingLastPathComponent]; [[NSFileManager defaultManager] createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil]; } _filePath = path; } return _filePath; } - (NSString *)filename { if (_filename == nil) { NSString *pathExtension = self.url.pathExtension; if (pathExtension.length) { _filename = [NSString stringWithFormat:@"%@.%@", getMD5String(self.url), pathExtension]; } else { _filename = getMD5String(self.url); } } return _filename; } - (NSString *)truename { if (_truename == nil) { _truename = self.url.lastPathComponent; } return _truename; } - (NSProgress *)progress { if (_progress == nil) { _progress = [[NSProgress alloc] initWithParent:nil userInfo:nil]; } @try { _progress.totalUnitCount = self.totalBytesExpectedToWrite; _progress.completedUnitCount = self.totalBytesWritten; } @catch (NSException *exception) { } return _progress; } - (long long)totalBytesWritten { return fileSizeForPath(self.filePath); } - (instancetype)initWithURL:(NSString *)url { if (self = [self init]) { self.url = url; } return self; } #pragma mark - NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.url forKey:NSStringFromSelector(@selector(url))]; [aCoder encodeObject:self.filePath forKey:NSStringFromSelector(@selector(filePath))]; [aCoder encodeObject:@(self.state) forKey:NSStringFromSelector(@selector(state))]; [aCoder encodeObject:self.filename forKey:NSStringFromSelector(@selector(filename))]; [aCoder encodeObject:@(self.totalBytesWritten) forKey:NSStringFromSelector(@selector(totalBytesWritten))]; [aCoder encodeObject:@(self.totalBytesExpectedToWrite) forKey:NSStringFromSelector(@selector(totalBytesExpectedToWrite))]; } - (id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (self) { self.url = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(url))]; self.filePath = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(filePath))]; self.state = [[aDecoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(state))] unsignedIntegerValue]; self.filename = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(filename))]; self.totalBytesWritten = [[aDecoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(totalBytesWritten))] unsignedIntegerValue]; self.totalBytesExpectedToWrite = [[aDecoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(totalBytesExpectedToWrite))] unsignedIntegerValue]; } return self; } - (instancetype)initWithURLString:(NSString *)URLString downloadOperationCancelToken:(id)downloadOperationCancelToken downloaderProgressBlock:(MCDownloaderProgressBlock)downloaderProgressBlock downloaderCompletedBlock:(MCDownloaderCompletedBlock)downloaderCompletedBlock { if (self = [self init]) { self.url = URLString; self.totalBytesExpectedToWrite = 0; self.downloadOperationCancelToken = downloadOperationCancelToken; self.downloaderProgressBlock = downloaderProgressBlock; self.downloaderCompletedBlock = downloaderCompletedBlock; } return self; } - (void)setTotalBytesExpectedToWrite:(long long)totalBytesExpectedToWrite { _totalBytesExpectedToWrite = totalBytesExpectedToWrite; } - (void)setState:(MCDownloadState)state { _state = state; } - (void)setDownloadOperationCancelToken:(id)downloadOperationCancelToken { _downloadOperationCancelToken = downloadOperationCancelToken; } - (void)setDownloaderProgressBlock:(MCDownloaderProgressBlock)downloaderProgressBlock { _downloaderProgressBlock = downloaderProgressBlock; } - (void)setDownloaderCompletedBlock:(MCDownloaderCompletedBlock)downloaderCompletedBlock { _downloaderCompletedBlock = downloaderCompletedBlock; } - (void)setSpeed:(NSString *)speed { _speed = speed; } @end