Преглед изворни кода

Add Blob.slice implementation #89

This commit includes Android and IOS implementations.
Ben Hsieh пре 8 година
родитељ
комит
d249efc149

+ 2
- 2
src/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java Прегледај датотеку

@@ -223,8 +223,8 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
223 223
     }
224 224
 
225 225
     @ReactMethod
226
-    public void slice(String src, String dest, int start, int end, String encode, Callback callback) {
227
-        RNFetchBlobFS.slice(src, dest, start, end, encode, callback);
226
+    public void slice(String src, String dest, int start, int end, Promise promise) {
227
+        RNFetchBlobFS.slice(src, dest, start, end, "", promise);
228 228
     }
229 229
 
230 230
     @ReactMethod

+ 11
- 3
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java Прегледај датотеку

@@ -537,7 +537,7 @@ public class RNFetchBlobFS {
537 537
      * @param encode
538 538
      * @param callback
539 539
      */
540
-    public static void slice(String src, String dest, int start, int end, String encode, Callback callback) {
540
+    public static void slice(String src, String dest, int start, int end, String encode, Promise promise) {
541 541
         try {
542 542
             long expected = end - start;
543 543
             long now = 0;
@@ -547,17 +547,25 @@ public class RNFetchBlobFS {
547 547
             byte [] buffer = new byte[10240];
548 548
             while(now < expected) {
549 549
                 long read = in.read(buffer, 0, 10240);
550
+                long remain = expected - now;
550 551
                 if(read <= 0) {
551 552
                     break;
552 553
                 }
554
+                if(remain < 10240) {
555
+                    out.write(buffer, 0, (int) remain);
556
+                }
557
+                else
558
+                    out.write(buffer, 0, (int) read);
553 559
                 now += read;
554
-                out.write(buffer, 0, (int) read);
560
+
555 561
             }
556 562
             in.close();
563
+            out.flush();
557 564
             out.close();
558
-            callback.invoke(null, dest);
565
+            promise.resolve(dest);
559 566
         } catch (Exception e) {
560 567
             e.printStackTrace();
568
+            promise.reject(e.getLocalizedMessage());
561 569
         }
562 570
     }
563 571
 

+ 5
- 0
src/fs.js Прегледај датотеку

@@ -299,6 +299,10 @@ function exists(path:string):Promise<bool, bool> {
299 299
 
300 300
 }
301 301
 
302
+function slice(src:string, dest:string, start:number, end:number):Promise {
303
+  return RNFetchBlob.slice(src, dest, start, end)
304
+}
305
+
302 306
 function isDir(path:string):Promise<bool, bool> {
303 307
 
304 308
   return new Promise((resolve, reject) => {
@@ -333,5 +337,6 @@ export default {
333 337
   lstat,
334 338
   scanFile,
335 339
   dirs,
340
+  slice,
336 341
   asset
337 342
 }

+ 4
- 2
src/ios/RNFetchBlob/RNFetchBlob.m Прегледај датотеку

@@ -362,9 +362,11 @@ RCT_EXPORT_METHOD(enableUploadProgressReport:(NSString *)taskId {
362 362
     [RNFetchBlobNetwork enableUploadProgress:taskId];
363 363
 })
364 364
 
365
-RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(NSNumber *)start end:(NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject
365
+RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(nonnull NSNumber *)start end:(nonnull NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject
366 366
 {
367
-    [RNFetchBlobFS slice:src dest:dest start:start end:end encode:@"" resolver:resolve rejecter:reject];
367
+     dispatch_sync(dispatch_get_main_queue(),^(void){
368
+         [RNFetchBlobFS slice:src dest:dest start:start end:end encode:@"" resolver:resolve rejecter:reject];
369
+     });
368 370
 })
369 371
 
370 372
 #pragma mark RNFetchBlob private methods

+ 7
- 1
src/ios/RNFetchBlobFS.h Прегледај датотеку

@@ -55,7 +55,13 @@
55 55
 + (void) writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
56 56
 + (void) readFile:(NSString *)path encoding:(NSString *)encoding resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject onComplete:(void (^)(NSData * content))onComplete;
57 57
 + (void) readAssetFile:(NSData *)assetUrl completionBlock:(void(^)(NSData * content))completionBlock failBlock:(void(^)(NSError * err))failBlock;
58
-+ (void) slice:(NSString *)path dest:(NSString *)dest start:(NSNumber *)start end:(NSNumber *)end encode:(NSString *)encode resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
58
++ (void)slice:(NSString *)path
59
+         dest:(NSString *)dest
60
+        start:(nonnull NSNumber *)start
61
+          end:(nonnull NSNumber *)end
62
+        encode:(NSString *)encode
63
+     resolver:(RCTPromiseResolveBlock)resolve
64
+     rejecter:(RCTPromiseRejectBlock)reject;
59 65
 //+ (void) writeFileFromFile:(NSString *)src toFile:(NSString *)dest append:(BOOL)append;
60 66
 
61 67
 // constructor

+ 17
- 8
src/ios/RNFetchBlobFS.m Прегледај датотеку

@@ -525,11 +525,11 @@ NSMutableDictionary *fileStreams = nil;
525 525
 }
526 526
 
527 527
 // Slice a file into another file, generally for support Blob implementation.
528
-- (void)slice:(NSString *)path
528
++ (void)slice:(NSString *)path
529 529
          dest:(NSString *)dest
530
-        start:(NSNumber *)start
531
-          end:(NSNumber *)end
532
-        encod:(NSString *)encode
530
+        start:(nonnull NSNumber *)start
531
+          end:(nonnull NSNumber *)end
532
+        encode:(NSString *)encode
533 533
      resolver:(RCTPromiseResolveBlock)resolve
534 534
      rejecter:(RCTPromiseRejectBlock)reject
535 535
 {
@@ -547,20 +547,29 @@ NSMutableDictionary *fileStreams = nil;
547 547
     }
548 548
     long size = [fm attributesOfItemAtPath:path error:nil].fileSize;
549 549
     // abort for the file size is less than start
550
-    if(size < start)
550
+    if(size < [start longValue])
551 551
     {
552
-        reject(@"RNFetchBlob slice failed", @"start is greater than file size", @"");
552
+        reject(@"RNFetchBlob slice failed", @"start is greater than file size", @"start is greater than file size");
553 553
         return;
554 554
     }
555 555
     if(![fm fileExistsAtPath:dest]) {
556 556
         [fm createFileAtPath:dest contents:@"" attributes:nil];
557 557
     }
558
-    [handle seekToFileOffset:start];
558
+    [handle seekToFileOffset:[start longValue]];
559 559
     while(read < expected)
560 560
     {
561
+
561 562
         NSData * chunk = [handle readDataOfLength:10240];
563
+        long remain = expected - read;
564
+        if(remain < 10240)
565
+        {
566
+            [os write:[chunk bytes] maxLength:remain];
567
+        }
568
+        else
569
+        {
570
+            [os write:[chunk bytes] maxLength:10240];
571
+        }
562 572
         read += [chunk length];
563
-        [os write:[chunk bytes] maxLength:10240];
564 573
     }
565 574
     [handle closeFile];
566 575
     [os close];

+ 24
- 7
src/polyfill/Blob.js Прегледај датотеку

@@ -11,8 +11,8 @@ import EventTarget from './EventTarget'
11 11
 const log = new Log('Blob')
12 12
 const blobCacheDir = fs.dirs.DocumentDir + '/RNFetchBlob-blobs/'
13 13
 
14
-log.disable()
15
-// log.level(3)
14
+// log.disable()
15
+log.level(3)
16 16
 
17 17
 /**
18 18
  * A RNFetchBlob style Blob polyfill class, this is a Blob which compatible to
@@ -181,6 +181,14 @@ export default class Blob extends EventTarget {
181 181
     return this
182 182
   }
183 183
 
184
+  markAsDerived() {
185
+    this._isDerived = true
186
+  }
187
+
188
+  get isDerived() {
189
+    return this._isDerived || false
190
+  }
191
+
184 192
   /**
185 193
    * Get file reference of the Blob object.
186 194
    * @nonstandard
@@ -197,13 +205,22 @@ export default class Blob extends EventTarget {
197 205
    * @param  {string} contentType Optional, content type of new Blob object
198 206
    * @return {Blob}
199 207
    */
200
-  slice(start:?number, end:?number, encoding:?string):Blob {
208
+  slice(start:?number, end:?number, contentType:?string):Blob {
201 209
     if(this._closed)
202 210
       throw 'Blob has been released.'
203
-    log.verbose('slice called', start, end, encoding)
204
-    console.warn('RNFB#Blob.slice() is not implemented yet, to read Blob content, use Blob.readBlob(encoding:string) instead.')
205
-    // TODO : fs.slice
206
-    // return fs.slice(this.cacheName, getBlobName(), contentType, start, end)
211
+    log.verbose('slice called', start, end, contentType)
212
+    let resPath = blobCacheDir + getBlobName()
213
+    let pass = false
214
+    log.debug('fs.slice new blob will at', resPath)
215
+    fs.slice(this._ref, resPath, start, end).then((dest) => {
216
+      log.debug('fs.slice done', dest)
217
+      pass = true
218
+    })
219
+    .catch((err) => {
220
+      pass = true
221
+    })
222
+    log.debug('slice returning new Blob')
223
+    return new Blob(RNFetchBlob.wrap(resPath))
207 224
   }
208 225
 
209 226
   /**