Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit dc17e30

Browse files
committed
Add test case and exception handling for #247
fastfix
1 parent 12a7368 commit dc17e30

File tree

4 files changed

+151
-79
lines changed

4 files changed

+151
-79
lines changed

src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
import java.io.IOException;
2929
import java.io.InputStream;
3030
import java.io.OutputStream;
31+
import java.nio.ByteBuffer;
3132
import java.nio.charset.Charset;
33+
import java.nio.charset.CharsetEncoder;
3234
import java.util.HashMap;
3335
import java.util.Map;
3436
import java.util.UUID;
@@ -243,8 +245,12 @@ public void readStream(String path, String encoding, int bufferSize, int tick, f
243245
boolean error = false;
244246

245247
if (encoding.equalsIgnoreCase("utf8")) {
248+
CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
246249
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);
248254
emitStreamEvent(streamId, "data", chunk);
249255
if(tick > 0)
250256
SystemClock.sleep(tick);
@@ -286,7 +292,7 @@ public void readStream(String path, String encoding, int bufferSize, int tick, f
286292
buffer = null;
287293

288294
} 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.");
290296
}
291297
}
292298

src/ios/RNFetchBlob/RNFetchBlob.m

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ - (NSDictionary *)constantsToExport
131131
callback(@[[NSString stringWithFormat:@"failed to create new file at path %@ please ensure the folder exists"]]);
132132

133133
}
134+
134135
#pragma mark - fs.createFileASCII
135136
// method for create file with ASCII content
136137
RCT_EXPORT_METHOD(createFileASCII:(NSString *)path data:(NSArray *)dataArray callback:(RCTResponseSenderBlock)callback) {
@@ -159,17 +160,20 @@ - (NSDictionary *)constantsToExport
159160
}
160161

161162
#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+
{
163165
[RNFetchBlobFS writeFile:path encoding:[NSString stringWithString:encoding] data:data append:append resolver:resolve rejecter:reject];
164-
})
166+
}
165167

166168
#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+
{
168171
[RNFetchBlobFS writeFileArray:path data:data append:append resolver:resolve rejecter:reject];
169-
})
172+
}
170173

171174
#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+
{
173177
RNFetchBlobFS * fileStream = [[RNFetchBlobFS alloc] initWithBridgeRef:self.bridge];
174178
NSFileManager * fm = [NSFileManager defaultManager];
175179
BOOL isDir = nil;
@@ -183,7 +187,8 @@ - (NSDictionary *)constantsToExport
183187
}
184188

185189
#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+
{
187192
RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
188193
char * bytes = (char *) malloc([dataArray count]);
189194
for(int i = 0; i < dataArray.count; i++) {
@@ -197,21 +202,24 @@ - (NSDictionary *)constantsToExport
197202
}
198203

199204
#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+
{
201207
RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
202208
[fs writeEncodeChunk:data];
203209
callback(@[[NSNull null]]);
204210
}
205211

206212
#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+
{
208215
RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
209216
[fs closeOutStream];
210217
callback(@[[NSNull null], @YES]);
211218
}
212219

213220
#pragma mark - unlink
214-
RCT_EXPORT_METHOD(unlink:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
221+
RCT_EXPORT_METHOD(unlink:(NSString *)path callback:(RCTResponseSenderBlock) callback)
222+
{
215223
NSError * error = nil;
216224
NSString * tmpPath = nil;
217225
[[NSFileManager defaultManager] removeItemAtPath:path error:&error];
@@ -222,7 +230,8 @@ - (NSDictionary *)constantsToExport
222230
}
223231

224232
#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+
{
226235
NSError * error = nil;
227236
NSString * tmpPath = nil;
228237

@@ -238,7 +247,8 @@ - (NSDictionary *)constantsToExport
238247
}
239248

240249
#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+
{
242252
NSFileManager* fm = [NSFileManager defaultManager];
243253
BOOL exist = nil;
244254
BOOL isDir = nil;
@@ -258,7 +268,8 @@ - (NSDictionary *)constantsToExport
258268
}
259269

260270
#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+
{
262273

263274
[RNFetchBlobFS getPathFromUri:target completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
264275
__block NSMutableArray * result;
@@ -297,7 +308,8 @@ - (NSDictionary *)constantsToExport
297308
}
298309

299310
#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+
{
301313
NSFileManager* fm = [NSFileManager defaultManager];
302314
BOOL exist = nil;
303315
BOOL isDir = nil;
@@ -331,7 +343,8 @@ - (NSDictionary *)constantsToExport
331343
}
332344

333345
#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+
{
335348

336349
// path = [RNFetchBlobFS getPathOfAsset:path];
337350
[RNFetchBlobFS getPathFromUri:src completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
@@ -356,7 +369,8 @@ - (NSDictionary *)constantsToExport
356369

357370

358371
#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+
{
360374
NSError * error = nil;
361375
BOOL result = [[NSFileManager defaultManager] moveItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
362376

@@ -368,7 +382,8 @@ - (NSDictionary *)constantsToExport
368382
}
369383

370384
#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+
{
372387
if([[NSFileManager defaultManager] fileExistsAtPath:path]) {
373388
callback(@[@"mkdir failed, folder already exists"]);
374389
return;
@@ -379,13 +394,14 @@ - (NSDictionary *)constantsToExport
379394
}
380395

381396
#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+
{
383399

384400
[RNFetchBlobFS readFile:path encoding:encoding resolver:resolve rejecter:reject onComplete:nil];
385-
})
401+
}
386402

387403
#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)
389405
{
390406
if(bufferSize == nil) {
391407
if([[encoding lowercaseString] isEqualToString:@"base64"])
@@ -397,10 +413,11 @@ - (NSDictionary *)constantsToExport
397413
dispatch_async(fsQueue, ^{
398414
[RNFetchBlobFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId bridgeRef:_bridge];
399415
});
400-
})
416+
}
401417

402418
#pragma mark - fs.getEnvionmentDirs
403-
RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback) {
419+
RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback)
420+
{
404421

405422
callback(@[
406423
[RNFetchBlobFS getDocumentDir],
@@ -416,25 +433,27 @@ - (NSDictionary *)constantsToExport
416433
}
417434

418435
#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+
{
420438

421439
RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Download interval:interval count:count];
422440
[RNFetchBlobNetwork enableProgressReport:taskId config:cfg];
423-
})
441+
}
424442

425443
#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+
{
427446
RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Upload interval:interval count:count];
428447
[RNFetchBlobNetwork enableUploadProgress:taskId config:cfg];
429-
})
448+
}
430449

