react-native-blob-util 0.13.18 → 0.14.0

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.
Files changed (24) hide show
  1. package/README.md +471 -406
  2. package/android/build.gradle +1 -0
  3. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +86 -21
  4. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilBody.java +14 -15
  5. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +8 -6
  6. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +21 -286
  7. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilMediaCollection.java +278 -0
  8. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilPackage.java +6 -2
  9. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +17 -21
  10. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilStream.java +287 -0
  11. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilUtils.java +57 -2
  12. package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilFileResp.java +5 -0
  13. package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileDescription.java +19 -0
  14. package/android/src/main/java/com/ReactNativeBlobUtil/Utils/MimeType.java +70 -0
  15. package/fs.js +2 -1
  16. package/index.d.ts +92 -1
  17. package/index.js +2 -0
  18. package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.m +2 -1
  19. package/ios/ReactNativeBlobUtilFS.h +1 -0
  20. package/ios/ReactNativeBlobUtilFS.m +4 -0
  21. package/mediacollection.js +33 -0
  22. package/package.json +1 -1
  23. package/scripts/prelink.js +1 -1
  24. package/types.js +3 -0
@@ -7,10 +7,8 @@ import android.os.AsyncTask;
7
7
  import android.os.Build;
8
8
  import android.os.Environment;
9
9
  import android.os.StatFs;
10
- import android.os.SystemClock;
11
10
  import android.util.Base64;
12
11
 
13
- import com.ReactNativeBlobUtil.Utils.PathResolver;
14
12
  import com.facebook.react.bridge.Arguments;
15
13
  import com.facebook.react.bridge.Callback;
16
14
  import com.facebook.react.bridge.Promise;
@@ -20,13 +18,18 @@ import com.facebook.react.bridge.WritableArray;
20
18
  import com.facebook.react.bridge.WritableMap;
21
19
  import com.facebook.react.modules.core.DeviceEventManagerModule;
22
20
 
23
- import java.io.*;
24
- import java.nio.charset.Charset;
21
+ import java.io.File;
22
+ import java.io.FileInputStream;
23
+ import java.io.FileNotFoundException;
24
+ import java.io.FileOutputStream;
25
+ import java.io.IOException;
26
+ import java.io.InputStream;
27
+ import java.io.OutputStream;
25
28
  import java.security.MessageDigest;
26
29
  import java.util.ArrayList;
27
30
  import java.util.HashMap;
31
+ import java.util.Locale;
28
32
  import java.util.Map;
29
- import java.util.UUID;
30
33
 
