react-native-fs-turbo 0.1.2 → 0.1.5

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 (31) hide show
  1. package/android/CMakeLists.txt +36 -0
  2. package/android/build.gradle +106 -0
  3. package/android/gradle.properties +5 -0
  4. package/android/src/main/AndroidManifest.xml +3 -0
  5. package/android/src/main/AndroidManifestNew.xml +2 -0
  6. package/android/src/main/cpp/RNFSTurboLogger.cpp +16 -0
  7. package/android/src/main/cpp/RNFSTurboPlatformHelper.cpp +703 -0
  8. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboDownloadParams.java +48 -0
  9. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboDownloadResult.java +25 -0
  10. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboDownloader.java +190 -0
  11. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboIORejectionException.java +32 -0
  12. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboPackage.java +52 -0
  13. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboPlatformContextModule.java +99 -0
  14. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboPlatformHelper.java +458 -0
  15. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboUploadParams.java +45 -0
  16. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboUploadResult.java +28 -0
  17. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboUploader.java +237 -0
  18. package/cpp/NativeRNFSTurboModule.cpp +2 -2
  19. package/cpp/NativeRNFSTurboModule.h +2 -18
  20. package/cpp/RNFSTurboHostObject.cpp +1 -1
  21. package/cpp/RNFSTurboHostObject.h +1 -1
  22. package/lib/commonjs/createRNFSTurbo.js +1 -1
  23. package/lib/commonjs/createRNFSTurbo.js.map +1 -1
  24. package/lib/module/createRNFSTurbo.js +1 -1
  25. package/lib/module/createRNFSTurbo.js.map +1 -1
  26. package/lib/typescript/NativeRNFSTurboModule.d.ts +1 -1
  27. package/lib/typescript/NativeRNFSTurboModule.d.ts.map +1 -1
  28. package/package.json +6 -1
  29. package/react-native.config.js +20 -0
  30. package/src/NativeRNFSTurboModule.ts +1 -1
  31. package/src/createRNFSTurbo.ts +1 -1
