Skip to content

Commit a6b13fe

Browse files
#430: Add compareFiles method
1 parent 43adf1a commit a6b13fe

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

core/tzdbOnFilesystem/src/internal/filesystem.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
@file:OptIn(ExperimentalForeignApi::class, UnsafeNumber::class)
7+
78
package kotlinx.datetime.internal
89

910
import kotlinx.cinterop.*
@@ -43,3 +44,41 @@ internal fun Path.tryTraverseDirectory(
4344
}
4445
return true
4546
}
47+
48+
internal fun compareFiles(file1: String, file2: String): Boolean = memScoped {
49+
try {
50+
val stat1 = alloc<stat>()
51+
val stat2 = alloc<stat>()
52+
53+
if (stat(file1, stat1.ptr) != 0 || stat(file2, stat2.ptr) != 0) return false
54+
if (stat1.st_size != stat2.st_size) return false
55+
56+
val f1 = fopen(file1, "rb") ?: return false
57+
val f2 = fopen(file2, "rb") ?: run { fclose(f1); return false }
58+
59+
try {
60+
val bufferSize = 4096
61+
val buffer1 = allocArray<ByteVar>(bufferSize)
62+
val buffer2 = allocArray<ByteVar>(bufferSize)
63+
64+
while (true) {
65+
val read1 = fread(buffer1, 1u, bufferSize.toULong(), f1).toInt()
66+
val read2 = fread(buffer2, 1u, bufferSize.toULong(), f2).toInt()
67+
68+
if (read1 != read2) return false
69+
if (read1 == 0) break // EOF
70+
71+
for (i in 0..<read1.toInt()) {
72+
if (buffer1[i] != buffer2[i]) return false
73+
}
74+
}
75+
76+
return true
77+
} finally {
78+
fclose(f1)
79+
fclose(f2)
80+
}
81+
} catch (_: Throwable) {
82+
return false
83+
}
84+
}

0 commit comments

Comments
 (0)