1 /* <lambda>null2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.datastore 18 19 import androidx.datastore.core.InterProcessCoordinator 20 import androidx.datastore.core.Storage 21 import androidx.datastore.core.okio.OkioStorage 22 import kotlin.reflect.KClass 23 import okio.FileSystem 24 import okio.IOException 25 import okio.Path 26 27 open class OkioTestIO(private val fileSystem: FileSystem = FileSystem.SYSTEM) : 28 TestIO<OkioPath, IOException>( 29 getTmpDir = { 30 OkioPath(fileSystem = fileSystem, path = FileSystem.SYSTEM_TEMPORARY_DIRECTORY) 31 } 32 ) { getStoragenull33 override fun getStorage( 34 serializerConfig: TestingSerializerConfig, 35 coordinatorProducer: () -> InterProcessCoordinator, 36 futureFile: () -> OkioPath 37 ): Storage<Byte> { 38 return OkioStorage( 39 fileSystem = fileSystem, 40 serializer = TestingOkioSerializer(serializerConfig), 41 coordinatorProducer = { _, _ -> coordinatorProducer() } 42 ) { 43 futureFile().path 44 } 45 } 46 ioExceptionnull47 override fun ioException(message: String): IOException { 48 return IOException(message) 49 } 50 ioExceptionClassnull51 override fun ioExceptionClass(): KClass<IOException> = IOException::class 52 } 53 54 class OkioPath(private val fileSystem: FileSystem, val path: Path) : TestFile<OkioPath>() { 55 override val name: String 56 get() = path.name 57 58 override fun path(): String { 59 return path.normalized().toString() 60 } 61 62 override fun delete(): Boolean { 63 if (!fileSystem.exists(path)) { 64 // to be consistent with the TestFile API. 65 return false 66 } 67 fileSystem.delete(path) 68 return !fileSystem.exists(path) 69 } 70 71 override fun exists(): Boolean { 72 return fileSystem.exists(path) 73 } 74 75 override fun mkdirs(mustCreate: Boolean) { 76 if (exists()) { 77 check(fileSystem.metadataOrNull(path)?.isDirectory == true) { 78 "$path already exists but it is not a directory" 79 } 80 check(!mustCreate) { "Directory $path already exists" } 81 } 82 fileSystem.createDirectories(path, mustCreate = mustCreate) 83 } 84 85 override fun isRegularFile(): Boolean { 86 return fileSystem.metadataOrNull(path)?.isRegularFile == true 87 } 88 89 override fun isDirectory(): Boolean { 90 return fileSystem.metadataOrNull(path)?.isDirectory == true 91 } 92 93 override fun protectedResolve(relative: String): OkioPath { 94 return OkioPath(fileSystem, path / relative) 95 } 96 97 override fun parentFile(): OkioPath? { 98 return path.parent?.let { OkioPath(fileSystem = fileSystem, path = it) } 99 } 100 101 override fun protectedWrite(body: ByteArray) { 102 fileSystem.write(path) { 103 write(body) 104 flush() 105 } 106 } 107 108 override fun protectedReadBytes(): ByteArray { 109 return fileSystem.read(path) { readByteArray() } 110 } 111 } 112