react-native-blob-util 0.19.9 → 0.19.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +3 -3
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilImpl.java +1 -1
- package/android/src/newarch/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +1 -1
- package/android/src/oldarch/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +2 -2
- package/index.d.ts +871 -872
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.mm +1 -2
- package/ios/ReactNativeBlobUtilFS.mm +94 -7
- package/ios/ReactNativeBlobUtilRequest.h +2 -2
- package/ios/ReactNativeBlobUtilRequest.mm +88 -43
- package/package.json +1 -1
- package/react-native-blob-util.podspec +1 -1
|
@@ -680,8 +680,7 @@ RCT_EXPORT_METHOD(readFile:(NSString *)path
|
|
|
680
680
|
}
|
|
681
681
|
if([encoding isEqualToString:@"ascii"]) {
|
|
682
682
|
resolve((NSMutableArray *)content);
|
|
683
|
-
}
|
|
684
|
-
if([encoding isEqualToString:@"base64"]) {
|
|
683
|
+
} else if([encoding isEqualToString:@"base64"]) {
|
|
685
684
|
resolve([content base64EncodedStringWithOptions:0]);
|
|
686
685
|
} else {
|
|
687
686
|
resolve([[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding]);
|
|
@@ -581,6 +581,15 @@ NSMutableDictionary *fileStreams = nil;
|
|
|
581
581
|
|
|
582
582
|
# pragma mark - hash
|
|
583
583
|
|
|
584
|
+
typedef enum {
|
|
585
|
+
HashAlgorithmMD5,
|
|
586
|
+
HashAlgorithmSHA1,
|
|
587
|
+
HashAlgorithmSHA224,
|
|
588
|
+
HashAlgorithmSHA256,
|
|
589
|
+
HashAlgorithmSHA384,
|
|
590
|
+
HashAlgorithmSHA512,
|
|
591
|
+
} HashAlgorithm;
|
|
592
|
+
|
|
584
593
|
+ (void) hash:(NSString *)path
|
|
585
594
|
algorithm:(NSString *)algorithm
|
|
586
595
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
@@ -611,7 +620,11 @@ NSMutableDictionary *fileStreams = nil;
|
|
|
611
620
|
return;
|
|
612
621
|
}
|
|
613
622
|
|
|
614
|
-
|
|
623
|
+
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
|
|
624
|
+
if (fileHandle == nil) {
|
|
625
|
+
reject(@"EUNKNOWN", [NSString stringWithFormat:@"Error opening '%@' for reading", path], error);
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
615
628
|
|
|
616
629
|
NSArray *keys = [NSArray arrayWithObjects:@"md5", @"sha1", @"sha224", @"sha256", @"sha384", @"sha512", nil];
|
|
617
630
|
|
|
@@ -634,23 +647,97 @@ NSMutableDictionary *fileStreams = nil;
|
|
|
634
647
|
|
|
635
648
|
unsigned char buffer[digestLength];
|
|
636
649
|
|
|
650
|
+
const NSUInteger chunkSize = 1024 * 1024; // 1 Megabyte
|
|
651
|
+
NSData *dataChunk;
|
|
652
|
+
|
|
653
|
+
CC_MD5_CTX md5Context;
|
|
654
|
+
CC_SHA1_CTX sha1Context;
|
|
655
|
+
CC_SHA256_CTX sha256Context;
|
|
656
|
+
CC_SHA512_CTX sha512Context;
|
|
657
|
+
HashAlgorithm hashAlgorithm;
|
|
658
|
+
|
|
637
659
|
if ([algorithm isEqualToString:@"md5"]) {
|
|
638
|
-
|
|
660
|
+
CC_MD5_Init(&md5Context);
|
|
661
|
+
hashAlgorithm = HashAlgorithmMD5;
|
|
639
662
|
} else if ([algorithm isEqualToString:@"sha1"]) {
|
|
640
|
-
|
|
663
|
+
CC_SHA1_Init(&sha1Context);
|
|
664
|
+
hashAlgorithm = HashAlgorithmSHA1;
|
|
641
665
|
} else if ([algorithm isEqualToString:@"sha224"]) {
|
|
642
|
-
|
|
666
|
+
CC_SHA224_Init(&sha256Context);
|
|
667
|
+
hashAlgorithm = HashAlgorithmSHA224;
|
|
643
668
|
} else if ([algorithm isEqualToString:@"sha256"]) {
|
|
644
|
-
|
|
669
|
+
CC_SHA256_Init(&sha256Context);
|
|
670
|
+
hashAlgorithm = HashAlgorithmSHA256;
|
|
645
671
|
} else if ([algorithm isEqualToString:@"sha384"]) {
|
|
646
|
-
|
|
672
|
+
CC_SHA384_Init(&sha512Context);
|
|
673
|
+
hashAlgorithm = HashAlgorithmSHA384;
|
|
647
674
|
} else if ([algorithm isEqualToString:@"sha512"]) {
|
|
648
|
-
|
|
675
|
+
CC_SHA512_Init(&sha512Context);
|
|
676
|
+
hashAlgorithm = HashAlgorithmSHA512;
|
|
649
677
|
} else {
|
|
650
678
|
reject(@"EINVAL", [NSString stringWithFormat:@"Invalid algorithm '%@', must be one of md5, sha1, sha224, sha256, sha384, sha512", algorithm], nil);
|
|
651
679
|
return;
|
|
652
680
|
}
|
|
653
681
|
|
|
682
|
+
while (true) {
|
|
683
|
+
@autoreleasepool {
|
|
684
|
+
dataChunk = [fileHandle readDataUpToLength:chunkSize error:&error];
|
|
685
|
+
|
|
686
|
+
if (error) {
|
|
687
|
+
return reject(@"EREAD", [NSString stringWithFormat:@"Error reading file '%@'", path], error);
|
|
688
|
+
break;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
if (dataChunk == nil || dataChunk.length == 0) {
|
|
692
|
+
break;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
switch(hashAlgorithm) {
|
|
696
|
+
case HashAlgorithmMD5:
|
|
697
|
+
CC_MD5_Update(&md5Context, [dataChunk bytes], CC_LONG([dataChunk length]));
|
|
698
|
+
break;
|
|
699
|
+
case HashAlgorithmSHA1:
|
|
700
|
+
CC_SHA1_Update(&sha1Context, [dataChunk bytes], CC_LONG([dataChunk length]));
|
|
701
|
+
break;
|
|
702
|
+
case HashAlgorithmSHA224:
|
|
703
|
+
CC_SHA224_Update(&sha256Context, [dataChunk bytes], CC_LONG([dataChunk length]));
|
|
704
|
+
break;
|
|
705
|
+
case HashAlgorithmSHA256:
|
|
706
|
+
CC_SHA256_Update(&sha256Context, [dataChunk bytes], CC_LONG([dataChunk length]));
|
|
707
|
+
break;
|
|
708
|
+
case HashAlgorithmSHA384:
|
|
709
|
+
CC_SHA384_Update(&sha512Context, [dataChunk bytes], CC_LONG([dataChunk length]));
|
|
710
|
+
break;
|
|
711
|
+
case HashAlgorithmSHA512:
|
|
712
|
+
CC_SHA512_Update(&sha512Context, [dataChunk bytes], CC_LONG([dataChunk length]));
|
|
713
|
+
break;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
dataChunk = nil;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
switch(hashAlgorithm) {
|
|
721
|
+
case HashAlgorithmMD5:
|
|
722
|
+
CC_MD5_Final(buffer, &md5Context);
|
|
723
|
+
break;
|
|
724
|
+
case HashAlgorithmSHA1:
|
|
725
|
+
CC_SHA1_Final(buffer, &sha1Context);
|
|
726
|
+
break;
|
|
727
|
+
case HashAlgorithmSHA224:
|
|
728
|
+
CC_SHA224_Final(buffer, &sha256Context);
|
|
729
|
+
break;
|
|
730
|
+
case HashAlgorithmSHA256:
|
|
731
|
+
CC_SHA256_Final(buffer, &sha256Context);
|
|
732
|
+
break;
|
|
733
|
+
case HashAlgorithmSHA384:
|
|
734
|
+
CC_SHA384_Final(buffer, &sha512Context);
|
|
735
|
+
break;
|
|
736
|
+
case HashAlgorithmSHA512:
|
|
737
|
+
CC_SHA512_Final(buffer, &sha512Context);
|
|
738
|
+
break;
|
|
739
|
+
}
|
|
740
|
+
|
|
654
741
|
NSMutableString *output = [NSMutableString stringWithCapacity:digestLength * 2];
|
|
655
742
|
for(int i = 0; i < digestLength; i++)
|
|
656
743
|
[output appendFormat:@"%02x",buffer[i]];
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
#import "RCTBridgeModule.h"
|
|
21
21
|
#endif
|
|
22
22
|
|
|
23
|
-
@interface ReactNativeBlobUtilRequest : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
|
|
23
|
+
@interface ReactNativeBlobUtilRequest : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
|
|
24
24
|
|
|
25
25
|
@property (nullable, nonatomic) NSString * taskId;
|
|
26
26
|
@property (nonatomic) long long expectedBytes;
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
@property (nullable, nonatomic) NSError * error;
|
|
34
34
|
@property (nullable, nonatomic) ReactNativeBlobUtilProgress *progressConfig;
|
|
35
35
|
@property (nullable, nonatomic) ReactNativeBlobUtilProgress *uploadProgressConfig;
|
|
36
|
-
@property (nullable, nonatomic, weak)
|
|
36
|
+
@property (nullable, nonatomic, weak) NSURLSessionTask *task;
|
|
37
37
|
|
|
38
38
|
- (void) sendRequest:(NSDictionary * _Nullable )options
|
|
39
39
|
contentLength:(long)contentLength
|
|
@@ -167,9 +167,15 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
|
|
167
167
|
respFile = NO;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
if(backgroundTask) {
|
|
171
|
+
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:req];
|
|
172
|
+
[task resume];
|
|
173
|
+
self.task = task;
|
|
174
|
+
} else {
|
|
175
|
+
NSURLSessionDataTask *task = [session dataTaskWithRequest:req];
|
|
176
|
+
[task resume];
|
|
177
|
+
self.task = task;
|
|
178
|
+
}
|
|
173
179
|
|
|
174
180
|
// network status indicator
|
|
175
181
|
if ([[options objectForKey:CONFIG_INDICATOR] boolValue]) {
|
|
@@ -188,6 +194,52 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
|
|
188
194
|
|
|
189
195
|
#pragma mark NSURLSession delegate methods
|
|
190
196
|
|
|
197
|
+
- (void)configureWriteStream {
|
|
198
|
+
if (respFile)
|
|
199
|
+
{
|
|
200
|
+
@try{
|
|
201
|
+
NSFileManager * fm = [NSFileManager defaultManager];
|
|
202
|
+
NSString * folder = [destPath stringByDeletingLastPathComponent];
|
|
203
|
+
|
|
204
|
+
if (![fm fileExistsAtPath:folder]) {
|
|
205
|
+
[fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:nil];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// if not set overwrite in options, defaults to TRUE
|
|
209
|
+
BOOL overwrite = [options valueForKey:@"overwrite"] == nil ? YES : [[options valueForKey:@"overwrite"] boolValue];
|
|
210
|
+
BOOL appendToExistingFile = [destPath containsString:@"?append=true"];
|
|
211
|
+
|
|
212
|
+
appendToExistingFile = !overwrite;
|
|
213
|
+
|
|
214
|
+
// For solving #141 append response data if the file already exists
|
|
215
|
+
// base on PR#139 @kejinliang
|
|
216
|
+
if (appendToExistingFile) {
|
|
217
|
+
destPath = [destPath stringByReplacingOccurrencesOfString:@"?append=true" withString:@""];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (![fm fileExistsAtPath:destPath]) {
|
|
221
|
+
[fm createFileAtPath:destPath contents:[[NSData alloc] init] attributes:nil];
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
writeStream = [[NSOutputStream alloc] initToFileAtPath:destPath append:appendToExistingFile];
|
|
225
|
+
[writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
|
|
226
|
+
[writeStream open];
|
|
227
|
+
}
|
|
228
|
+
@catch(NSException * ex)
|
|
229
|
+
{
|
|
230
|
+
NSLog(@"write file error");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
- (void)processData:(NSData *)data {
|
|
236
|
+
if (respFile && ![self ShouldTransformFile]) {
|
|
237
|
+
[writeStream write:(const uint8_t *)[data bytes] maxLength:[data length]];
|
|
238
|
+
} else {
|
|
239
|
+
[respData appendData:data];
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
191
243
|
|
|
192
244
|
#pragma mark - Received Response
|
|
193
245
|
// set expected content length on response received
|
|
@@ -278,41 +330,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
|
|
278
330
|
NSLog(@"oops");
|
|
279
331
|
}
|
|
280
332
|
|
|
281
|
-
|
|
282
|
-
{
|
|
283
|
-
@try{
|
|
284
|
-
NSFileManager * fm = [NSFileManager defaultManager];
|
|
285
|
-
NSString * folder = [destPath stringByDeletingLastPathComponent];
|
|
286
|
-
|
|
287
|
-
if (![fm fileExistsAtPath:folder]) {
|
|
288
|
-
[fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:nil];
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// if not set overwrite in options, defaults to TRUE
|
|
292
|
-
BOOL overwrite = [options valueForKey:@"overwrite"] == nil ? YES : [[options valueForKey:@"overwrite"] boolValue];
|
|
293
|
-
BOOL appendToExistingFile = [destPath containsString:@"?append=true"];
|
|
294
|
-
|
|
295
|
-
appendToExistingFile = !overwrite;
|
|
296
|
-
|
|
297
|
-
// For solving #141 append response data if the file already exists
|
|
298
|
-
// base on PR#139 @kejinliang
|
|
299
|
-
if (appendToExistingFile) {
|
|
300
|
-
destPath = [destPath stringByReplacingOccurrencesOfString:@"?append=true" withString:@""];
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (![fm fileExistsAtPath:destPath]) {
|
|
304
|
-
[fm createFileAtPath:destPath contents:[[NSData alloc] init] attributes:nil];
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
writeStream = [[NSOutputStream alloc] initToFileAtPath:destPath append:appendToExistingFile];
|
|
308
|
-
[writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
|
|
309
|
-
[writeStream open];
|
|
310
|
-
}
|
|
311
|
-
@catch(NSException * ex)
|
|
312
|
-
{
|
|
313
|
-
NSLog(@"write file error");
|
|
314
|
-
}
|
|
315
|
-
}
|
|
333
|
+
[self configureWriteStream];
|
|
316
334
|
|
|
317
335
|
completionHandler(NSURLSessionResponseAllow);
|
|
318
336
|
}
|
|
@@ -339,11 +357,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
|
|
339
357
|
|
|
340
358
|
// If we need to process the data, we defer writing into the file until the we have all the data, at which point
|
|
341
359
|
// we can perform the processing and then write into the file
|
|
342
|
-
|
|
343
|
-
[writeStream write:(const uint8_t *)[data bytes] maxLength:[data length]];
|
|
344
|
-
} else {
|
|
345
|
-
[respData appendData:data];
|
|
346
|
-
}
|
|
360
|
+
[self processData:data];
|
|
347
361
|
|
|
348
362
|
if (expectedBytes == 0) {
|
|
349
363
|
return;
|
|
@@ -535,5 +549,36 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
|
|
535
549
|
}
|
|
536
550
|
}
|
|
537
551
|
|
|
552
|
+
// NSURLSessionDownloadTask delegates
|
|
553
|
+
|
|
554
|
+
#pragma mark NSURLSessionDownloadTask delegate methods
|
|
555
|
+
|
|
556
|
+
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
|
|
557
|
+
|
|
558
|
+
NSFileManager *fm = [NSFileManager defaultManager];
|
|
559
|
+
NSData *data = [fm contentsAtPath:location.path];
|
|
560
|
+
|
|
561
|
+
[self configureWriteStream];
|
|
562
|
+
|
|
563
|
+
[self processData:data];
|
|
564
|
+
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
|
|
568
|
+
if (totalBytesExpectedToWrite == 0) {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
NSNumber * now =[NSNumber numberWithFloat:((float)totalBytesWritten/(float)totalBytesExpectedToWrite)];
|
|
573
|
+
if ([self.progressConfig shouldReport:now]) {
|
|
574
|
+
[self.baseModule emitEventDict:EVENT_PROGRESS
|
|
575
|
+
body:@{
|
|
576
|
+
@"taskId": taskId,
|
|
577
|
+
@"written": [NSString stringWithFormat:@"%lld", (long long) totalBytesWritten],
|
|
578
|
+
@"total": [NSString stringWithFormat:@"%lld", (long long) totalBytesExpectedToWrite]
|
|
579
|
+
}
|
|
580
|
+
];
|
|
581
|
+
}
|
|
582
|
+
}
|
|
538
583
|
|
|
539
584
|
@end
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
|
|
|
10
10
|
s.requires_arc = true
|
|
11
11
|
s.license = 'MIT'
|
|
12
12
|
s.homepage = 'n/a'
|
|
13
|
-
s.source = { :git => "https://github.com/RonRadtke/react-native-blob-util" }
|
|
13
|
+
s.source = { :git => "https://github.com/RonRadtke/react-native-blob-util", :tag => "v#{s.version.to_s}" }
|
|
14
14
|
s.author = 'RonRadtke'
|
|
15
15
|
s.source_files = 'ios/**/*.{h,m,mm,swift}'
|
|
16
16
|
s.resource_bundles = {
|