431450
#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)
433452
{
434453
[RNFetchBlobFS slice:src dest:dest start:start end:end encode:@"" resolver:resolve rejecter:reject];
435-
})
454+
}
436455

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)
438457
{
439458
NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
440459
NSURL * url = [[NSURL alloc] initWithString:utf8uri];
@@ -450,11 +469,11 @@ - (NSDictionary *)constantsToExport
450469
} else {
451470
reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
452471
}
453-
})
472+
}
454473

455474
# pragma mark - open file with UIDocumentInteractionController and delegate
456475

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)
458477
{
459478
NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
460479
NSURL * url = [[NSURL alloc] initWithString:utf8uri];
@@ -470,11 +489,11 @@ - (NSDictionary *)constantsToExport
470489
} else {
471490
reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
472491
}
473-
})
492+
}
474493

475494
# pragma mark - exclude from backup key
476495

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)
478497
{
479498
NSError *error = nil;
480499
[ [NSURL URLWithString:url] setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
@@ -485,31 +504,32 @@ - (NSDictionary *)constantsToExport
485504
reject(@"RNFetchBlob could not open document", [error description], nil);
486505
}
487506

488-
})
507+
}
489508

490509

491-
RCT_EXPORT_METHOD(df:(RCTResponseSenderBlock)callback
510+
RCT_EXPORT_METHOD(df:(RCTResponseSenderBlock)callback)
492511
{
493512
[RNFetchBlobFS df:callback];
494-
})
513+
}
495514

496-
- (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller {
515+
- (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller
516+
{
497517
UIWindow *window = [UIApplication sharedApplication].keyWindow;
498518
return window.rootViewController;
499519
}
500520

501521
# 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)
503523
{
504524
resolve([RNFetchBlobNetwork getCookies:url]);
505-
})
525+
}
506526

507527
# pragma mark - check expired network events
508528

509-
RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback
529+
RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback)
510530
{
511531
[RNFetchBlobNetwork emitExpiredTasks];
512-
})
532+
}
513533

514534

515535
@end

src/ios/RNFetchBlobFS.m

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -214,37 +214,58 @@ + (void) readStream:(NSString *)uri
214214
// send read stream chunks via native event emitter
215215
+ (void) emitDataChunks:(NSData *)data encoding:(NSString *) encoding streamId:(NSString *)streamId event:(RCTEventDispatcher *)event
216216
{
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
229218
{
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"])
234221
{
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)
238239
{
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+
}
240246
}
247+
248+
NSDictionary * payload = @{ @"event": FS_EVENT_DATA, @"detail" : asciiArray };
249+
[event sendDeviceEventWithName:streamId body:payload];
241250
}
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+
}];
245268
}
246-
247-
248269
}
249270

250271
# pragma write file from file

0 commit comments

Comments
 (0)