@@ -344,7 +344,137 @@ class ISystem : public core::IReferenceCounted
344
344
}
345
345
void unmount (const IFileArchive* archive, const system::path& pathAlias)
346
346
{
347
+ assert (false ); // TODO(dan): i swear i'll get to it at some point
348
+ }
349
+
350
+ /*
351
+ Returns true if the path is writable (e.g. if p is a path inside an archive the function will return true).
352
+ The path existence is not checked.
353
+ */
354
+ bool isPathReadOnly (const system::path& p)
355
+ {
356
+ auto curPath = p;
357
+ while (!curPath.empty () && curPath.parent_path () != curPath)
358
+ {
359
+ auto archives = m_cachedArchiveFiles.findRange (curPath);
360
+ if (!archives.empty ()) return true ;
361
+
362
+ curPath = curPath.parent_path ().generic_string ();
363
+ }
364
+ return false ;
365
+ }
366
+
367
+ bool createDirectory (const system::path& p)
368
+ {
369
+ return std::filesystem::create_directory (p);
370
+ }
371
+
372
+ bool deleteDirectory (const system::path& p)
373
+ {
374
+ return std::filesystem::remove (p);
375
+ }
376
+
377
+
378
+ /*
379
+ Recursively lists all files and directories in the directory.
380
+ */
381
+ core::vector<system::path> listFilesInDirectory (const system::path& p)
382
+ {
383
+ if (isPathReadOnly (p))
384
+ {
385
+ auto curPath = p;
386
+ while (!curPath.empty () && curPath.parent_path () != curPath)
387
+ {
388
+ auto archives = m_cachedArchiveFiles.findRange (curPath);
389
+ for (auto & arch : archives)
390
+ {
391
+ auto rel = std::filesystem::relative (p, arch.first );
392
+ auto res = arch.second ->listAssets (rel.generic_string ().c_str ());
393
+ std::for_each (res.begin (), res.end (), [&arch](system::path& p) {p = arch.first / p; });
394
+ return res;
395
+ }
396
+
397
+ curPath = curPath.parent_path ().generic_string ();
398
+ }
399
+ return {};
400
+ }
401
+ else
402
+ {
403
+ uint32_t fileCount = std::distance (std::filesystem::recursive_directory_iterator (p), std::filesystem::recursive_directory_iterator{});
404
+ core::vector<system::path> res;
405
+ res.reserve (fileCount);
406
+ for (auto entry : std::filesystem::recursive_directory_iterator (p))
407
+ {
408
+ res.push_back (entry.path ());
409
+ }
410
+ return res;
411
+ }
412
+ }
413
+
414
+
415
+ bool isDirectory (const system::path& p)
416
+ {
417
+ if (isPathReadOnly (p))
418
+ {
419
+ return p.extension () == " " ; // TODO: this is a temporary decision until i figure out how to check if a file is directory in androi APK
420
+ }
421
+ else
422
+ {
423
+ return std::filesystem::is_directory (p);
424
+ }
425
+ }
426
+
427
+ /*
428
+ Recursively copy a directory or a file from one place to another.
429
+ from - a path to the source file or directory. Must exist. Can be both readonly and mutable path.
430
+ to - a path to the destination file or directory. Must be mutable path (isPathReadonly(to) must be false).
431
+ */
432
+ bool copy (const system::path& from, const system::path& to)
433
+ {
434
+ constexpr auto copyFile = [this ](const system::path& from, const system::path& to)
435
+ {
436
+ system::future<core::smart_refctd_ptr<IFile>> readFileFut, writeFileFut;
437
+ system::future<size_t > readFut, writeFut;
438
+
439
+ createFile (readFileFut, from, IFile::ECF_READ);
440
+ createFile (writeFileFut, from, IFile::ECF_WRITE);
441
+ auto readFile = readFileFut.get ();
442
+ auto writeFile = writeFileFut.get ();
347
443
444
+ char * fileData = (char *)malloc (readFile->getSize ());
445
+ readFile->read (readFut, fileData, 0 , readFile->getSize ());
446
+ readFut.get ();
447
+
448
+ writeFile->write (writeFut, fileData, 0 , readFile->getSize ());
449
+ writeFut.get ();
450
+
451
+ free (fileData);
452
+ };
453
+ if (isPathReadOnly (from))
454
+ {
455
+ if (isPathReadOnly (to)) return false ;
456
+ if (isDirectory (from))
457
+ {
458
+ auto allFiles = listFilesInDirectory (from);
459
+ for (const auto & file : allFiles)
460
+ {
461
+ auto relative = std::filesystem::relative (file, from);
462
+ auto targetName = to / relative;
463
+ copyFile (file, targetName);
464
+ }
465
+ }
466
+ else
467
+ {
468
+ copyFile (from, to);
469
+ }
470
+ return true ;
471
+ }
472
+ else
473
+ {
474
+ std::error_code error;
475
+ std::filesystem::copy (from, to, error);
476
+ return static_cast <bool >(error);
477
+ }
348
478
}
349
479
350
480
struct SystemMemory
0 commit comments