123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- //
- // QNPartsUploadApiV1.m
- // QiniuSDK
- //
- // Created by yangsen on 2020/11/30.
- // Copyright © 2020 Qiniu. All rights reserved.
- //
- #import "QNLogUtil.h"
- #import "QNDefine.h"
- #import "QNRequestTransaction.h"
- #import "QNUploadFileInfoPartV1.h"
- #import "QNPartsUploadPerformerV1.h"
- @interface QNPartsUploadPerformerV1()
- @end
- @implementation QNPartsUploadPerformerV1
- + (long long)blockSize{
- return 4 * 1024 * 1024;
- }
- - (QNUploadFileInfo *)getFileInfoWithDictionary:(NSDictionary *)fileInfoDictionary {
- return [QNUploadFileInfoPartV1 infoFromDictionary:fileInfoDictionary];
- }
- - (QNUploadFileInfo *)getDefaultUploadFileInfo {
- return [[QNUploadFileInfoPartV1 alloc] initWithFileSize:[self.file size]
- blockSize:[QNPartsUploadPerformerV1 blockSize]
- dataSize:[self getUploadChunkSize]
- modifyTime:[self.file modifyTime]];
- }
- - (void)serverInit:(void(^)(QNResponseInfo * _Nullable responseInfo,
- QNUploadRegionRequestMetrics * _Nullable metrics,
- NSDictionary * _Nullable response))completeHandler {
- QNResponseInfo *responseInfo = [QNResponseInfo successResponse];
- completeHandler(responseInfo, nil, nil);
- }
- - (void)uploadNextData:(void(^)(BOOL stop,
- QNResponseInfo * _Nullable responseInfo,
- QNUploadRegionRequestMetrics * _Nullable metrics,
- NSDictionary * _Nullable response))completeHandler {
- QNUploadFileInfoPartV1 *fileInfo = (QNUploadFileInfoPartV1 *)self.fileInfo;
-
- QNUploadBlock *block = nil;
- QNUploadData *chunk = nil;
- @synchronized (self) {
- block = [fileInfo nextUploadBlock];
- chunk = [block nextUploadData];
- chunk.isUploading = YES;
- chunk.isCompleted = NO;
- }
- if (block == nil || chunk == nil) {
- QNLogInfo(@"key:%@ no chunk left", self.key);
-
- QNResponseInfo *responseInfo = [QNResponseInfo responseInfoWithSDKInteriorError:@"no chunk left"];
- completeHandler(YES, responseInfo, nil, nil);
- return;
- }
-
- NSData *chunkData = [self getDataWithChunk:chunk block:block];
- if (chunkData == nil) {
- QNLogInfo(@"key:%@ get chunk data error", self.key);
-
- chunk.isUploading = NO;
- chunk.isCompleted = NO;
- QNResponseInfo *responseInfo = [QNResponseInfo responseInfoWithLocalIOError:@"get chunk data error"];
- completeHandler(YES, responseInfo, nil, nil);
- return;
- }
-
- kQNWeakSelf;
- void (^progress)(long long, long long) = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite){
- kQNStrongSelf;
-
- chunk.progress = (float)totalBytesWritten / (float)totalBytesExpectedToWrite;
- [self notifyProgress];
- };
-
- void (^completeHandlerP)(QNResponseInfo *, QNUploadRegionRequestMetrics *, NSDictionary *) = ^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
- kQNStrongSelf;
-
- NSString *blockContext = response[@"ctx"];
- if (responseInfo.isOK && blockContext) {
- block.context = blockContext;
- chunk.progress = 1;
- chunk.isUploading = NO;
- chunk.isCompleted = YES;
- [self recordUploadInfo];
- [self notifyProgress];
- } else {
- chunk.isUploading = NO;
- chunk.isCompleted = NO;
- }
- completeHandler(NO, responseInfo, metrics, response);
- };
-
- if (chunk.isFirstData) {
- QNLogInfo(@"key:%@ makeBlock", self.key);
- [self makeBlock:block firstChunk:chunk chunkData:chunkData progress:progress completeHandler:completeHandlerP];
- } else {
- QNLogInfo(@"key:%@ uploadChunk", self.key);
- [self uploadChunk:block chunk:chunk chunkData:chunkData progress:progress completeHandler:completeHandlerP];
- }
- }
- - (void)completeUpload:(void(^)(QNResponseInfo * _Nullable responseInfo,
- QNUploadRegionRequestMetrics * _Nullable metrics,
- NSDictionary * _Nullable response))completeHandler {
- QNUploadFileInfoPartV1 *fileInfo = (QNUploadFileInfoPartV1 *)self.fileInfo;
-
- QNRequestTransaction *transaction = [self createUploadRequestTransaction];
-
- kQNWeakSelf;
- kQNWeakObj(transaction);
- [transaction makeFile:fileInfo.size
- fileName:self.fileName
- blockContexts:[fileInfo allBlocksContexts]
- complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
- kQNStrongSelf;
- kQNStrongObj(transaction);
-
- completeHandler(responseInfo, metrics, response);
- [self destroyUploadRequestTransaction:transaction];
- }];
- }
- - (void)makeBlock:(QNUploadBlock *)block
- firstChunk:(QNUploadData *)chunk
- chunkData:(NSData *)chunkData
- progress:(void(^)(long long totalBytesWritten,
- long long totalBytesExpectedToWrite))progress
- completeHandler:(void(^)(QNResponseInfo * _Nullable responseInfo,
- QNUploadRegionRequestMetrics * _Nullable metrics,
- NSDictionary * _Nullable response))completeHandler {
-
- QNRequestTransaction *transaction = [self createUploadRequestTransaction];
- kQNWeakSelf;
- kQNWeakObj(transaction);
- [transaction makeBlock:block.offset
- blockSize:block.size
- firstChunkData:chunkData
- progress:progress
- complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
- kQNStrongSelf;
- kQNStrongObj(transaction);
-
- completeHandler(responseInfo, metrics, response);
- [self destroyUploadRequestTransaction:transaction];
- }];
- }
- - (void)uploadChunk:(QNUploadBlock *)block
- chunk:(QNUploadData *)chunk
- chunkData:(NSData *)chunkData
- progress:(void(^)(long long totalBytesWritten,
- long long totalBytesExpectedToWrite))progress
- completeHandler:(void(^)(QNResponseInfo * _Nullable responseInfo,
- QNUploadRegionRequestMetrics * _Nullable metrics,
- NSDictionary * _Nullable response))completeHandler {
-
- QNRequestTransaction *transaction = [self createUploadRequestTransaction];
- kQNWeakSelf;
- kQNWeakObj(transaction);
- [transaction uploadChunk:block.context
- blockOffset:block.offset
- chunkData:chunkData
- chunkOffset:chunk.offset
- progress:progress
- complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
- kQNStrongSelf;
- kQNStrongObj(transaction);
-
- completeHandler(responseInfo, metrics, response);
- [self destroyUploadRequestTransaction:transaction];
- }];
- }
- - (NSData *)getDataWithChunk:(QNUploadData *)chunk block:(QNUploadBlock *)block{
- if (!self.file) {
- return nil;
- }
- NSError *error = nil;
- NSData *data = [self.file read:(long)(chunk.offset + block.offset)
- size:(long)chunk.size
- error:&error];
-
- return error ? nil : data;
- }
- - (long long)getUploadChunkSize{
- if (self.config.useConcurrentResumeUpload) {
- return [QNPartsUploadPerformerV1 blockSize];
- } else {
- return self.config.chunkSize;
- }
- }
- @end
|