@@ -0,0 +1,703 @@
1
+ //
2
+ // RNFSTurboPlatformHelper.cpp
3
+ // react-native-fs-turbo
4
+ //
5
+ // Created by Sergei Kazakov on 16.09.24.
6
+ //
7
+
8
+ #include <jni.h>
9
+ #include "RNFSTurboPlatformHelper.h"
10
+ #include "RNFSTurboLogger.h"
11
+
12
+ void JavaHashMapToStlStringStringMap(JNIEnv *env, jobject hashMap, std::map<std::string, std::string>& mapOut) {
13
+ // Get the Map's entry Set.
14
+ jclass mapClass = env->FindClass("java/util/Map");
15
+ if (mapClass == nullptr) {
16
+ return;
17
+ }
18
+ jmethodID entrySet =
19
+ env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;");
20
+ if (entrySet == nullptr) {
21
+ return;
22
+ }
23
+ jobject set = env->CallObjectMethod(hashMap, entrySet);
24
+ if (set == nullptr) {
25
+ return;
26
+ }
27
+ // Obtain an iterator over the Set
28
+ jclass setClass = env->FindClass("java/util/Set");
29
+ if (setClass == nullptr) {
30
+ return;
31
+ }
32
+ jmethodID iterator =
33
+ env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
34
+ if (iterator == nullptr) {
35
+ return;
36
+ }
37
+ jobject iter = env->CallObjectMethod(set, iterator);
38
+ if (iter == nullptr) {
39
+ return;
40
+ }
41
+ // Get the Iterator method IDs
42
+ jclass iteratorClass = env->FindClass("java/util/Iterator");
43
+ if (iteratorClass == nullptr) {
44
+ return;
45
+ }
46
+ jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
47
+ if (hasNext == nullptr) {
48
+ return;
49
+ }
50
+ jmethodID next =
51
+ env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
52
+ if (next == nullptr) {
53
+ return;
54
+ }
55
+ // Get the Entry class method IDs
56
+ jclass entryClass = env->FindClass("java/util/Map$Entry");
57
+ if (entryClass == nullptr) {
58
+ return;
59
+ }
60
+ jmethodID getKey =
61
+ env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
62
+ if (getKey == nullptr) {
63
+ return;
64
+ }
65
+ jmethodID getValue =
66
+ env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
67
+ if (getValue == nullptr) {
68
+ return;
69
+ }
70
+ // Iterate over the entry Set
71
+ while (env->CallBooleanMethod(iter, hasNext)) {
72
+ jobject entry = env->CallObjectMethod(iter, next);
73
+ jstring key = (jstring) env->CallObjectMethod(entry, getKey);
74
+ jstring value = (jstring) env->CallObjectMethod(entry, getValue);
75
+ const char* keyStr = env->GetStringUTFChars(key, nullptr);
76
+ if (!keyStr) { // Out of memory
77
+ return;
78
+ }
79
+ const char* valueStr = env->GetStringUTFChars(value, nullptr);
80
+ if (!valueStr) { // Out of memory
81
+ env->ReleaseStringUTFChars(key, keyStr);
82
+ return;
83
+ }
84
+
85
+ mapOut.insert(std::make_pair(std::string(keyStr), std::string(valueStr)));
86
+
87
+ env->DeleteLocalRef(entry);
88
+ env->ReleaseStringUTFChars(key, keyStr);
89
+ env->DeleteLocalRef(key);
90
+ env->ReleaseStringUTFChars(value, valueStr);
91
+ env->DeleteLocalRef(value);
92
+ }
93
+ }
94
+
95
+ extern "C"
96
+ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_downloadCompleteCallback(
97
+ JNIEnv *env,
98
+ jclass cls,
99
+ int jobId,
100
+ int statusCode,
101
+ double bytesWritten
102
+ ) {
103
+ std::map<int, DownloadCallbacks>::iterator it = RNFSTurboPlatformHelper::downloadCallbacks.find(jobId);
104
+ 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
+ RNFSTurboPlatformHelper::downloadCallbacks[jobId].completeCallback(
114
+ jobId,
115
+ statusCode,
116
+ static_cast<float>(bytesWritten)
117
+ );
118
+ RNFSTurboPlatformHelper::downloadCallbacks.erase(it);
119
+ }
120
+ }
121
+
122
+ extern "C"
123
+ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_downloadErrorCallback(
124
+ JNIEnv *env,
125
+ jclass cls,
126
+ int jobId,
127
+ jstring errorStr
128
+ ) {
129
+ std::map<int, DownloadCallbacks>::iterator it = RNFSTurboPlatformHelper::downloadCallbacks.find(jobId);
130
+ if (it != RNFSTurboPlatformHelper::downloadCallbacks.end()) {
131
+ const char *error = env->GetStringUTFChars(errorStr, nullptr);
132
+ RNFSTurboPlatformHelper::downloadCallbacks[jobId].errorCallback(jobId, error);
133
+ RNFSTurboPlatformHelper::downloadCallbacks.erase(it);
134
+ env->ReleaseStringUTFChars(errorStr, error);
135
+ }
136
+ env->DeleteLocalRef(errorStr);
137
+ }
138
+
139
+ extern "C"
140
+ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_downloadBeginCallback(
141
+ JNIEnv *env,
142
+ jclass cls,
143
+ int jobId,
144
+ int statusCode,
145
+ double contentLength,
146
+ jobject headersObj
147
+ ) {
148
+ std::map<int, DownloadCallbacks>::iterator it = RNFSTurboPlatformHelper::downloadCallbacks.find(jobId);
149
+ if (it != RNFSTurboPlatformHelper::downloadCallbacks.end()) {
150
+ std::map<std::string, std::string> headers;
151
+ JavaHashMapToStlStringStringMap(env, headersObj, headers);
152
+
153
+ RNFSTurboPlatformHelper::downloadCallbacks[jobId].beginCallback(
154
+ jobId,
155
+ statusCode,
156
+ static_cast<float>(contentLength),
157
+ headers
158
+ );
159
+ }
160
+ env->DeleteLocalRef(headersObj);
161
+ }
162
+
163
+ extern "C"
164
+ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_downloadProgressCallback(
165
+ JNIEnv *env,
166
+ jclass cls,
167
+ int jobId,
168
+ double contentLength,
169
+ double bytesWritten
170
+ ) {
171
+ std::map<int, DownloadCallbacks>::iterator callback = RNFSTurboPlatformHelper::downloadCallbacks.find(jobId);
172
+ if (callback != RNFSTurboPlatformHelper::downloadCallbacks.end()) {
173
+ const auto now = std::chrono::steady_clock::now();
174
+ const auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(
175
+ now - RNFSTurboPlatformHelper::downloadCallbacks[jobId].lastProgressCall
176
+ ).count();
177
+ if (elapsedTime > 50) {
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
+ }
185
+ }
186
+ }
187
+
188
+ extern "C"
189
+ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_uploadCompleteCallback(
190
+ JNIEnv *env,
191
+ jclass cls,
192
+ int jobId,
193
+ int statusCode,
194
+ jobject headersObj,
195
+ jstring bodyStr
196
+ ) {
197
+ std::map<int, UploadCallbacks>::iterator it = RNFSTurboPlatformHelper::uploadCallbacks.find(jobId);
198
+ 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
+ std::map<std::string, std::string> headers;
206
+ JavaHashMapToStlStringStringMap(env, headersObj, headers);
207
+ const char *body = env->GetStringUTFChars(bodyStr, nullptr);
208
+ RNFSTurboPlatformHelper::uploadCallbacks[jobId].completeCallback(jobId, statusCode, headers, body);
209
+ RNFSTurboPlatformHelper::uploadCallbacks.erase(it);
210
+ env->ReleaseStringUTFChars(bodyStr, body);
211
+ }
212
+ env->DeleteLocalRef(headersObj);
213
+ env->DeleteLocalRef(bodyStr);
214
+ }
215
+
216
+ extern "C"
217
+ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_uploadBeginCallback(
218
+ JNIEnv *env,
219
+ jclass cls,
220
+ int jobId
221
+ ) {
222
+ std::map<int, UploadCallbacks>::iterator it = RNFSTurboPlatformHelper::uploadCallbacks.find(jobId);
223
+ if (it != RNFSTurboPlatformHelper::uploadCallbacks.end()) {
224
+ RNFSTurboPlatformHelper::uploadCallbacks[jobId].beginCallback(jobId);
225
+ }
226
+ }
227
+
228
+ extern "C"
229
+ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_uploadProgressCallback(
230
+ JNIEnv *env,
231
+ jclass cls,
232
+ int jobId,
233
+ double totalBytesExpectedToSend,
234
+ double totalBytesSent
235
+ ) {
236
+ std::map<int, UploadCallbacks>::iterator callback = RNFSTurboPlatformHelper::uploadCallbacks.find(jobId);
237
+ if (callback != RNFSTurboPlatformHelper::uploadCallbacks.end()) {
238
+ const auto now = std::chrono::steady_clock::now();
239
+ const auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(
240
+ now - RNFSTurboPlatformHelper::uploadCallbacks[jobId].lastProgressCall
241
+ ).count();
242
+ if (elapsedTime > 50) {
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
+ }
250
+ }
251
+ }
252
+
253
+ extern "C"
254
+ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_uploadErrorCallback(
255
+ JNIEnv *env,
256
+ jclass cls,
257
+ int jobId,
258
+ jstring errorStr
259
+ ) {
260
+ std::map<int, UploadCallbacks>::iterator it = RNFSTurboPlatformHelper::uploadCallbacks.find(jobId);
261
+ if (it != RNFSTurboPlatformHelper::uploadCallbacks.end()) {
262
+ const char *error = env->GetStringUTFChars(errorStr, nullptr);
263
+ RNFSTurboPlatformHelper::uploadCallbacks[jobId].errorCallback(jobId, error);
264
+ RNFSTurboPlatformHelper::uploadCallbacks.erase(it);
265
+ env->ReleaseStringUTFChars(errorStr, error);
266
+ }
267
+ env->DeleteLocalRef(errorStr);
268
+ }
269
+
270
+ extern "C"
271
+ JNIEXPORT void JNICALL Java_com_cmpayc_rnfsturbo_RNFSTurboPlatformHelper_scanCallback(
272
+ JNIEnv *env,
273
+ jclass cls,
274
+ int jobId,
275
+ jstring pathStr
276
+ ) {
277
+ std::map<int, RNFSTurboScanCallback>::iterator it = RNFSTurboPlatformHelper::scanCallbacks.find(jobId);
278
+ if (it != RNFSTurboPlatformHelper::scanCallbacks.end()) {
279
+ const char *path = env->GetStringUTFChars(pathStr, nullptr);
280
+ RNFSTurboPlatformHelper::scanCallbacks[jobId](
281
+ jobId,
282
+ path
283
+ );
284
+ env->ReleaseStringUTFChars(pathStr, path);
285
+ RNFSTurboPlatformHelper::scanCallbacks.erase(it);
286
+ }
287
+ }
288
+
289
+ RNFSTurboPlatformHelper::RNFSTurboPlatformHelper(JNIEnv *env) {
290
+ jniEnv = env;
291
+ jclass jniCls = env->FindClass("com/cmpayc/rnfsturbo/RNFSTurboPlatformHelper");
292
+ jmethodID initObject = jniEnv->GetMethodID(jniCls, "<init>", "(Landroid/content/Context;)V");
293
+ jclass contextCls = env->FindClass("com/cmpayc/rnfsturbo/RNFSTurboPlatformContextModule");
294
+ jmethodID mid = env->GetStaticMethodID(contextCls, "getContext", "()Landroid/content/Context;");
295
+ jobject context = env->CallStaticObjectMethod(contextCls, mid);
296
+ jobject obj = jniEnv->NewObject(jniCls, initObject, context);
297
+ jniObj = jniEnv->NewGlobalRef(obj);
298
+ jniEnv->DeleteLocalRef(jniCls);
299
+ jniEnv->DeleteLocalRef(context);
300
+ jniEnv->DeleteLocalRef(obj);
301
+ }
302
+
303
+ std::vector<ReadDirItem> RNFSTurboPlatformHelper::readDirAssets(const char* dirPath) {
304
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
305
+ std::vector<ReadDirItem> files;
306
+ jmethodID mid = jniEnv->GetMethodID(
307
+ jniCls,
308
+ "readDirAssets",
309
+ "(Ljava/lang/String;)[Ljava/lang/String;"
310
+ );
311
+ jobjectArray filesObject = (jobjectArray)jniEnv->CallObjectMethod(
312
+ jniObj,
313
+ mid,
314
+ jniEnv->NewStringUTF(dirPath)
315
+ );
316
+ if (jniEnv->ExceptionCheck()) {
317
+ jniEnv->ExceptionClear();
318
+ throw "Dir not exists or access denied";
319
+ }
320
+ int length = (int)jniEnv->GetArrayLength(filesObject);
321
+ for (int i = 0; i < length; i += 4) {
322
+ jstring nameStr = (jstring)jniEnv->GetObjectArrayElement(filesObject, i);
323
+ jstring pathStr = (jstring)jniEnv->GetObjectArrayElement(filesObject, i + 1);
324
+ jstring sizeStr = (jstring)jniEnv->GetObjectArrayElement(filesObject, i + 2);
325
+ jstring isDirectoryStr = (jstring)jniEnv->GetObjectArrayElement(filesObject, i + 3);
326
+
327
+ const char* name = jniEnv->GetStringUTFChars(nameStr, nullptr);
328
+ const char* path = jniEnv->GetStringUTFChars(pathStr, nullptr);
329
+ const char* size = jniEnv->GetStringUTFChars(sizeStr, nullptr);
330
+ const char* isDirectoryChr = jniEnv->GetStringUTFChars(isDirectoryStr, nullptr);
331
+ float floatSize = std::stof(size);
332
+ bool isDirectory = std::strcmp(isDirectoryChr, "1") == 0;
333
+ ReadDirItem dirItem{name, path, floatSize, isDirectory};
334
+ files.push_back(dirItem);
335
+ jniEnv->ReleaseStringUTFChars(nameStr, name);
336
+ jniEnv->DeleteLocalRef(nameStr);
337
+ jniEnv->ReleaseStringUTFChars(pathStr, path);
338
+ jniEnv->DeleteLocalRef(pathStr);
339
+ jniEnv->ReleaseStringUTFChars(sizeStr, size);
340
+ jniEnv->DeleteLocalRef(sizeStr);
341
+ jniEnv->ReleaseStringUTFChars(isDirectoryStr, isDirectoryChr);
342
+ jniEnv->DeleteLocalRef(isDirectoryStr);
343
+ }
344
+ jniEnv->DeleteLocalRef(filesObject);
345
+ jniEnv->DeleteLocalRef(jniCls);
346
+
347
+ return files;
348
+ }
349
+
350
+ std::string RNFSTurboPlatformHelper::readFileAssetsOrRes(const char* filePath, bool isRes) {
351
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
352
+ std::vector<ReadDirItem> files;
353
+ jmethodID mid = jniEnv->GetMethodID(
354
+ jniCls,
355
+ "readFileAssetsOrRes",
356
+ "(Ljava/lang/String;Z)[B"
357
+ );
358
+ jbyteArray fileBytesArr = (jbyteArray) jniEnv->CallObjectMethod(
359
+ jniObj,
360
+ mid,
361
+ jniEnv->NewStringUTF(filePath),
362
+ isRes
363
+ );
364
+ if (jniEnv->ExceptionCheck()) {
365
+ jniEnv->ExceptionClear();
366
+ throw isRes ? "Failed to open asset" : "Failed to open res";
367
+ }
368
+ jbyte* fileJBytes = jniEnv->GetByteArrayElements(fileBytesArr, nullptr);
369
+ std::string fileData = (char*) fileJBytes;
370
+ jniEnv->ReleaseByteArrayElements(fileBytesArr, fileJBytes, 0);
371
+
372
+ return fileData;
373
+ }
374
+
375
+ void RNFSTurboPlatformHelper::copyFileAssetsOrRes(const char *filePath, const char *destPath, bool isRes) {
376
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
377
+ std::vector<ReadDirItem> files;
378
+ jmethodID mid = jniEnv->GetMethodID(
379
+ jniCls,
380
+ "copyFileAssetsOrRes",
381
+ "(Ljava/lang/String;Ljava/lang/String;Z)V"
382
+ );
383
+ jniEnv->CallVoidMethod(
384
+ jniObj,
385
+ mid,
386
+ jniEnv->NewStringUTF(filePath),
387
+ jniEnv->NewStringUTF(destPath),
388
+ isRes
389
+ );
390
+ if (jniEnv->ExceptionCheck()) {
391
+ jniEnv->ExceptionClear();
392
+ throw isRes ? "Failed to copy res" : "Failed to copy asset";
393
+ }
394
+ }
395
+
396
+ bool RNFSTurboPlatformHelper::existsAssetsOrRes(const char *filePath, bool isRes) {
397
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
398
+ std::vector<ReadDirItem> files;
399
+ jmethodID mid = jniEnv->GetMethodID(
400
+ jniCls,
401
+ "existsAssetsOrRes",
402
+ "(Ljava/lang/String;Z)Z"
403
+ );
404
+ jboolean isExists = jniEnv->CallBooleanMethod(
405
+ jniObj,
406
+ mid,
407
+ jniEnv->NewStringUTF(filePath),
408
+ isRes
409
+ );
410
+ if (jniEnv->ExceptionCheck()) {
411
+ jniEnv->ExceptionClear();
412
+ throw isRes ? "Failed to open asset" : "Failed to open res";
413
+ }
414
+
415
+ return (bool)isExists;
416
+ }
417
+
418
+ void RNFSTurboPlatformHelper::downloadFile(
419
+ int jobId,
420
+ const char* fromUrl,
421
+ const char* toFile,
422
+ std::map<std::string, std::string> headers,
423
+ bool background,
424
+ bool discretionary,
425
+ bool cacheable,
426
+ int progressInterval,
427
+ float progressDivider,
428
+ int connectionTimeout,
429
+ int readTimeout,
430
+ int backgroundTimeout,
431
+ RNFSTurboCompleteDownloadCallback completeCallback,
432
+ RNFSTurboErrorCallback errorCallback,
433
+ std::optional<RNFSTurboBeginDownloadCallback> beginCallback,
434
+ std::optional<RNFSTurboProgressDownloadCallback> progressCallback,
435
+ std::optional<RNFSTurboResumableDownloadCallback> resumableCallback
436
+ ) {
437
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
438
+ jmethodID mid = jniEnv->GetMethodID(
439
+ jniCls,
440
+ "downloadFile",
441
+ "(ILjava/lang/String;Ljava/lang/String;Ljava/util/HashMap;IFIIZZ)V"
442
+ );
443
+ jclass mapClass = jniEnv->FindClass("java/util/HashMap");
444
+ jmethodID initHashMap = jniEnv->GetMethodID(mapClass, "<init>", "()V");
445
+ jobject headersMap = jniEnv->NewObject(mapClass, initHashMap);
446
+ jmethodID putMethod = jniEnv->GetMethodID(
447
+ mapClass,
448
+ "put",
449
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"
450
+ );
451
+ for (auto const& [key, val] : headers) {
452
+ jniEnv->CallObjectMethod(
453
+ headersMap,
454
+ putMethod,
455
+ jniEnv->NewStringUTF(key.c_str()),
456
+ jniEnv->NewStringUTF(val.c_str())
457
+ );
458
+ }
459
+
460
+ bool hasBeginCallback = beginCallback.has_value();
461
+ bool hasProgressCallback = progressCallback.has_value();
462
+ RNFSTurboPlatformHelper::downloadCallbacks[jobId].completeCallback = completeCallback;
463
+ RNFSTurboPlatformHelper::downloadCallbacks[jobId].errorCallback = errorCallback;
464
+ if (hasBeginCallback) {
465
+ RNFSTurboPlatformHelper::downloadCallbacks[jobId].beginCallback = beginCallback.value();
466
+ }
467
+ if (hasProgressCallback) {
468
+ RNFSTurboPlatformHelper::downloadCallbacks[jobId].progressCallback = progressCallback.value();
469
+ }
470
+
471
+ jniEnv->CallVoidMethod(
472
+ jniCls,
473
+ mid,
474
+ jobId,
475
+ jniEnv->NewStringUTF(fromUrl),
476
+ jniEnv->NewStringUTF(toFile),
477
+ headersMap,
478
+ progressInterval,
479
+ progressDivider,
480
+ connectionTimeout,
481
+ readTimeout,
482
+ hasBeginCallback,
483
+ hasProgressCallback
484
+ );
485
+ jniEnv->DeleteLocalRef(mapClass);
486
+ jniEnv->DeleteLocalRef(headersMap);
487
+ jniEnv->DeleteLocalRef(headersMap);
488
+ }
489
+
490
+ void RNFSTurboPlatformHelper::stopDownload(int jobId) {
491
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
492
+ jmethodID mid = jniEnv->GetMethodID(
493
+ jniCls,
494
+ "stopDownload",
495
+ "(I)V"
496
+ );
497
+
498
+ jniEnv->CallVoidMethod(
499
+ jniCls,
500
+ mid,
501
+ jobId
502
+ );
503
+ jniEnv->DeleteLocalRef(jniCls);
504
+ }
505
+
506
+ void RNFSTurboPlatformHelper::uploadFiles(
507
+ int jobId,
508
+ const char* toUrl,
509
+ bool binaryStreamOnly,
510
+ UploadFileItem files[],
511
+ int filesNum,
512
+ std::map<std::string, std::string> headers,
513
+ std::map<std::string, std::string> fields,
514
+ const char* method,
515
+ RNFSTurboCompleteUploadCallback completeCallback,
516
+ RNFSTurboErrorCallback errorCallback,
517
+ std::optional<RNFSTurboBeginUploadCallback> beginCallback,
518
+ std::optional<RNFSTurboProgressUploadCallback> progressCallback
519
+ ) {
520
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
521
+ jmethodID mid = jniEnv->GetMethodID(
522
+ jniCls,
523
+ "uploadFile",
524
+ "(ILjava/lang/String;Z[Ljava/lang/String;ILjava/util/HashMap;Ljava/util/HashMap;Ljava/lang/String;ZZ)V"
525
+ );
526
+ jobjectArray filesArr = jniEnv->NewObjectArray(
527
+ filesNum * 4,
528
+ jniEnv->FindClass("java/lang/String"),
529
+ jniEnv->NewStringUTF("")
530
+ );
531
+ for (int i = 0; i < filesNum * 4; i += 4) {
532
+ jniEnv->SetObjectArrayElement(
533
+ filesArr,
534
+ i,
535
+ jniEnv->NewStringUTF(files[i].name.c_str())
536
+ );
537
+ jniEnv->SetObjectArrayElement(
538
+ filesArr,
539
+ i + 1,
540
+ jniEnv->NewStringUTF(files[i].filename.c_str())
541
+ );
542
+ jniEnv->SetObjectArrayElement(
543
+ filesArr,
544
+ i + 2,
545
+ jniEnv->NewStringUTF(files[i].filepath.c_str())
546
+ );
547
+ jniEnv->SetObjectArrayElement(
548
+ filesArr,
549
+ i + 3,
550
+ jniEnv->NewStringUTF(files[i].filetype.c_str())
551
+ );
552
+ }
553
+
554
+ jclass mapClass = jniEnv->FindClass("java/util/HashMap");
555
+ jmethodID initHashMap = jniEnv->GetMethodID(mapClass, "<init>", "()V");
556
+ jobject headersMap = jniEnv->NewObject(mapClass, initHashMap);
557
+ jmethodID putMethod = jniEnv->GetMethodID(
558
+ mapClass,
559
+ "put",
560
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"
561
+ );
562
+ for (auto const& [key, val] : headers) {
563
+ jniEnv->CallObjectMethod(
564
+ headersMap,
565
+ putMethod,
566
+ jniEnv->NewStringUTF(key.c_str()),
567
+ jniEnv->NewStringUTF(val.c_str())
568
+ );
569
+ }
570
+ jobject fieldsMap = jniEnv->NewObject(mapClass, initHashMap);
571
+ for (auto const& [key, val] : fields) {
572
+ jniEnv->CallObjectMethod(
573
+ fieldsMap,
574
+ putMethod,
575
+ jniEnv->NewStringUTF(key.c_str()),
576
+ jniEnv->NewStringUTF(val.c_str())
577
+ );
578
+ }
579
+ bool hasBeginCallback = beginCallback.has_value();
580
+ bool hasProgressCallback = progressCallback.has_value();
581
+ RNFSTurboPlatformHelper::uploadCallbacks[jobId].completeCallback = completeCallback;
582
+ RNFSTurboPlatformHelper::uploadCallbacks[jobId].errorCallback = errorCallback;
583
+ if (hasBeginCallback) {
584
+ RNFSTurboPlatformHelper::uploadCallbacks[jobId].beginCallback = beginCallback.value();
585
+ }
586
+ if (hasProgressCallback) {
587
+ RNFSTurboPlatformHelper::uploadCallbacks[jobId].progressCallback = progressCallback.value();
588
+ }
589
+
590
+ jniEnv->CallVoidMethod(
591
+ jniCls,
592
+ mid,
593
+ jobId,
594
+ jniEnv->NewStringUTF(toUrl),
595
+ binaryStreamOnly,
596
+ filesArr,
597
+ filesNum,
598
+ headersMap,
599
+ fieldsMap,
600
+ jniEnv->NewStringUTF(method),
601
+ hasBeginCallback,
602
+ hasProgressCallback
603
+ );
604
+
605
+ jniEnv->DeleteLocalRef(filesArr);
606
+ jniEnv->DeleteLocalRef(mapClass);
607
+ jniEnv->DeleteLocalRef(headersMap);
608
+ jniEnv->DeleteLocalRef(fieldsMap);
609
+ jniEnv->DeleteLocalRef(jniCls);
610
+ }
611
+
612
+ void RNFSTurboPlatformHelper::stopUpload(int jobId) {
613
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
614
+ jmethodID mid = jniEnv->GetMethodID(
615
+ jniCls,
616
+ "stopUpload",
617
+ "(I)V"
618
+ );
619
+
620
+ jniEnv->CallVoidMethod(
621
+ jniCls,
622
+ mid,
623
+ jobId
624
+ );
625
+ jniEnv->DeleteLocalRef(jniCls);
626
+ }
627
+
628
+ FSInfo RNFSTurboPlatformHelper::getFSInfo() {
629
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
630
+ jmethodID mid = jniEnv->GetStaticMethodID(jniCls, "getFSInfo", "()[J");
631
+ jobject infoArr = jniEnv->CallObjectMethod(jniCls, mid);
632
+ jlongArray *infoLongArr = reinterpret_cast<jlongArray*>(&infoArr);
633
+ jlong* infoData = jniEnv->GetLongArrayElements(*infoLongArr, NULL);
634
+
635
+ FSInfo fsInfo = {
636
+ static_cast<unsigned long long>(infoData[0]),
637
+ static_cast<unsigned long long>(infoData[1]),
638
+ static_cast<unsigned long long>(infoData[2]),
639
+ static_cast<unsigned long long>(infoData[3])
640
+ };
641
+
642
+ jniEnv->ReleaseLongArrayElements(*infoLongArr, infoData, 0);
643
+ jniEnv->DeleteLocalRef(infoArr);
644
+ jniEnv->DeleteLocalRef(jniCls);
645
+
646
+ return fsInfo;
647
+ }
648
+
649
+ void RNFSTurboPlatformHelper::scanFile(int jobId, const char *path, RNFSTurboScanCallback scanCallback) {
650
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
651
+ std::vector<std::string> items;
652
+ jmethodID mid = jniEnv->GetMethodID(
653
+ jniCls,
654
+ "scanFile",
655
+ "(ILjava/lang/String;)V"
656
+ );
657
+ RNFSTurboPlatformHelper::scanCallbacks[jobId] = scanCallback;
658
+ jniEnv->CallVoidMethod(
659
+ jniObj,
660
+ mid,
661
+ jobId,
662
+ jniEnv->NewStringUTF(path)
663
+ );
664
+ if (jniEnv->ExceptionCheck()) {
665
+ jniEnv->ExceptionClear();
666
+ std::map<int, RNFSTurboScanCallback>::iterator it = RNFSTurboPlatformHelper::scanCallbacks.find(jobId);
667
+ if (it != RNFSTurboPlatformHelper::scanCallbacks.end()) {
668
+ RNFSTurboPlatformHelper::scanCallbacks.erase(it);
669
+ }
670
+ throw "Scan error";
671
+ }
672
+ jniEnv->DeleteLocalRef(jniCls);
673
+ }
674
+
675
+ std::vector<std::string> RNFSTurboPlatformHelper::getAllExternalFilesDirs() {
676
+ jclass jniCls = jniEnv->GetObjectClass(jniObj);
677
+ std::vector<std::string> items;
678
+ jmethodID mid = jniEnv->GetMethodID(
679
+ jniCls,
680
+ "getAllExternalFilesDirs",
681
+ "()[Ljava/lang/String;"
682
+ );
683
+ jobjectArray filesObject = (jobjectArray) jniEnv->CallObjectMethod(
684
+ jniObj,
685
+ mid
686
+ );
687
+ if (jniEnv->ExceptionCheck()) {
688
+ jniEnv->ExceptionClear();
689
+ throw "Get all external files dirs error";
690
+ }
691
+ int length = (int) jniEnv->GetArrayLength(filesObject);
692
+ for (int i = 0; i < length; i++) {
693
+ jstring itemStr = (jstring)jniEnv->GetObjectArrayElement(filesObject, i);
694
+
695
+ const char* item = jniEnv->GetStringUTFChars(itemStr, nullptr);
696
+ items.push_back(item);
697
+ jniEnv->ReleaseStringUTFChars(itemStr, item);
698
+ }
699
+ jniEnv->DeleteLocalRef(filesObject);
700
+ jniEnv->DeleteLocalRef(jniCls);
701
+
702
+ return items;
703
+ }