1 // Copyright 2023-present 650 Industries. All rights reserved.
2 
3 import ExpoModulesCore
4 
ensureFileDirectoryExistsnull5 internal func ensureFileDirectoryExists(_ fileUrl: URL) throws {
6   let directoryPath = fileUrl.deletingLastPathComponent()
7 
8   if !FileManager.default.fileExists(atPath: directoryPath.path) {
9     throw DirectoryNotExistsException(directoryPath.path)
10   }
11 }
12 
readFileAsBase64null13 internal func readFileAsBase64(path: String, options: ReadingOptions) throws -> String {
14   let file = FileHandle(forReadingAtPath: path)
15 
16   guard let file else {
17     throw FileNotExistsException(path)
18   }
19   if let position = options.position, position != 0 {
20     // TODO: Handle these errors?
21     try? file.seek(toOffset: UInt64(position))
22   }
23   if let length = options.length {
24     return file.readData(ofLength: length).base64EncodedString(options: .endLineWithLineFeed)
25   }
26   return file.readDataToEndOfFile().base64EncodedString(options: .endLineWithLineFeed)
27 }
28 
writeFileAsBase64null29 internal func writeFileAsBase64(path: String, string: String) throws {
30   let data = Data(base64Encoded: string, options: .ignoreUnknownCharacters)
31 
32   if !FileManager.default.createFile(atPath: path, contents: data) {
33     throw FileWriteFailedException(path)
34   }
35 }
36 
removeFilenull37 internal func removeFile(path: String, idempotent: Bool = false) throws {
38   if FileManager.default.fileExists(atPath: path) {
39     do {
40       try FileManager.default.removeItem(atPath: path)
41     } catch {
42       throw FileCannotDeleteException(path)
43         .causedBy(error)
44     }
45   } else if !idempotent {
46     throw FileCannotDeleteException(path)
47       .causedBy(FileNotExistsException(path))
48   }
49 }
50 
getResourceValuesnull51 internal func getResourceValues(from directory: URL?, forKeys: Set<URLResourceKey>) throws -> URLResourceValues? {
52   do {
53     return try directory?.resourceValues(forKeys: forKeys)
54   } catch {
55     throw CannotDetermineDiskCapacity().causedBy(error)
56   }
57 }
58 
ensurePathPermissionnull59 internal func ensurePathPermission(_ appContext: AppContext?, path: String, flag: EXFileSystemPermissionFlags) throws {
60   guard let permissionsManager: EXFilePermissionModuleInterface = appContext?.legacyModule(implementing: EXFilePermissionModuleInterface.self) else {
61     throw Exceptions.PermissionsModuleNotFound()
62   }
63   guard permissionsManager.getPathPermissions(path).contains(flag) else {
64     throw flag == .read ? FileNotReadableException(path) : FileNotWritableException(path)
65   }
66 }
67