xref: /aosp_15_r20/external/okio/okio/src/jvmMain/kotlin/okio/NioFileSystemFileHandle.kt (revision f9742813c14b702d71392179818a9e591da8620c)
1 /*
2  * Copyright (C) 2023 Square, Inc.
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 package okio
17 
18 import java.nio.ByteBuffer
19 import java.nio.channels.FileChannel
20 
21 internal class NioFileSystemFileHandle(
22   readWrite: Boolean,
23   private val fileChannel: FileChannel,
24 ) : FileHandle(readWrite) {
25 
26   @Synchronized
protectedResizenull27   override fun protectedResize(size: Long) {
28     val currentSize = size()
29     val delta = size - currentSize
30     if (delta > 0) {
31       protectedWrite(currentSize, ByteArray(delta.toInt()), 0, delta.toInt())
32     } else {
33       fileChannel.truncate(size)
34     }
35   }
36 
37   @Synchronized
protectedSizenull38   override fun protectedSize(): Long {
39     return fileChannel.size()
40   }
41 
42   @Synchronized
protectedReadnull43   override fun protectedRead(
44     fileOffset: Long,
45     array: ByteArray,
46     arrayOffset: Int,
47     byteCount: Int,
48   ): Int {
49     fileChannel.position(fileOffset)
50     val byteBuffer = ByteBuffer.wrap(array, arrayOffset, byteCount)
51     var bytesRead = 0
52     while (bytesRead < byteCount) {
53       val readResult = fileChannel.read(byteBuffer)
54       if (readResult == -1) {
55         if (bytesRead == 0) return -1
56         break
57       }
58       bytesRead += readResult
59     }
60     return bytesRead
61   }
62 
63   @Synchronized
protectedWritenull64   override fun protectedWrite(
65     fileOffset: Long,
66     array: ByteArray,
67     arrayOffset: Int,
68     byteCount: Int,
69   ) {
70     fileChannel.position(fileOffset)
71     val byteBuffer = ByteBuffer.wrap(array, arrayOffset, byteCount)
72     fileChannel.write(byteBuffer)
73   }
74 
75   @Synchronized
protectedFlushnull76   override fun protectedFlush() {
77     fileChannel.force(true)
78   }
79 
80   @Synchronized
protectedClosenull81   override fun protectedClose() {
82     fileChannel.close()
83   }
84 }
85