react-native-fs-turbo 0.2.0 → 0.3.1
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 +143 -21
- package/android/src/main/cpp/RNFSTurboPlatformHelper.cpp +85 -67
- package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboPlatformHelper.java +16 -7
- package/cpp/NativeRNFSTurboModule.cpp +2 -1
- package/cpp/RNFSTurboHostObject.cpp +222 -64
- package/cpp/RNFSTurboHostObject.h +1 -0
- package/cpp/RNFSTurboPlatformHelper.h +2 -2
- package/ios/RNFSTurboPlatformHelper.mm +19 -0
- package/lib/commonjs/RNFSTurbo.js +20 -20
- package/lib/commonjs/RNFSTurbo.js.map +1 -1
- package/lib/module/RNFSTurbo.js +20 -20
- package/lib/module/RNFSTurbo.js.map +1 -1
- package/lib/typescript/RNFSTurbo.d.ts +11 -11
- package/lib/typescript/RNFSTurbo.d.ts.map +1 -1
- package/lib/typescript/Types.d.ts +28 -15
- package/lib/typescript/Types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/RNFSTurbo.ts +37 -23
- package/src/Types.ts +50 -23
package/README.md
CHANGED
|
@@ -278,61 +278,175 @@ type ReadDirItem = {
|
|
|
278
278
|
|
|
279
279
|
Node.js style version of `readDir` that returns only the names. Note the lowercase `d`.
|
|
280
280
|
|
|
281
|
-
### `readFile(filepath: string,
|
|
281
|
+
### `readFile(filepath: string, options?: ReadOptions): string | number[]`
|
|
282
282
|
|
|
283
|
-
Reads the file at `path` and return contents. `
|
|
283
|
+
Reads the file at `path` and return contents. `options` can be string of encrypted types or object, default is `utf8`. Use `base64` or `uint8` or `float32` encoding for reading binary files.
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
type ReadOptions =
|
|
287
|
+
| 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32'
|
|
288
|
+
| { encoding: 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32' };
|
|
289
|
+
```
|
|
284
290
|
|
|
285
291
|
Note: you will take quite a performance hit if you are reading big files
|
|
286
292
|
|
|
287
|
-
### `read(filepath: string, length: number, position: number,
|
|
293
|
+
### `read(filepath: string, length: number, position: number, options?: ReadOptions): string | number[]`
|
|
288
294
|
|
|
289
|
-
Reads `length` bytes from the given `position` of the file at `path` and returns contents. `
|
|
295
|
+
Reads `length` bytes from the given `position` of the file at `path` and returns contents. `options` can be string of encrypted types or object, default is `utf8`. Use `base64` or `uint8` or `float32` encoding for reading binary files.
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
type ReadOptions =
|
|
299
|
+
| 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32'
|
|
300
|
+
| { encoding: 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32' };
|
|
301
|
+
```
|
|
290
302
|
|
|
291
303
|
Note: reading big files piece by piece using this method may be useful in terms of performance.
|
|
292
304
|
Note: `float32` size is 4 bytes, so `position` and `length` should be specified in bytes (multiplied by 4)
|
|
293
305
|
|
|
294
|
-
### (Android only) `readFileAssets(filepath: string,
|
|
306
|
+
### (Android only) `readFileAssets(filepath: string, options?: ReadOptions) => string[]`
|
|
295
307
|
|
|
296
|
-
Reads the file at `path` in the Android app's assets folder and return contents. `
|
|
308
|
+
Reads the file at `path` in the Android app's assets folder and return contents. `options` can be string of encrypted types or object, default is `utf8`. Use `base64` encoding for reading binary files.
|
|
297
309
|
|
|
298
310
|
`filepath` is the relative path to the file from the root of the `assets` folder.
|
|
299
311
|
|
|
300
|
-
|
|
312
|
+
```ts
|
|
313
|
+
type ReadOptions =
|
|
314
|
+
| 'utf8' | 'ascii' | 'base64'
|
|
315
|
+
| { encoding: 'utf8' | 'ascii' | 'base64' };
|
|
316
|
+
```
|
|
301
317
|
|
|
302
|
-
|
|
318
|
+
### (Android only) `readFileRes: (filepath: string, options?: ReadOptions) => string[]`
|
|
303
319
|
|
|
304
|
-
|
|
320
|
+
Reads the file named `filename` in the Android app's `res` folder and return contents. Only the file name (not folder) needs to be specified. The file type will be detected from the extension and automatically located within `res/drawable` (for image files) or `res/raw` (for everything else). `options` can be string of encrypted types or object, default is `utf8`. Use `base64` encoding for reading binary files.
|
|
305
321
|
|
|
306
|
-
|
|
322
|
+
```ts
|
|
323
|
+
type ReadOptions =
|
|
324
|
+
| 'utf8' | 'ascii' | 'base64'
|
|
325
|
+
| { encoding: 'utf8' | 'ascii' };
|
|
326
|
+
```
|
|
307
327
|
|
|
308
|
-
### `
|
|
328
|
+
### `writeFile(filepath: string, contents: string | number[], options?: WriteOptions): void`
|
|
309
329
|
|
|
310
|
-
|
|
330
|
+
Write the `contents` to `filepath`. `options` can be string of encrypted types or object, default is `utf8`
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
type WriteOptions =
|
|
334
|
+
| 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32'
|
|
335
|
+
| {
|
|
336
|
+
encoding?: 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32',
|
|
337
|
+
NSFileProtectionKey?:
|
|
338
|
+
|"NSFileProtectionNone"
|
|
339
|
+
| "NSFileProtectionComplete"
|
|
340
|
+
| "NSFileProtectionCompleteUnlessOpen"
|
|
341
|
+
| "NSFileProtectionCompleteUntilFirstUserAuthentication"
|
|
342
|
+
| "NSFileProtectionCompleteWhenUserInactive" // iOS 17+ only
|
|
343
|
+
};
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
(IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
|
|
347
|
+
|
|
348
|
+
### `appendFile(filepath: string, contents: string | number[], options?: WriteOptions): void`
|
|
349
|
+
|
|
350
|
+
Append the `contents` to `filepath`. `encoding` can be string of encrypted types or object, default is `utf8`.
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
type WriteOptions =
|
|
354
|
+
| 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32'
|
|
355
|
+
| {
|
|
356
|
+
encoding?: 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32',
|
|
357
|
+
NSFileProtectionKey?:
|
|
358
|
+
|"NSFileProtectionNone"
|
|
359
|
+
| "NSFileProtectionComplete"
|
|
360
|
+
| "NSFileProtectionCompleteUnlessOpen"
|
|
361
|
+
| "NSFileProtectionCompleteUntilFirstUserAuthentication"
|
|
362
|
+
| "NSFileProtectionCompleteWhenUserInactive" // iOS 17+ only
|
|
363
|
+
};
|
|
364
|
+
```
|
|
311
365
|
|
|
312
|
-
|
|
366
|
+
(IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
|
|
313
367
|
|
|
314
|
-
|
|
368
|
+
### `write(filepath: string, contents: string | number[], position?: number, options?: WriteOptions): void`
|
|
369
|
+
|
|
370
|
+
Write the `contents` to `filepath` at the given random access position. When `position` is `undefined` or `-1` the contents is appended to the end of the file. `encoding` can be string of encrypted types or object, default is `utf8`.
|
|
371
|
+
|
|
372
|
+
```ts
|
|
373
|
+
type WriteOptions =
|
|
374
|
+
| 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32'
|
|
375
|
+
| {
|
|
376
|
+
encoding?: 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32',
|
|
377
|
+
NSFileProtectionKey?:
|
|
378
|
+
|"NSFileProtectionNone"
|
|
379
|
+
| "NSFileProtectionComplete"
|
|
380
|
+
| "NSFileProtectionCompleteUnlessOpen"
|
|
381
|
+
| "NSFileProtectionCompleteUntilFirstUserAuthentication"
|
|
382
|
+
| "NSFileProtectionCompleteWhenUserInactive" // iOS 17+ only
|
|
383
|
+
};
|
|
384
|
+
```
|
|
315
385
|
|
|
316
386
|
Note: `float32` size is 4 bytes, so `position` should be specified in bytes (multiplied by 4)
|
|
317
387
|
|
|
318
|
-
|
|
388
|
+
(IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
|
|
389
|
+
|
|
390
|
+
### `moveFile(filepath: string, destPath: string, options?: MoveCopyOptions): void`
|
|
319
391
|
|
|
320
392
|
Moves the file located at `filepath` to `destPath`. This is more performant than reading and then re-writing the file data because the move is done natively and the data doesn't have to be copied or cross the bridge.
|
|
321
393
|
|
|
394
|
+
```ts
|
|
395
|
+
type MoveCopyOptions =
|
|
396
|
+
| {
|
|
397
|
+
NSFileProtectionKey?:
|
|
398
|
+
|"NSFileProtectionNone"
|
|
399
|
+
| "NSFileProtectionComplete"
|
|
400
|
+
| "NSFileProtectionCompleteUnlessOpen"
|
|
401
|
+
| "NSFileProtectionCompleteUntilFirstUserAuthentication"
|
|
402
|
+
| "NSFileProtectionCompleteWhenUserInactive" // iOS 17+ only
|
|
403
|
+
};
|
|
404
|
+
```
|
|
405
|
+
|
|
322
406
|
Note: Overwrites existing file
|
|
323
407
|
|
|
324
|
-
|
|
408
|
+
(IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
|
|
409
|
+
|
|
410
|
+
### `copyFolder(srcFolderPath: string, destFolderPath: string, options?: MoveCopyOptions): void`
|
|
325
411
|
|
|
326
412
|
Copies the contents located at `srcFolderPath` to `destFolderPath`.
|
|
327
413
|
|
|
414
|
+
```ts
|
|
415
|
+
type MoveCopyOptions =
|
|
416
|
+
| {
|
|
417
|
+
NSFileProtectionKey?:
|
|
418
|
+
|"NSFileProtectionNone"
|
|
419
|
+
| "NSFileProtectionComplete"
|
|
420
|
+
| "NSFileProtectionCompleteUnlessOpen"
|
|
421
|
+
| "NSFileProtectionCompleteUntilFirstUserAuthentication"
|
|
422
|
+
| "NSFileProtectionCompleteWhenUserInactive" // iOS 17+ only
|
|
423
|
+
};
|
|
424
|
+
```
|
|
425
|
+
|
|
328
426
|
Note: Recursively replaces all files and folders
|
|
329
427
|
|
|
330
|
-
|
|
428
|
+
(IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
|
|
429
|
+
|
|
430
|
+
### `copyFile(filepath: string, destPath: string, options?: MoveCopyOptions): void`
|
|
331
431
|
|
|
332
432
|
Copies the file located at `filepath` to `destPath`.
|
|
333
433
|
|
|
434
|
+
```ts
|
|
435
|
+
type MoveCopyOptions =
|
|
436
|
+
| {
|
|
437
|
+
NSFileProtectionKey?:
|
|
438
|
+
|"NSFileProtectionNone"
|
|
439
|
+
| "NSFileProtectionComplete"
|
|
440
|
+
| "NSFileProtectionCompleteUnlessOpen"
|
|
441
|
+
| "NSFileProtectionCompleteUntilFirstUserAuthentication"
|
|
442
|
+
| "NSFileProtectionCompleteWhenUserInactive" // iOS 17+ only
|
|
443
|
+
};
|
|
444
|
+
```
|
|
445
|
+
|
|
334
446
|
Note: Error will be thrown if the file already exists.
|
|
335
447
|
|
|
448
|
+
(IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
|
|
449
|
+
|
|
336
450
|
### (Android only) `copyFileAssets(filepath: string, destPath: string): void`
|
|
337
451
|
|
|
338
452
|
Copies the file at `filepath` in the Android app's assets folder and copies it to the given `destPath ` path.
|
|
@@ -449,12 +563,20 @@ Note: `ctime` no longer supported
|
|
|
449
563
|
Create a directory at `filepath`. Automatically creates parents and does not throw if already exists (works like Linux `mkdir -p`).
|
|
450
564
|
|
|
451
565
|
```ts
|
|
452
|
-
type MkdirOptions =
|
|
453
|
-
|
|
454
|
-
|
|
566
|
+
type MkdirOptions =
|
|
567
|
+
| {
|
|
568
|
+
NSFileProtectionKey?:
|
|
569
|
+
|"NSFileProtectionNone"
|
|
570
|
+
| "NSFileProtectionComplete"
|
|
571
|
+
| "NSFileProtectionCompleteUnlessOpen"
|
|
572
|
+
| "NSFileProtectionCompleteUntilFirstUserAuthentication"
|
|
573
|
+
| "NSFileProtectionCompleteWhenUserInactive"; // iOS 17+ only
|
|
574
|
+
NSURLIsExcludedFromBackupKey?: boolean;
|
|
575
|
+
};
|
|
455
576
|
```
|
|
456
577
|
|
|
457
|
-
(IOS only):
|
|
578
|
+
(IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
|
|
579
|
+
(IOS only): The `options.NSURLIsExcludedFromBackupKey` property can be provided to set this attribute on iOS platforms. Apple will *reject* apps for storing offline cache data that does not have this attribute.
|
|
458
580
|
|
|
459
581
|
### `downloadFile(options: DownloadFileOptions, completeCallback?: DownloadResultFunc, errorCallback?: DownloadErrorFunc): DownloadResult | Promise<DownloadResult>`
|
|
460
582
|
|
|
@@ -13,58 +13,92 @@ void JavaHashMapToStlStringStringMap(JNIEnv *env, jobject hashMap, std::map<std:
|
|
|
13
13
|
// Get the Map's entry Set.
|
|
14
14
|
jclass mapClass = env->FindClass("java/util/Map");
|
|
15
15
|
if (mapClass == nullptr) {
|
|
16
|
-
|
|
16
|
+
env->DeleteLocalRef(hashMap);
|
|
17
|
+
return;
|
|
17
18
|
}
|
|
18
19
|
jmethodID entrySet =
|
|
19
|
-
|
|
20
|
+
env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;");
|
|
20
21
|
if (entrySet == nullptr) {
|
|
22
|
+
env->DeleteLocalRef(hashMap);
|
|
23
|
+
env->DeleteLocalRef(mapClass);
|
|
21
24
|
return;
|
|
22
25
|
}
|
|
23
26
|
jobject set = env->CallObjectMethod(hashMap, entrySet);
|
|
24
27
|
if (set == nullptr) {
|
|
28
|
+
env->DeleteLocalRef(hashMap);
|
|
29
|
+
env->DeleteLocalRef(mapClass);
|
|
25
30
|
return;
|
|
26
31
|
}
|
|
27
32
|
// Obtain an iterator over the Set
|
|
28
33
|
jclass setClass = env->FindClass("java/util/Set");
|
|
29
34
|
if (setClass == nullptr) {
|
|
35
|
+
env->DeleteLocalRef(hashMap);
|
|
36
|
+
env->DeleteLocalRef(mapClass);
|
|
37
|
+
env->DeleteLocalRef(set);
|
|
30
38
|
return;
|
|
31
39
|
}
|
|
32
40
|
jmethodID iterator =
|
|
33
|
-
|
|
41
|
+
env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
|
|
34
42
|
if (iterator == nullptr) {
|
|
43
|
+
env->DeleteLocalRef(hashMap);
|
|
44
|
+
env->DeleteLocalRef(mapClass);
|
|
45
|
+
env->DeleteLocalRef(set);
|
|
46
|
+
env->DeleteLocalRef(setClass);
|
|
35
47
|
return;
|
|
36
48
|
}
|
|
37
49
|
jobject iter = env->CallObjectMethod(set, iterator);
|
|
38
50
|
if (iter == nullptr) {
|
|
51
|
+
env->DeleteLocalRef(hashMap);
|
|
52
|
+
env->DeleteLocalRef(mapClass);
|
|
53
|
+
env->DeleteLocalRef(set);
|
|
54
|
+
env->DeleteLocalRef(setClass);
|
|
39
55
|
return;
|
|
40
56
|
}
|
|
41
57
|
// Get the Iterator method IDs
|
|
42
58
|
jclass iteratorClass = env->FindClass("java/util/Iterator");
|
|
43
59
|
if (iteratorClass == nullptr) {
|
|
60
|
+
env->DeleteLocalRef(hashMap);
|
|
61
|
+
env->DeleteLocalRef(mapClass);
|
|
62
|
+
env->DeleteLocalRef(set);
|
|
63
|
+
env->DeleteLocalRef(setClass);
|
|
64
|
+
env->DeleteLocalRef(iter);
|
|
44
65
|
return;
|
|
45
66
|
}
|
|
46
67
|
jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
|
|
47
|
-
if (hasNext == nullptr) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
68
|
jmethodID next =
|
|
51
|
-
|
|
52
|
-
if (next == nullptr) {
|
|
69
|
+
env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
|
|
70
|
+
if (hasNext == nullptr || next == nullptr) {
|
|
71
|
+
env->DeleteLocalRef(hashMap);
|
|
72
|
+
env->DeleteLocalRef(mapClass);
|
|
73
|
+
env->DeleteLocalRef(set);
|
|
74
|
+
env->DeleteLocalRef(setClass);
|
|
75
|
+
env->DeleteLocalRef(iter);
|
|
76
|
+
env->DeleteLocalRef(iteratorClass);
|
|
53
77
|
return;
|
|
54
78
|
}
|
|
55
79
|
// Get the Entry class method IDs
|
|
56
80
|
jclass entryClass = env->FindClass("java/util/Map$Entry");
|
|
57
81
|
if (entryClass == nullptr) {
|
|
82
|
+
env->DeleteLocalRef(hashMap);
|
|
83
|
+
env->DeleteLocalRef(mapClass);
|
|
84
|
+
env->DeleteLocalRef(set);
|
|
85
|
+
env->DeleteLocalRef(setClass);
|
|
86
|
+
env->DeleteLocalRef(iter);
|
|
87
|
+
env->DeleteLocalRef(iteratorClass);
|
|
58
88
|
return;
|
|
59
89
|
}
|
|
60
90
|
jmethodID getKey =
|
|
61
|
-
|
|
62
|
-
if (getKey == nullptr) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
91
|
+
env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
|
|
65
92
|
jmethodID getValue =
|
|
66
|
-
|
|
67
|
-
if (getValue == nullptr) {
|
|
93
|
+
env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
|
|
94
|
+
if (getKey == nullptr || getValue == nullptr) {
|
|
95
|
+
env->DeleteLocalRef(hashMap);
|
|
96
|
+
env->DeleteLocalRef(mapClass);
|
|
97
|
+
env->DeleteLocalRef(set);
|
|
98
|
+
env->DeleteLocalRef(setClass);
|
|
99
|
+
env->DeleteLocalRef(iter);
|
|
100
|
+
env->DeleteLocalRef(iteratorClass);
|
|
101
|
+
env->DeleteLocalRef(entryClass);
|
|
68
102
|
return;
|
|
69
103
|
}
|
|
70
104
|
// Iterate over the entry Set
|
|
@@ -90,6 +124,13 @@ void JavaHashMapToStlStringStringMap(JNIEnv *env, jobject hashMap, std::map<std:
|
|
|
90
124
|
env->ReleaseStringUTFChars(value, valueStr);
|
|
91
125
|
env->DeleteLocalRef(value);
|
|
92
126
|
}
|
|
127
|
+
env->DeleteLocalRef(hashMap);
|
|
128
|
+
env->DeleteLocalRef(mapClass);
|
|
129
|
+
env->DeleteLocalRef(set);
|
|
130
|
+
env->DeleteLocalRef(setClass);
|
|
131
|
+
env->DeleteLocalRef(iter);
|
|
132
|
+
env->DeleteLocalRef(iteratorClass);
|
|
133
|
+
env->DeleteLocalRef(entryClass);
|
|
93
134
|
}
|
|
94
135
|
|
|
95
136
|
extern "C"
|
|
@@ -102,14 +143,6 @@ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_downloa
|
|
|
102
143
|
) {
|
|
103
144
|
std::map<int, DownloadCallbacks>::iterator it = RNFSTurboPlatformHelper::downloadCallbacks.find(jobId);
|
|
104
145
|
if (it != RNFSTurboPlatformHelper::downloadCallbacks.end()) {
|
|
105
|
-
const auto now = std::chrono::steady_clock::now();
|
|
106
|
-
const auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
107
|
-
now - RNFSTurboPlatformHelper::downloadCallbacks[jobId].lastProgressCall
|
|
108
|
-
).count();
|
|
109
|
-
RNFSTurboPlatformHelper::downloadCallbacks[jobId].lastProgressCall = now - std::chrono::seconds(1);
|
|
110
|
-
if (elapsedTime < 50) {
|
|
111
|
-
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
112
|
-
}
|
|
113
146
|
RNFSTurboPlatformHelper::downloadCallbacks[jobId].completeCallback(
|
|
114
147
|
jobId,
|
|
115
148
|
statusCode,
|
|
@@ -168,20 +201,13 @@ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_downloa
|
|
|
168
201
|
double contentLength,
|
|
169
202
|
double bytesWritten
|
|
170
203
|
) {
|
|
171
|
-
std::map<int, DownloadCallbacks>::iterator
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
RNFSTurboPlatformHelper::downloadCallbacks[jobId].progressCallback(
|
|
179
|
-
jobId,
|
|
180
|
-
static_cast<float>(contentLength),
|
|
181
|
-
static_cast<float>(bytesWritten)
|
|
182
|
-
);
|
|
183
|
-
RNFSTurboPlatformHelper::downloadCallbacks[jobId].lastProgressCall = now;
|
|
184
|
-
}
|
|
204
|
+
std::map<int, DownloadCallbacks>::iterator it = RNFSTurboPlatformHelper::downloadCallbacks.find(jobId);
|
|
205
|
+
if (it != RNFSTurboPlatformHelper::downloadCallbacks.end()) {
|
|
206
|
+
RNFSTurboPlatformHelper::downloadCallbacks[jobId].progressCallback(
|
|
207
|
+
jobId,
|
|
208
|
+
static_cast<float>(contentLength),
|
|
209
|
+
static_cast<float>(bytesWritten)
|
|
210
|
+
);
|
|
185
211
|
}
|
|
186
212
|
}
|
|
187
213
|
|
|
@@ -196,12 +222,6 @@ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_uploadC
|
|
|
196
222
|
) {
|
|
197
223
|
std::map<int, UploadCallbacks>::iterator it = RNFSTurboPlatformHelper::uploadCallbacks.find(jobId);
|
|
198
224
|
if (it != RNFSTurboPlatformHelper::uploadCallbacks.end()) {
|
|
199
|
-
const auto now = std::chrono::steady_clock::now();
|
|
200
|
-
const auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(now - RNFSTurboPlatformHelper::uploadCallbacks[jobId].lastProgressCall).count();
|
|
201
|
-
RNFSTurboPlatformHelper::uploadCallbacks[jobId].lastProgressCall = now - std::chrono::seconds(1);
|
|
202
|
-
if (elapsedTime < 50) {
|
|
203
|
-
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
204
|
-
}
|
|
205
225
|
std::map<std::string, std::string> headers;
|
|
206
226
|
JavaHashMapToStlStringStringMap(env, headersObj, headers);
|
|
207
227
|
const char *body = env->GetStringUTFChars(bodyStr, nullptr);
|
|
@@ -233,20 +253,13 @@ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_uploadP
|
|
|
233
253
|
double totalBytesExpectedToSend,
|
|
234
254
|
double totalBytesSent
|
|
235
255
|
) {
|
|
236
|
-
std::map<int, UploadCallbacks>::iterator
|
|
237
|
-
if (
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
RNFSTurboPlatformHelper::uploadCallbacks[jobId].progressCallback(
|
|
244
|
-
jobId,
|
|
245
|
-
static_cast<float>(totalBytesExpectedToSend),
|
|
246
|
-
static_cast<float>(totalBytesSent)
|
|
247
|
-
);
|
|
248
|
-
RNFSTurboPlatformHelper::uploadCallbacks[jobId].lastProgressCall = now;
|
|
249
|
-
}
|
|
256
|
+
std::map<int, UploadCallbacks>::iterator it = RNFSTurboPlatformHelper::uploadCallbacks.find(jobId);
|
|
257
|
+
if (it != RNFSTurboPlatformHelper::uploadCallbacks.end()) {
|
|
258
|
+
RNFSTurboPlatformHelper::uploadCallbacks[jobId].progressCallback(
|
|
259
|
+
jobId,
|
|
260
|
+
static_cast<float>(totalBytesExpectedToSend),
|
|
261
|
+
static_cast<float>(totalBytesSent)
|
|
262
|
+
);
|
|
250
263
|
}
|
|
251
264
|
}
|
|
252
265
|
|
|
@@ -312,7 +325,7 @@ std::vector<ReadDirItem> RNFSTurboPlatformHelper::readDirAssets(const char* dirP
|
|
|
312
325
|
jniObj,
|
|
313
326
|
mid,
|
|
314
327
|
jniEnv->NewStringUTF(dirPath)
|
|
315
|
-
|
|
328
|
+
);
|
|
316
329
|
if (jniEnv->ExceptionCheck()) {
|
|
317
330
|
jniEnv->ExceptionClear();
|
|
318
331
|
throw "Dir not exists or access denied";
|
|
@@ -341,8 +354,8 @@ std::vector<ReadDirItem> RNFSTurboPlatformHelper::readDirAssets(const char* dirP
|
|
|
341
354
|
jniEnv->ReleaseStringUTFChars(isDirectoryStr, isDirectoryChr);
|
|
342
355
|
jniEnv->DeleteLocalRef(isDirectoryStr);
|
|
343
356
|
}
|
|
344
|
-
jniEnv->DeleteLocalRef(filesObject);
|
|
345
357
|
jniEnv->DeleteLocalRef(jniCls);
|
|
358
|
+
jniEnv->DeleteLocalRef(filesObject);
|
|
346
359
|
|
|
347
360
|
return files;
|
|
348
361
|
}
|
|
@@ -369,6 +382,9 @@ std::string RNFSTurboPlatformHelper::readFileAssetsOrRes(const char* filePath, b
|
|
|
369
382
|
std::string fileData = (char*) fileJBytes;
|
|
370
383
|
jniEnv->ReleaseByteArrayElements(fileBytesArr, fileJBytes, 0);
|
|
371
384
|
|
|
385
|
+
jniEnv->DeleteLocalRef(jniCls);
|
|
386
|
+
jniEnv->DeleteLocalRef(fileBytesArr);
|
|
387
|
+
|
|
372
388
|
return fileData;
|
|
373
389
|
}
|
|
374
390
|
|
|
@@ -387,6 +403,7 @@ void RNFSTurboPlatformHelper::copyFileAssetsOrRes(const char *filePath, const ch
|
|
|
387
403
|
jniEnv->NewStringUTF(destPath),
|
|
388
404
|
isRes
|
|
389
405
|
);
|
|
406
|
+
jniEnv->DeleteLocalRef(jniCls);
|
|
390
407
|
if (jniEnv->ExceptionCheck()) {
|
|
391
408
|
jniEnv->ExceptionClear();
|
|
392
409
|
throw isRes ? "Failed to copy res" : "Failed to copy asset";
|
|
@@ -407,6 +424,7 @@ bool RNFSTurboPlatformHelper::existsAssetsOrRes(const char *filePath, bool isRes
|
|
|
407
424
|
jniEnv->NewStringUTF(filePath),
|
|
408
425
|
isRes
|
|
409
426
|
);
|
|
427
|
+
jniEnv->DeleteLocalRef(jniCls);
|
|
410
428
|
if (jniEnv->ExceptionCheck()) {
|
|
411
429
|
jniEnv->ExceptionClear();
|
|
412
430
|
throw isRes ? "Failed to open asset" : "Failed to open res";
|
|
@@ -469,7 +487,7 @@ void RNFSTurboPlatformHelper::downloadFile(
|
|
|
469
487
|
}
|
|
470
488
|
|
|
471
489
|
jniEnv->CallVoidMethod(
|
|
472
|
-
|
|
490
|
+
jniObj,
|
|
473
491
|
mid,
|
|
474
492
|
jobId,
|
|
475
493
|
jniEnv->NewStringUTF(fromUrl),
|
|
@@ -482,9 +500,9 @@ void RNFSTurboPlatformHelper::downloadFile(
|
|
|
482
500
|
hasBeginCallback,
|
|
483
501
|
hasProgressCallback
|
|
484
502
|
);
|
|
503
|
+
jniEnv->DeleteLocalRef(jniCls);
|
|
485
504
|
jniEnv->DeleteLocalRef(mapClass);
|
|
486
505
|
jniEnv->DeleteLocalRef(headersMap);
|
|
487
|
-
jniEnv->DeleteLocalRef(headersMap);
|
|
488
506
|
}
|
|
489
507
|
|
|
490
508
|
void RNFSTurboPlatformHelper::stopDownload(int jobId) {
|
|
@@ -496,7 +514,7 @@ void RNFSTurboPlatformHelper::stopDownload(int jobId) {
|
|
|
496
514
|
);
|
|
497
515
|
|
|
498
516
|
jniEnv->CallVoidMethod(
|
|
499
|
-
|
|
517
|
+
jniObj,
|
|
500
518
|
mid,
|
|
501
519
|
jobId
|
|
502
520
|
);
|
|
@@ -588,7 +606,7 @@ void RNFSTurboPlatformHelper::uploadFiles(
|
|
|
588
606
|
}
|
|
589
607
|
|
|
590
608
|
jniEnv->CallVoidMethod(
|
|
591
|
-
|
|
609
|
+
jniObj,
|
|
592
610
|
mid,
|
|
593
611
|
jobId,
|
|
594
612
|
jniEnv->NewStringUTF(toUrl),
|
|
@@ -618,7 +636,7 @@ void RNFSTurboPlatformHelper::stopUpload(int jobId) {
|
|
|
618
636
|
);
|
|
619
637
|
|
|
620
638
|
jniEnv->CallVoidMethod(
|
|
621
|
-
|
|
639
|
+
jniObj,
|
|
622
640
|
mid,
|
|
623
641
|
jobId
|
|
624
642
|
);
|
|
@@ -627,8 +645,8 @@ void RNFSTurboPlatformHelper::stopUpload(int jobId) {
|
|
|
627
645
|
|
|
628
646
|
FSInfo RNFSTurboPlatformHelper::getFSInfo() {
|
|
629
647
|
jclass jniCls = jniEnv->GetObjectClass(jniObj);
|
|
630
|
-
jmethodID mid = jniEnv->
|
|
631
|
-
jobject infoArr = jniEnv->CallObjectMethod(
|
|
648
|
+
jmethodID mid = jniEnv->GetMethodID(jniCls, "getFSInfo", "()[J");
|
|
649
|
+
jobject infoArr = jniEnv->CallObjectMethod(jniObj, mid);
|
|
632
650
|
jlongArray *infoLongArr = reinterpret_cast<jlongArray*>(&infoArr);
|
|
633
651
|
jlong* infoData = jniEnv->GetLongArrayElements(*infoLongArr, NULL);
|
|
634
652
|
|
|
@@ -640,8 +658,8 @@ FSInfo RNFSTurboPlatformHelper::getFSInfo() {
|
|
|
640
658
|
};
|
|
641
659
|
|
|
642
660
|
jniEnv->ReleaseLongArrayElements(*infoLongArr, infoData, 0);
|
|
643
|
-
jniEnv->DeleteLocalRef(infoArr);
|
|
644
661
|
jniEnv->DeleteLocalRef(jniCls);
|
|
662
|
+
jniEnv->DeleteLocalRef(infoArr);
|
|
645
663
|
|
|
646
664
|
return fsInfo;
|
|
647
665
|
}
|
|
@@ -661,6 +679,7 @@ void RNFSTurboPlatformHelper::scanFile(int jobId, const char *path, RNFSTurboSca
|
|
|
661
679
|
jobId,
|
|
662
680
|
jniEnv->NewStringUTF(path)
|
|
663
681
|
);
|
|
682
|
+
jniEnv->DeleteLocalRef(jniCls);
|
|
664
683
|
if (jniEnv->ExceptionCheck()) {
|
|
665
684
|
jniEnv->ExceptionClear();
|
|
666
685
|
std::map<int, RNFSTurboScanCallback>::iterator it = RNFSTurboPlatformHelper::scanCallbacks.find(jobId);
|
|
@@ -669,7 +688,6 @@ void RNFSTurboPlatformHelper::scanFile(int jobId, const char *path, RNFSTurboSca
|
|
|
669
688
|
}
|
|
670
689
|
throw "Scan error";
|
|
671
690
|
}
|
|
672
|
-
jniEnv->DeleteLocalRef(jniCls);
|
|
673
691
|
}
|
|
674
692
|
|
|
675
693
|
std::vector<std::string> RNFSTurboPlatformHelper::getAllExternalFilesDirs() {
|
|
@@ -223,12 +223,15 @@ public class RNFSTurboPlatformHelper {
|
|
|
223
223
|
|
|
224
224
|
params.onTaskCompleted = new RNFSTurboDownloadParams.OnTaskCompleted() {
|
|
225
225
|
public void onTaskCompleted(RNFSTurboDownloadResult res) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
226
|
+
RNFSTurboDownloader downloader = downloaders.get(jobId);
|
|
227
|
+
if (downloader != null) {
|
|
228
|
+
if (res.exception == null) {
|
|
229
|
+
downloadCompleteCallback(jobId, res.statusCode, (double)res.bytesWritten);
|
|
230
|
+
} else {
|
|
231
|
+
downloadErrorCallback(jobId, res.exception.toString());
|
|
232
|
+
}
|
|
233
|
+
downloaders.remove(jobId);
|
|
230
234
|
}
|
|
231
|
-
downloaders.remove(jobId);
|
|
232
235
|
}
|
|
233
236
|
};
|
|
234
237
|
|
|
@@ -236,7 +239,10 @@ public class RNFSTurboPlatformHelper {
|
|
|
236
239
|
params.onDownloadBegin = new RNFSTurboDownloadParams.OnDownloadBegin() {
|
|
237
240
|
@Override
|
|
238
241
|
public void onDownloadBegin(int statusCode, long contentLength, Map<String, String> headers) {
|
|
239
|
-
|
|
242
|
+
RNFSTurboDownloader downloader = downloaders.get(jobId);
|
|
243
|
+
if (downloader != null) {
|
|
244
|
+
downloadBeginCallback(jobId, statusCode, (double)contentLength, new HashMap<String, String>(headers));
|
|
245
|
+
}
|
|
240
246
|
}
|
|
241
247
|
};
|
|
242
248
|
}
|
|
@@ -244,7 +250,10 @@ public class RNFSTurboPlatformHelper {
|
|
|
244
250
|
if (hasProgressCallback) {
|
|
245
251
|
params.onDownloadProgress = new RNFSTurboDownloadParams.OnDownloadProgress() {
|
|
246
252
|
public void onDownloadProgress(long contentLength, long bytesWritten) {
|
|
247
|
-
|
|
253
|
+
RNFSTurboDownloader downloader = downloaders.get(jobId);
|
|
254
|
+
if (downloader != null) {
|
|
255
|
+
downloadProgressCallback(jobId, (double)contentLength, (double)bytesWritten);
|
|
256
|
+
}
|
|
248
257
|
}
|
|
249
258
|
};
|
|
250
259
|
}
|
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
namespace facebook::react {
|
|
12
12
|
|
|
13
13
|
NativeRNFSTurboModule::NativeRNFSTurboModule(std::shared_ptr<CallInvoker> jsInvoker)
|
|
14
|
-
: NativeRNFSTurboModuleCxxSpec(jsInvoker) {}
|
|
14
|
+
: NativeRNFSTurboModuleCxxSpec(std::move(jsInvoker)) {}
|
|
15
15
|
|
|
16
16
|
NativeRNFSTurboModule::~NativeRNFSTurboModule() {}
|
|
17
17
|
|
|
18
18
|
jsi::Object NativeRNFSTurboModule::createRNFSTurbo(jsi::Runtime& runtime) {
|
|
19
19
|
auto instance = std::make_shared<RNFSTurboHostObject>();
|
|
20
|
+
instance->jsInvoker = jsInvoker_;
|
|
20
21
|
return jsi::Object::createFromHostObject(runtime, instance);
|
|
21
22
|
}
|
|
22
23
|
|