Browse Source

Add test case and exception handling for #247

fastfix
Ben Hsieh 8 years ago
parent
commit
dc17e308ce

+ 8
- 2
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java View File

28
 import java.io.IOException;
28
 import java.io.IOException;
29
 import java.io.InputStream;
29
 import java.io.InputStream;
30
 import java.io.OutputStream;
30
 import java.io.OutputStream;
31
+import java.nio.ByteBuffer;
31
 import java.nio.charset.Charset;
32
 import java.nio.charset.Charset;
33
+import java.nio.charset.CharsetEncoder;
32
 import java.util.HashMap;
34
 import java.util.HashMap;
33
 import java.util.Map;
35
 import java.util.Map;
34
 import java.util.UUID;
36
 import java.util.UUID;
243
             boolean error = false;
245
             boolean error = false;
244
 
246
 
245
             if (encoding.equalsIgnoreCase("utf8")) {
247
             if (encoding.equalsIgnoreCase("utf8")) {
248
+                CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
246
                 while ((cursor = fs.read(buffer)) != -1) {
249
                 while ((cursor = fs.read(buffer)) != -1) {
247
-                    String chunk = new String(buffer, 0, cursor, "UTF-8");
250
+                    encoder.encode(ByteBuffer.wrap(buffer).asCharBuffer());
251
+                    // if the data contains invalid characters the following lines will be
252
+                    // skipped.
253
+                    String chunk = new String(buffer);
248
                     emitStreamEvent(streamId, "data", chunk);
254
                     emitStreamEvent(streamId, "data", chunk);
249
                     if(tick > 0)
255
                     if(tick > 0)
250
                         SystemClock.sleep(tick);
256
                         SystemClock.sleep(tick);
286
             buffer = null;
292
             buffer = null;
287
 
293
 
288
         } catch (Exception err) {
294
         } catch (Exception err) {
289
-            emitStreamEvent(streamId, "error", err.getLocalizedMessage());
295
+            emitStreamEvent(streamId, "error", "Failed to convert data to "+encoding+" encoded string, this might due to the source data is not able to convert using this encoding.");
290
         }
296
         }
291
     }
297
     }
292
 
298
 

+ 60
- 40
src/ios/RNFetchBlob/RNFetchBlob.m View File

131
         callback(@[[NSString stringWithFormat:@"failed to create new file at path %@ please ensure the folder exists"]]);
131
         callback(@[[NSString stringWithFormat:@"failed to create new file at path %@ please ensure the folder exists"]]);
132
 
132
 
133
 }
133
 }
134
+
134
 #pragma mark - fs.createFileASCII
135
 #pragma mark - fs.createFileASCII
135
 // method for create file with ASCII content
136
 // method for create file with ASCII content
136
 RCT_EXPORT_METHOD(createFileASCII:(NSString *)path data:(NSArray *)dataArray callback:(RCTResponseSenderBlock)callback) {
137
 RCT_EXPORT_METHOD(createFileASCII:(NSString *)path data:(NSArray *)dataArray callback:(RCTResponseSenderBlock)callback) {
159
 }
160
 }
160
 
161
 
161
 #pragma mark - fs.writeFile
162
 #pragma mark - fs.writeFile
162
-RCT_EXPORT_METHOD(writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
163
+RCT_EXPORT_METHOD(writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
164
+{
163
     [RNFetchBlobFS writeFile:path encoding:[NSString stringWithString:encoding] data:data append:append resolver:resolve rejecter:reject];
165
     [RNFetchBlobFS writeFile:path encoding:[NSString stringWithString:encoding] data:data append:append resolver:resolve rejecter:reject];
164
-})
166
+}
165
 
167
 
166
 #pragma mark - fs.writeArray
168
 #pragma mark - fs.writeArray
