Use native endian mode from MappedByteBuffer

This commit is contained in:
Denis.Zharkov
2021-03-24 18:41:44 +03:00
committed by TeamCityServer
parent 33cf058b55
commit 7ca2a83f08
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.cli.jvm.compiler.jarfs package org.jetbrains.kotlin.cli.jvm.compiler.jarfs
import java.nio.ByteOrder
import java.nio.MappedByteBuffer import java.nio.MappedByteBuffer
import java.util.zip.Inflater import java.util.zip.Inflater
@@ -32,8 +33,9 @@ private const val LOCAL_FILE_HEADER_SIZE = LOCAL_FILE_HEADER_EXTRA_OFFSET + 2
fun MappedByteBuffer.contentsToByteArray( fun MappedByteBuffer.contentsToByteArray(
zipEntryDescription: ZipEntryDescription zipEntryDescription: ZipEntryDescription
): ByteArray { ): ByteArray {
order(ByteOrder.LITTLE_ENDIAN)
val extraSize = val extraSize =
readShortLittleEndianFromOffset((zipEntryDescription.offsetInFile + LOCAL_FILE_HEADER_EXTRA_OFFSET)) getShort(zipEntryDescription.offsetInFile + LOCAL_FILE_HEADER_EXTRA_OFFSET)
position( position(
zipEntryDescription.offsetInFile + LOCAL_FILE_HEADER_SIZE + zipEntryDescription.fileNameSize + extraSize zipEntryDescription.offsetInFile + LOCAL_FILE_HEADER_SIZE + zipEntryDescription.fileNameSize + extraSize
@@ -57,39 +59,41 @@ fun MappedByteBuffer.contentsToByteArray(
} }
fun MappedByteBuffer.parseCentralDirectory(): List<ZipEntryDescription> { fun MappedByteBuffer.parseCentralDirectory(): List<ZipEntryDescription> {
order(ByteOrder.LITTLE_ENDIAN)
val endOfCentralDirectoryOffset = (capacity() - END_OF_CENTRAL_DIR_SIZE downTo 0).first { offset -> val endOfCentralDirectoryOffset = (capacity() - END_OF_CENTRAL_DIR_SIZE downTo 0).first { offset ->
// header of "End of central directory" // header of "End of central directory"
readIntLittleEndianFromOffset(offset) == 0x06054b50 getInt(offset) == 0x06054b50
} }
val entriesNumber = readShortLittleEndianFromOffset(endOfCentralDirectoryOffset + 10) val entriesNumber = getShort(endOfCentralDirectoryOffset + 10)
val offsetOfCentralDirectory = readIntLittleEndianFromOffset(endOfCentralDirectoryOffset + 16) val offsetOfCentralDirectory = getInt(endOfCentralDirectoryOffset + 16)
var currentOffset = offsetOfCentralDirectory var currentOffset = offsetOfCentralDirectory
val result = mutableListOf<ZipEntryDescription>() val result = mutableListOf<ZipEntryDescription>()
for (i in 0 until entriesNumber) { for (i in 0 until entriesNumber) {
val headerConst = readIntLittleEndianFromOffset(currentOffset) val headerConst = getInt(currentOffset)
require(headerConst == 0x02014b50) { require(headerConst == 0x02014b50) {
"$i: $headerConst" "$i: $headerConst"
} }
val versionNeededToExtract = val versionNeededToExtract =
readShortLittleEndianFromOffset(currentOffset + 6) getShort(currentOffset + 6).toInt()
val compressionMethod = readShortLittleEndianFromOffset(currentOffset + 10) val compressionMethod = getShort(currentOffset + 10).toInt()
val compressedSize = readIntLittleEndianFromOffset(currentOffset + 20) val compressedSize = getInt(currentOffset + 20)
val uncompressedSize = readIntLittleEndian() val uncompressedSize = getInt(currentOffset + 24)
val fileNameLength = readShortLittleEndian() val fileNameLength = getShort(currentOffset + 28).toInt()
val extraLength = readShortLittleEndian() val extraLength = getShort(currentOffset + 30).toInt()
val fileCommentLength = readShortLittleEndian() val fileCommentLength = getShort(currentOffset + 32).toInt()
val offsetOfFileData = readIntLittleEndianFromOffset(currentOffset + 42) val offsetOfFileData = getInt(currentOffset + 42)
val bytesForName = ByteArray(fileNameLength) val bytesForName = ByteArray(fileNameLength)
position(currentOffset + 46)
get(bytesForName) get(bytesForName)
val name = String(bytesForName) val name = String(bytesForName)
@@ -114,29 +118,3 @@ fun MappedByteBuffer.parseCentralDirectory(): List<ZipEntryDescription> {
return result return result
} }
private fun MappedByteBuffer.readIntLittleEndianFromOffset(offset: Int): Int {
position(offset)
return readIntLittleEndian()
}
private fun MappedByteBuffer.getByteAsInt(): Int = java.lang.Byte.toUnsignedInt(get())
private fun MappedByteBuffer.readIntLittleEndian(): Int {
val a = this.getByteAsInt()
val b = this.getByteAsInt()
val c = this.getByteAsInt()
val d = this.getByteAsInt()
return (d shl 24) + (c shl 16) + (b shl 8) + a
}
private fun MappedByteBuffer.readShortLittleEndianFromOffset(offset: Int): Int {
position(offset)
return readShortLittleEndian()
}
private fun MappedByteBuffer.readShortLittleEndian(): Int {
val a = this.getByteAsInt()
val b = this.getByteAsInt()
return (b shl 8) + a
}