31
34
  class ReactNativeBlobUtilFS {
32
35
 
@@ -70,7 +73,7 @@ class ReactNativeBlobUtilFS {
70
73
 
71
74
  // write data from a file
72
75
  if (encoding.equalsIgnoreCase(ReactNativeBlobUtilConst.DATA_ENCODE_URI)) {
73
- String normalizedData = normalizePath(data);
76
+ String normalizedData = ReactNativeBlobUtilUtils.normalizePath(data);
74
77
  File src = new File(normalizedData);
75
78
  if (!src.exists()) {
76
79
  promise.reject("ENOENT", "No such file '" + path + "' " + "('" + normalizedData + "')");
@@ -97,7 +100,7 @@ class ReactNativeBlobUtilFS {
97
100
  }
98
101
  }
99
102
  } else {
100
- byte[] bytes = stringToBytes(data, encoding);
103
+ byte[] bytes = ReactNativeBlobUtilUtils.stringToBytes(data, encoding);
101
104
  FileOutputStream fout = new FileOutputStream(f, append);
102
105
  try {
103
106
  fout.write(bytes);
@@ -167,7 +170,7 @@ class ReactNativeBlobUtilFS {
167
170
  * @param promise JS promise
168
171
  */
169
172
  static void readFile(String path, String encoding, final Promise promise) {
170
- String resolved = normalizePath(path);
173
+ String resolved = ReactNativeBlobUtilUtils.normalizePath(path);
171
174
  if (resolved != null)
172
175
  path = resolved;
173
176
  try {
@@ -209,7 +212,7 @@ class ReactNativeBlobUtilFS {
209
212
  return;
210
213
  }
211
214
 
212
- switch (encoding.toLowerCase()) {
215
+ switch (encoding.toLowerCase(Locale.ROOT)) {
213
216
  case "base64":
214
217
  promise.resolve(Base64.encodeToString(bytes, Base64.NO_WRAP));
215
218
  break;
@@ -329,205 +332,6 @@ class ReactNativeBlobUtilFS {
329
332
  return ReactNativeBlobUtil.RCTContext.getFilesDir() + "/ReactNativeBlobUtilTmp_" + taskId;
330
333
  }
331
334
 
332
- /**
333
- * Create a file stream for read
334
- *
335
- * @param path File stream target path
336
- * @param encoding File stream decoder, should be one of `base64`, `utf8`, `ascii`
337
- * @param bufferSize Buffer size of read stream, default to 4096 (4095 when encode is `base64`)
338
- */
339
- void readStream(String path, String encoding, int bufferSize, int tick, final String streamId) {
340
- String resolved = normalizePath(path);
341
- if (resolved != null)
342
- path = resolved;
343
-
344
- try {
345
- int chunkSize = encoding.equalsIgnoreCase("base64") ? 4095 : 4096;
346
- if (bufferSize > 0)
347
- chunkSize = bufferSize;
348
-
349
- InputStream fs;
350
-
351
- if (resolved != null && path.startsWith(ReactNativeBlobUtilConst.FILE_PREFIX_BUNDLE_ASSET)) {
352
- fs = ReactNativeBlobUtil.RCTContext.getAssets().open(path.replace(ReactNativeBlobUtilConst.FILE_PREFIX_BUNDLE_ASSET, ""));
353
- }
354
- // fix issue 287
355
- else if (resolved == null) {
356
- fs = ReactNativeBlobUtil.RCTContext.getContentResolver().openInputStream(Uri.parse(path));
357
- } else {
358
- fs = new FileInputStream(new File(path));
359
- }
360
-
361
- int cursor = 0;
362
- boolean error = false;
363
-
364
- if (encoding.equalsIgnoreCase("utf8")) {
365
- InputStreamReader isr = new InputStreamReader(fs, Charset.forName("UTF-8"));
366
- BufferedReader reader = new BufferedReader(isr, chunkSize);
367
- char[] buffer = new char[chunkSize];
368
- // read chunks of the string
369
- while (reader.read(buffer, 0, chunkSize) != -1) {
370
- String chunk = new String(buffer);
371
- emitStreamEvent(streamId, "data", chunk);
372
- if (tick > 0)
373
- SystemClock.sleep(tick);
374
- }
375
-
376
- reader.close();
377
- isr.close();
378
- } else if (encoding.equalsIgnoreCase("ascii")) {
379
- byte[] buffer = new byte[chunkSize];
380
- while ((cursor = fs.read(buffer)) != -1) {
381
- WritableArray chunk = Arguments.createArray();
382
- for (int i = 0; i < cursor; i++) {
383
- chunk.pushInt((int) buffer[i]);
384
- }
385
- emitStreamEvent(streamId, "data", chunk);
386
- if (tick > 0)
387
- SystemClock.sleep(tick);
388
- }
389
- } else if (encoding.equalsIgnoreCase("base64")) {
390
- byte[] buffer = new byte[chunkSize];
391
- while ((cursor = fs.read(buffer)) != -1) {
392
- if (cursor < chunkSize) {
393
- byte[] copy = new byte[cursor];
394
- System.arraycopy(buffer, 0, copy, 0, cursor);
395
- emitStreamEvent(streamId, "data", Base64.encodeToString(copy, Base64.NO_WRAP));
396
- } else
397
- emitStreamEvent(streamId, "data", Base64.encodeToString(buffer, Base64.NO_WRAP));
398
- if (tick > 0)
399
- SystemClock.sleep(tick);
400
- }
401
- } else {
402
- emitStreamEvent(
403
- streamId,
404
- "error",
405
- "EINVAL",
406
- "Unrecognized encoding `" + encoding + "`, should be one of `base64`, `utf8`, `ascii`"
407
- );
408
- error = true;
409
- }
410
-
411
- if (!error)
412
- emitStreamEvent(streamId, "end", "");
413
- fs.close();
414
-
415
- } catch (FileNotFoundException err) {
416
- emitStreamEvent(
417
- streamId,
418
- "error",
419
- "ENOENT",
420
- "No such file '" + path + "'"
421
- );
422
- } catch (Exception err) {
423
- emitStreamEvent(
424
- streamId,
425
- "error",
426
- "EUNSPECIFIED",
427
- "Failed to convert data to " + encoding + " encoded string. This might be because this encoding cannot be used for this data."
428
- );
429
- err.printStackTrace();
430
- }
431
- }
432
-
433
- /**
434
- * Create a write stream and store its instance in ReactNativeBlobUtilFS.fileStreams
435
- *
436
- * @param path Target file path
437
- * @param encoding Should be one of `base64`, `utf8`, `ascii`
438
- * @param append Flag represents if the file stream overwrite existing content
439
- * @param callback Callback
440
- */
441
- void writeStream(String path, String encoding, boolean append, Callback callback) {
442
- try {
443
- File dest = new File(path);
444
- File dir = dest.getParentFile();
445
-
446
- if (!dest.exists()) {
447
- if (dir != null && !dir.exists()) {
448
- if (!dir.mkdirs() && !dir.exists()) {
449
- callback.invoke("ENOTDIR", "Failed to create parent directory of '" + path + "'");
450
- return;
451
- }
452
- }
453
- if (!dest.createNewFile()) {
454
- callback.invoke("ENOENT", "File '" + path + "' does not exist and could not be created");
455
- return;
456
- }
457
- } else if (dest.isDirectory()) {
458
- callback.invoke("EISDIR", "Expecting a file but '" + path + "' is a directory");
459
- return;
460
- }
461
-
462
- OutputStream fs = new FileOutputStream(path, append);
463
- this.encoding = encoding;
464
- String streamId = UUID.randomUUID().toString();
465
- ReactNativeBlobUtilFS.fileStreams.put(streamId, this);
466
- this.writeStreamInstance = fs;
467
- callback.invoke(null, null, streamId);
468
- } catch (Exception err) {
469
- callback.invoke("EUNSPECIFIED", "Failed to create write stream at path `" + path + "`; " + err.getLocalizedMessage());
470
- }
471
- }
472
-
473
- /**
474
- * Write a chunk of data into a file stream.
475
- *
476
- * @param streamId File stream ID
477
- * @param data Data chunk in string format
478
- * @param callback JS context callback
479
- */
480
- static void writeChunk(String streamId, String data, Callback callback) {
481
- ReactNativeBlobUtilFS fs = fileStreams.get(streamId);
482
- OutputStream stream = fs.writeStreamInstance;
483
- byte[] chunk = ReactNativeBlobUtilFS.stringToBytes(data, fs.encoding);
484
- try {
485
- stream.write(chunk);
486
- callback.invoke();
487
- } catch (Exception e) {
488
- callback.invoke(e.getLocalizedMessage());
489
- }
490
- }
491
-
492
- /**
493
- * Write data using ascii array
494
- *
495
- * @param streamId File stream ID
496
- * @param data Data chunk in ascii array format
497
- * @param callback JS context callback
498
- */
499
- static void writeArrayChunk(String streamId, ReadableArray data, Callback callback) {
500
- try {
501
- ReactNativeBlobUtilFS fs = fileStreams.get(streamId);
502
- OutputStream stream = fs.writeStreamInstance;
503
- byte[] chunk = new byte[data.size()];
504
- for (int i = 0; i < data.size(); i++) {
505
- chunk[i] = (byte) data.getInt(i);
506
- }
507
- stream.write(chunk);
508
- callback.invoke();
509
- } catch (Exception e) {
510
- callback.invoke(e.getLocalizedMessage());
511
- }
512
- }
513
-
514
- /**
515
- * Close file write stream by ID
516
- *
517
- * @param streamId Stream ID
518
- * @param callback JS context callback
519
- */
520
- static void closeStream(String streamId, Callback callback) {
521
- try {
522
- ReactNativeBlobUtilFS fs = fileStreams.get(streamId);
523
- OutputStream stream = fs.writeStreamInstance;
524
- fileStreams.remove(streamId);
525
- stream.close();
526
- callback.invoke();
527
- } catch (Exception err) {
528
- callback.invoke(err.getLocalizedMessage());
529
- }
530
- }
531
335
 
532
336
  /**
533
337
  * Unlink file at path
@@ -537,7 +341,7 @@ class ReactNativeBlobUtilFS {
537
341
  */
538
342
  static void unlink(String path, Callback callback) {
539
343
  try {
540
- String normalizedPath = normalizePath(path);
344
+ String normalizedPath = ReactNativeBlobUtilUtils.normalizePath(path);
541
345
  ReactNativeBlobUtilFS.deleteRecursive(new File(normalizedPath));
542
346
  callback.invoke(null, true);
543
347
  } catch (Exception err) {
@@ -595,7 +399,7 @@ class ReactNativeBlobUtilFS {
595
399
  * @param callback JS context callback
596
400
  */
597
401
  static void cp(String path, String dest, Callback callback) {
598
- path = normalizePath(path);
402
+ path = ReactNativeBlobUtilUtils.normalizePath(path);
599
403
  InputStream in = null;
600
404
  OutputStream out = null;
601
405
  String message = "";
@@ -700,7 +504,7 @@ class ReactNativeBlobUtilFS {
700
504
  callback.invoke(false, false);
701
505
  }
702
506
  } else {
703
- path = normalizePath(path);
507
+ path = ReactNativeBlobUtilUtils.normalizePath(path);
704
508
  if (path != null) {
705
509
  boolean exist = new File(path).exists();
706
510
  boolean isDir = new File(path).isDirectory();
@@ -719,7 +523,7 @@ class ReactNativeBlobUtilFS {
719
523
  */
720
524
  static void ls(String path, Promise promise) {
721
525
  try {
722
- path = normalizePath(path);
526
+ path = ReactNativeBlobUtilUtils.normalizePath(path);
723
527
  File src = new File(path);
724
528
  if (!src.exists()) {
725
529
  promise.reject("ENOENT", "No such file '" + path + "'");
@@ -754,7 +558,7 @@ class ReactNativeBlobUtilFS {
754
558
  */
755
559
  static void slice(String path, String dest, int start, int end, String encode, Promise promise) {
756
560
  try {
757
- path = normalizePath(path);
561
+ path = ReactNativeBlobUtilUtils.normalizePath(path);
758
562
  File source = new File(path);
759
563
  if (source.isDirectory()) {
760
564
  promise.reject("EISDIR", "Expecting a file but '" + path + "' is a directory");
@@ -796,7 +600,7 @@ class ReactNativeBlobUtilFS {
796
600
  }
797
601
 
798
602
  static void lstat(String path, final Callback callback) {
799
- path = normalizePath(path);
603
+ path = ReactNativeBlobUtilUtils.normalizePath(path);
800
604
 
801
605
  new AsyncTask<String, Integer, Integer>() {
802
606
  @Override
@@ -835,7 +639,7 @@ class ReactNativeBlobUtilFS {
835
639
  */
836
640
  static void stat(String path, Callback callback) {
837
641
  try {
838
- path = normalizePath(path);
642
+ path = ReactNativeBlobUtilUtils.normalizePath(path);
839
643
  WritableMap result = statFile(path);
840
644
  if (result == null)
841
645
  callback.invoke("failed to stat path `" + path + "` because it does not exist or it is not a folder", null);
@@ -854,7 +658,7 @@ class ReactNativeBlobUtilFS {
854
658
  */
855
659
  static WritableMap statFile(String path) {
856
660
  try {
857
- path = normalizePath(path);
661
+ path = ReactNativeBlobUtilUtils.normalizePath(path);
858
662
  WritableMap stat = Arguments.createMap();
859
663
  if (isAsset(path)) {
860
664
  String name = path.replace(ReactNativeBlobUtilConst.FILE_PREFIX_BUNDLE_ASSET, "");
@@ -990,7 +794,7 @@ class ReactNativeBlobUtilFS {
990
794
  return;
991
795
  }
992
796
  OutputStream ostream = new FileOutputStream(dest);
993
- ostream.write(ReactNativeBlobUtilFS.stringToBytes(data, encoding));
797
+ ostream.write(ReactNativeBlobUtilUtils.stringToBytes(data, encoding));
994
798
  }
995
799
  promise.resolve(path);
996
800
  } catch (Exception err) {
@@ -1085,56 +889,6 @@ class ReactNativeBlobUtilFS {
1085
889
  task.execute(paths);
1086
890
  }
1087
891
 
1088
- /**
1089
- * String to byte converter method
1090
- *
1091
- * @param data Raw data in string format
1092
- * @param encoding Decoder name
1093
- * @return Converted data byte array
1094
- */
1095
- private static byte[] stringToBytes(String data, String encoding) {
1096
- if (encoding.equalsIgnoreCase("ascii")) {
1097
- return data.getBytes(Charset.forName("US-ASCII"));
1098
- } else if (encoding.toLowerCase().contains("base64")) {
1099
- return Base64.decode(data, Base64.NO_WRAP);
1100
-
1101
- } else if (encoding.equalsIgnoreCase("utf8")) {
1102
- return data.getBytes(Charset.forName("UTF-8"));
1103
- }
1104
- return data.getBytes(Charset.forName("US-ASCII"));
1105
- }
1106
-
1107
- /**
1108
- * Private method for emit read stream event.
1109
- *
1110
- * @param streamName ID of the read stream
1111
- * @param event Event name, `data`, `end`, `error`, etc.
1112
- * @param data Event data
1113
- */
1114
- private void emitStreamEvent(String streamName, String event, String data) {
1115
- WritableMap eventData = Arguments.createMap();
1116
- eventData.putString("event", event);
1117
- eventData.putString("detail", data);
1118
- this.emitter.emit(streamName, eventData);
1119
- }
1120
-
1121
- // "event" always is "data"...
1122
- private void emitStreamEvent(String streamName, String event, WritableArray data) {
1123
- WritableMap eventData = Arguments.createMap();
1124
- eventData.putString("event", event);
1125
- eventData.putArray("detail", data);
1126
- this.emitter.emit(streamName, eventData);
1127
- }
1128
-
1129
- // "event" always is "error"...
1130
- private void emitStreamEvent(String streamName, String event, String code, String message) {
1131
- WritableMap eventData = Arguments.createMap();
1132
- eventData.putString("event", event);
1133
- eventData.putString("code", code);
1134
- eventData.putString("detail", message);
1135
- this.emitter.emit(streamName, eventData);
1136
- }
1137
-
1138
892
  /**
1139
893
  * Get input stream of the given path, when the path is a string starts with bundle-assets://
1140
894
  * the stream is created by Assets Manager, otherwise use FileInputStream.
@@ -1174,23 +928,4 @@ class ReactNativeBlobUtilFS {
1174
928
  return path != null && path.startsWith(ReactNativeBlobUtilConst.FILE_PREFIX_BUNDLE_ASSET);
1175
929
  }
1176
930
 
1177
- /**
1178
- * Normalize the path, remove URI scheme (xxx://) so that we can handle it.
1179
- *
1180
- * @param path URI string.
1181
- * @return Normalized string
1182
- */
1183
- static String normalizePath(String path) {
1184
- if (path == null)
1185
- return null;
1186
- if (!path.matches("\\w+\\:.*"))
1187
- return path;
1188
-
1189
- Uri uri = Uri.parse(path);
1190
- if (path.startsWith(ReactNativeBlobUtilConst.FILE_PREFIX_BUNDLE_ASSET)) {
1191
- return path;
1192
- } else
1193
- return PathResolver.getRealPathFromURI(ReactNativeBlobUtil.RCTContext, uri);
1194
- }
1195
-
1196
931
  }