167
-RCT_EXPORT_METHOD(writeFileArray:(NSString *)path data:(NSArray *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
169
+RCT_EXPORT_METHOD(writeFileArray:(NSString *)path data:(NSArray *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
170
+{
168
     [RNFetchBlobFS writeFileArray:path data:data append:append resolver:resolve rejecter:reject];
171
     [RNFetchBlobFS writeFileArray:path data:data append:append resolver:resolve rejecter:reject];
169
-})
172
+}
170
 
173
 
171
 #pragma mark - fs.writeStream
174
 #pragma mark - fs.writeStream
172
-RCT_EXPORT_METHOD(writeStream:(NSString *)path withEncoding:(NSString *)encoding appendData:(BOOL)append callback:(RCTResponseSenderBlock)callback) {
175
+RCT_EXPORT_METHOD(writeStream:(NSString *)path withEncoding:(NSString *)encoding appendData:(BOOL)append callback:(RCTResponseSenderBlock)callback)
176
+{
173
     RNFetchBlobFS * fileStream = [[RNFetchBlobFS alloc] initWithBridgeRef:self.bridge];
177
     RNFetchBlobFS * fileStream = [[RNFetchBlobFS alloc] initWithBridgeRef:self.bridge];
174
     NSFileManager * fm = [NSFileManager defaultManager];
178
     NSFileManager * fm = [NSFileManager defaultManager];
175
     BOOL isDir = nil;
179
     BOOL isDir = nil;
183
 }
187
 }
184
 
188
 
185
 #pragma mark - fs.writeArrayChunk
189
 #pragma mark - fs.writeArrayChunk
186
-RCT_EXPORT_METHOD(writeArrayChunk:(NSString *)streamId withArray:(NSArray *)dataArray callback:(RCTResponseSenderBlock) callback) {
190
+RCT_EXPORT_METHOD(writeArrayChunk:(NSString *)streamId withArray:(NSArray *)dataArray callback:(RCTResponseSenderBlock) callback)
191
+{
187
     RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
192
     RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
188
     char * bytes = (char *) malloc([dataArray count]);
193
     char * bytes = (char *) malloc([dataArray count]);
189
     for(int i = 0; i < dataArray.count; i++) {
194
     for(int i = 0; i < dataArray.count; i++) {
197
 }
202
 }
198
 
203
 
199
 #pragma mark - fs.writeChunk
204
 #pragma mark - fs.writeChunk
200
-RCT_EXPORT_METHOD(writeChunk:(NSString *)streamId withData:(NSString *)data callback:(RCTResponseSenderBlock) callback) {
205
+RCT_EXPORT_METHOD(writeChunk:(NSString *)streamId withData:(NSString *)data callback:(RCTResponseSenderBlock) callback)
206
+{
201
     RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
207
     RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
202
     [fs writeEncodeChunk:data];
208
     [fs writeEncodeChunk:data];
203
     callback(@[[NSNull null]]);
209
     callback(@[[NSNull null]]);
204
 }
210
 }
205
 
211
 
206
 #pragma mark - fs.closeStream
212
 #pragma mark - fs.closeStream
207
-RCT_EXPORT_METHOD(closeStream:(NSString *)streamId callback:(RCTResponseSenderBlock) callback) {
213
+RCT_EXPORT_METHOD(closeStream:(NSString *)streamId callback:(RCTResponseSenderBlock) callback)
214
+{
208
     RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
215
     RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
209
     [fs closeOutStream];
216
     [fs closeOutStream];
210
     callback(@[[NSNull null], @YES]);
217
     callback(@[[NSNull null], @YES]);
211
 }
218
 }
212
 
219
 
213
 #pragma mark - unlink
220
 #pragma mark - unlink
214
-RCT_EXPORT_METHOD(unlink:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
221
+RCT_EXPORT_METHOD(unlink:(NSString *)path callback:(RCTResponseSenderBlock) callback)
222
+{
215
     NSError * error = nil;
223
     NSError * error = nil;
216
     NSString * tmpPath = nil;
224
     NSString * tmpPath = nil;
217
     [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
225
     [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
222
 }
230
 }
223
 
231
 
224
 #pragma mark - fs.removeSession
232
 #pragma mark - fs.removeSession
225
-RCT_EXPORT_METHOD(removeSession:(NSArray *)paths callback:(RCTResponseSenderBlock) callback) {
233
+RCT_EXPORT_METHOD(removeSession:(NSArray *)paths callback:(RCTResponseSenderBlock) callback)
234
+{
226
     NSError * error = nil;
235
     NSError * error = nil;
227
     NSString * tmpPath = nil;
236
     NSString * tmpPath = nil;
228
 
237
 
238
 }
247
 }
239
 
248
 
240
 #pragma mark - fs.ls
249
 #pragma mark - fs.ls
241
-RCT_EXPORT_METHOD(ls:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
250
+RCT_EXPORT_METHOD(ls:(NSString *)path callback:(RCTResponseSenderBlock) callback)
251
+{
242
     NSFileManager* fm = [NSFileManager defaultManager];
252
     NSFileManager* fm = [NSFileManager defaultManager];
243
     BOOL exist = nil;
253
     BOOL exist = nil;
244
     BOOL isDir = nil;
254
     BOOL isDir = nil;
258
 }
268
 }
259
 
269
 
260
 #pragma mark - fs.stat
270
 #pragma mark - fs.stat
261
-RCT_EXPORT_METHOD(stat:(NSString *)target callback:(RCTResponseSenderBlock) callback) {
271
+RCT_EXPORT_METHOD(stat:(NSString *)target callback:(RCTResponseSenderBlock) callback)
272
+{
262
     
273
     
263
     [RNFetchBlobFS getPathFromUri:target completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
274
     [RNFetchBlobFS getPathFromUri:target completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
264
         __block NSMutableArray * result;
275
         __block NSMutableArray * result;
297
 }
308
 }
298
 
309
 
299
 #pragma mark - fs.lstat
310
 #pragma mark - fs.lstat
300
-RCT_EXPORT_METHOD(lstat:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
311
+RCT_EXPORT_METHOD(lstat:(NSString *)path callback:(RCTResponseSenderBlock) callback)
312
+{
301
     NSFileManager* fm = [NSFileManager defaultManager];
313
     NSFileManager* fm = [NSFileManager defaultManager];
302
     BOOL exist = nil;
314
     BOOL exist = nil;
303
     BOOL isDir = nil;
315
     BOOL isDir = nil;
331
 }
343
 }
332
 
344
 
333
 #pragma mark - fs.cp
345
 #pragma mark - fs.cp
334
-RCT_EXPORT_METHOD(cp:(NSString*)src toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
346
+RCT_EXPORT_METHOD(cp:(NSString*)src toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
347
+{
335
     
348
     
336
 //    path = [RNFetchBlobFS getPathOfAsset:path];
349
 //    path = [RNFetchBlobFS getPathOfAsset:path];
337
     [RNFetchBlobFS getPathFromUri:src completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
350
     [RNFetchBlobFS getPathFromUri:src completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
356
 
369
 
357
 
370
 
358
 #pragma mark - fs.mv
371
 #pragma mark - fs.mv
359
-RCT_EXPORT_METHOD(mv:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
372
+RCT_EXPORT_METHOD(mv:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
373
+{
360
     NSError * error = nil;
374
     NSError * error = nil;
361
     BOOL result = [[NSFileManager defaultManager] moveItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
375
     BOOL result = [[NSFileManager defaultManager] moveItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
362
 
376
 
368
 }
382
 }
369
 
383
 
370
 #pragma mark - fs.mkdir
384
 #pragma mark - fs.mkdir
371
-RCT_EXPORT_METHOD(mkdir:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
385
+RCT_EXPORT_METHOD(mkdir:(NSString *)path callback:(RCTResponseSenderBlock) callback)
386
+{
372
     if([[NSFileManager defaultManager] fileExistsAtPath:path]) {
387
     if([[NSFileManager defaultManager] fileExistsAtPath:path]) {
373
         callback(@[@"mkdir failed, folder already exists"]);
388
         callback(@[@"mkdir failed, folder already exists"]);
374
         return;
389
         return;
379
 }
394
 }
380
 
395
 
381
 #pragma mark - fs.readFile
396
 #pragma mark - fs.readFile
382
-RCT_EXPORT_METHOD(readFile:(NSString *)path encoding:(NSString *)encoding resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
397
+RCT_EXPORT_METHOD(readFile:(NSString *)path encoding:(NSString *)encoding resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
398
+{
383
 
399
 
384
     [RNFetchBlobFS readFile:path encoding:encoding resolver:resolve rejecter:reject onComplete:nil];
400
     [RNFetchBlobFS readFile:path encoding:encoding resolver:resolve rejecter:reject onComplete:nil];
385
-})
401
+}
386
 
402
 
387
 #pragma mark - fs.readStream
403
 #pragma mark - fs.readStream
388
-RCT_EXPORT_METHOD(readStream:(NSString *)path withEncoding:(NSString *)encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId
404
+RCT_EXPORT_METHOD(readStream:(NSString *)path withEncoding:(NSString *)encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId)
389
 {
405
 {
390
     if(bufferSize == nil) {
406
     if(bufferSize == nil) {
391
         if([[encoding lowercaseString] isEqualToString:@"base64"])
407
         if([[encoding lowercaseString] isEqualToString:@"base64"])
397
     dispatch_async(fsQueue, ^{
413
     dispatch_async(fsQueue, ^{
398
         [RNFetchBlobFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId bridgeRef:_bridge];
414
         [RNFetchBlobFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId bridgeRef:_bridge];
399
     });
415
     });
400
-})
416
+}
401
 
417
 
402
 #pragma mark - fs.getEnvionmentDirs
418
 #pragma mark - fs.getEnvionmentDirs
403
-RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback) {
419
+RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback)
420
+{
404
 
421
 
405
     callback(@[
422
     callback(@[
406
                [RNFetchBlobFS getDocumentDir],
423
                [RNFetchBlobFS getDocumentDir],
416
 }
433
 }
417
 
434
 
418
 #pragma mark - net.enableProgressReport
435
 #pragma mark - net.enableProgressReport
419
-RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count  {
436
+RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
437
+{
420
     
438
     
421
     RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Download interval:interval count:count];
439
     RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Download interval:interval count:count];
422
     [RNFetchBlobNetwork enableProgressReport:taskId config:cfg];
440
     [RNFetchBlobNetwork enableProgressReport:taskId config:cfg];
423
-})
441
+}
424
 
442
 
425
 #pragma mark - net.enableUploadProgressReport
443
 #pragma mark - net.enableUploadProgressReport
426
-RCT_EXPORT_METHOD(enableUploadProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count{
444
+RCT_EXPORT_METHOD(enableUploadProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
445
+{
427
     RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Upload interval:interval count:count];
446
     RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Upload interval:interval count:count];
428
     [RNFetchBlobNetwork enableUploadProgress:taskId config:cfg];
447
     [RNFetchBlobNetwork enableUploadProgress:taskId config:cfg];
429
-})
448
+}
430
 
449
 
431
 #pragma mark - fs.slice
450
 #pragma mark - fs.slice
432
-RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(nonnull NSNumber *)start end:(nonnull NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject
451
+RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(nonnull NSNumber *)start end:(nonnull NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
433
 {
452
 {
434
     [RNFetchBlobFS slice:src dest:dest start:start end:end encode:@"" resolver:resolve rejecter:reject];
453
     [RNFetchBlobFS slice:src dest:dest start:start end:end encode:@"" resolver:resolve rejecter:reject];
435
-})
454
+}
436
 
455
 
437
-RCT_EXPORT_METHOD(previewDocument:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject
456
+RCT_EXPORT_METHOD(previewDocument:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
438
 {
457
 {
439
     NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
458
     NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
440
     NSURL * url = [[NSURL alloc] initWithString:utf8uri];
459
     NSURL * url = [[NSURL alloc] initWithString:utf8uri];
450
     } else {
469
     } else {
451
         reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
470
         reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
452
     }
471
     }
453
-})
472
+}
454
 
473
 
455
 # pragma mark - open file with UIDocumentInteractionController and delegate
474
 # pragma mark - open file with UIDocumentInteractionController and delegate
456
 
475
 
457
-RCT_EXPORT_METHOD(openDocument:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject
476
+RCT_EXPORT_METHOD(openDocument:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
458
 {
477
 {
459
     NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
478
     NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
460
     NSURL * url = [[NSURL alloc] initWithString:utf8uri];
479
     NSURL * url = [[NSURL alloc] initWithString:utf8uri];
470
     } else {
489
     } else {
471
         reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
490
         reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
472
     }
491
     }
473
-})
492
+}
474
 
493
 
475
 # pragma mark - exclude from backup key
494
 # pragma mark - exclude from backup key
476
 
495
 
477
-RCT_EXPORT_METHOD(excludeFromBackupKey:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject
496
+RCT_EXPORT_METHOD(excludeFromBackupKey:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
478
 {
497
 {
479
     NSError *error = nil;
498
     NSError *error = nil;
480
     [ [NSURL URLWithString:url] setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
499
     [ [NSURL URLWithString:url] setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
485
         reject(@"RNFetchBlob could not open document", [error description], nil);
504
         reject(@"RNFetchBlob could not open document", [error description], nil);
486
     }
505
     }
487
     
506
     
488
-})
507
+}
489
 
508
 
490
 
509
 
491
-RCT_EXPORT_METHOD(df:(RCTResponseSenderBlock)callback
510
+RCT_EXPORT_METHOD(df:(RCTResponseSenderBlock)callback)
492
 {
511
 {
493
     [RNFetchBlobFS df:callback];
512
     [RNFetchBlobFS df:callback];
494
-})
513
+}
495
 
514
 
496
-- (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller {
515
+- (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller
516
+{
497
     UIWindow *window = [UIApplication sharedApplication].keyWindow;
517
     UIWindow *window = [UIApplication sharedApplication].keyWindow;
498
     return window.rootViewController;
518
     return window.rootViewController;
499
 }
519
 }
500
 
520
 
501
 # pragma mark - getCookies
521
 # pragma mark - getCookies
502
-RCT_EXPORT_METHOD(getCookies:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject
522
+RCT_EXPORT_METHOD(getCookies:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
503
 {
523
 {
504
     resolve([RNFetchBlobNetwork getCookies:url]);
524
     resolve([RNFetchBlobNetwork getCookies:url]);
505
-})
525
+}
506
 
526
 
507
 # pragma mark - check expired network events
527
 # pragma mark - check expired network events
508
 
528
 
509
-RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback
529
+RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback)
510
 {
530
 {
511
     [RNFetchBlobNetwork emitExpiredTasks];
531
     [RNFetchBlobNetwork emitExpiredTasks];
512
-})
532
+}
513
 
533
 
514
 
534
 
515
 @end
535
 @end

+ 46
- 25
src/ios/RNFetchBlobFS.m View File

214
 // send read stream chunks via native event emitter
214
 // send read stream chunks via native event emitter
215
 + (void) emitDataChunks:(NSData *)data encoding:(NSString *) encoding streamId:(NSString *)streamId event:(RCTEventDispatcher *)event
215
 + (void) emitDataChunks:(NSData *)data encoding:(NSString *) encoding streamId:(NSString *)streamId event:(RCTEventDispatcher *)event
216
 {
216
 {
217
-    NSString * encodedChunk = @"";
218
-    if([[encoding lowercaseString] isEqualToString:@"utf8"])
219
-    {
220
-        NSDictionary * payload = @{ @"event": FS_EVENT_DATA,  @"detail" : [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] };
221
-        [event sendDeviceEventWithName:streamId body:payload];
222
-    }
223
-    else if ([[encoding lowercaseString] isEqualToString:@"base64"])
224
-    {
225
-        NSDictionary * payload = @{ @"event": FS_EVENT_DATA,  @"detail" : [data base64EncodedStringWithOptions:0] };
226
-        [event sendDeviceEventWithName:streamId body:payload];
227
-    }
228
-    else if([[encoding lowercaseString] isEqualToString:@"ascii"])
217
+    @try
229
     {
218
     {
230
-        // RCTBridge only emits string data, so we have to create JSON byte array string
231
-        NSMutableArray * asciiArray = [NSMutableArray array];
232
-        unsigned char *bytePtr;
233
-        if (data.length > 0)
219
+        NSString * encodedChunk = @"";
220
+        if([[encoding lowercaseString] isEqualToString:@"utf8"])
234
         {
221
         {
235
-            bytePtr = (unsigned char *)[data bytes];
236
-            NSInteger byteLen = data.length/sizeof(uint8_t);
237
-            for (int i = 0; i < byteLen; i++)
222
+            NSDictionary * payload = @{
223
+                                       @"event": FS_EVENT_DATA,
224
+                                       @"detail" : [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]
225
+                                       };
226
+            [event sendDeviceEventWithName:streamId body:payload];
227
+        }
228
+        else if ([[encoding lowercaseString] isEqualToString:@"base64"])
229
+        {
230
+            NSDictionary * payload = @{ @"event": FS_EVENT_DATA,  @"detail" : [data base64EncodedStringWithOptions:0] };
231
+            [event sendDeviceEventWithName:streamId body:payload];
232
+        }
233
+        else if([[encoding lowercaseString] isEqualToString:@"ascii"])
234
+        {
235
+            // RCTBridge only emits string data, so we have to create JSON byte array string
236
+            NSMutableArray * asciiArray = [NSMutableArray array];
237
+            unsigned char *bytePtr;
238
+            if (data.length > 0)
238
             {
239
             {
239
-                [asciiArray addObject:[NSNumber numberWithChar:bytePtr[i]]];
240
+                bytePtr = (unsigned char *)[data bytes];
241
+                NSInteger byteLen = data.length/sizeof(uint8_t);
242
+                for (int i = 0; i < byteLen; i++)
243
+                {
244
+                    [asciiArray addObject:[NSNumber numberWithChar:bytePtr[i]]];
245
+                }
240
             }
246
             }
247
+            
248
+            NSDictionary * payload = @{ @"event": FS_EVENT_DATA,  @"detail" : asciiArray };
249
+            [event sendDeviceEventWithName:streamId body:payload];
241
         }
250
         }
242
-
243
-        NSDictionary * payload = @{ @"event": FS_EVENT_DATA,  @"detail" : asciiArray };
244
-        [event sendDeviceEventWithName:streamId body:payload];
251
+        
252
+    }
253
+    @catch (NSException * ex)
254
+    {
255
+        NSString * message = [NSString stringWithFormat:@"Failed to convert data to '%@' encoded string, this might due to the source data is not able to convert using this encoding. source = %@", encoding, [ex description]];
256
+        [event
257
+         sendDeviceEventWithName:streamId
258
+         body:@{
259
+                @"event" : MSG_EVENT_ERROR,
260
+                @"detail" : message
261
+                }];
262
+        [event
263
+         sendDeviceEventWithName:MSG_EVENT
264
+         body:@{
265
+                @"event" : MSG_EVENT_WARN,
266
+                @"detail" : message
267
+                }];
245
     }
268
     }
246
-
247
-
248
 }
269
 }
249
 
270
 
250
 # pragma write file from file
271
 # pragma write file from file

+ 37
- 12
test/test-0.10.2.js View File

63
 
63
 
64
 })
64
 })
65
 
65
 
66
-describe('#240 openDocument does not support file URI', (report, done) => {
67
-  RNFetchBlob
68
-  .config({ fileCache : true })
69
-  .fetch('GET', `${TEST_SERVER_URL}/public/github.png`)
70
-  .then((res) => {
71
-    RNFetchBlob.ios.openDocument(res.path())
72
-    .then(() => {
73
-      done();
74
-    })
75
-  })
76
-
77
-})
66
+// describe('#240 openDocument does not support file URI', (report, done) => {
67
+//   RNFetchBlob
68
+//   .config({ path : dirs.DocumentDir + '/app copy.png' })
69
+//   .fetch('GET', `${TEST_SERVER_URL}/public/github.png`)
70
+//   .then((res) => {
71
+//     RNFetchBlob.ios.openDocument(res.path())
72
+//     .then(() => {
73
+//       done();
74
+//     })
75
+//     .catch((err) => {
76
+//       console.log(err)
77
+//     })
78
+//   })
79
+//
80
+// })
78
 
81
 
79
 describe('#241 null header silent failed issue', (report, done) => {
82
 describe('#241 null header silent failed issue', (report, done) => {
80
 
83
 
82
     foo : null
85
     foo : null
83
   })
86
   })
84
   .then(() => {
87
   .then(() => {
88
+    report(<Assert key="null header should not crash the app"
89
+      expect={true}
90
+      actual={true}/>)
85
     done()
91
     done()
86
   })
92
   })
87
 })
93
 })
94
+
95
+describe('#247 binary data UTF8 encoding causes app crash', (report, done) => {
96
+
97
+  RNFetchBlob
98
+  .config({fileCache : true})
99
+  .fetch('GET', `${TEST_SERVER_URL}/public/github.png`)
100
+  .then((res) => fs.readStream(res.path(), 'utf8'))
101
+  .then((stream) => {
102
+    stream.open()
103
+    stream.onError((err) => {
104
+      report(<Assert
105
+        key="read binary data to UTF8 should cause error but not crash the app"
106
+        expect={true}
107
+        actual={true}/>)
108
+      done()
109
+    })
110
+  })
111
+
112
+})