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
import java.nio.ByteOrder
import java.nio.MappedByteBuffer
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(
zipEntryDescription: ZipEntryDescription
): ByteArray {
order(ByteOrder.LITTLE_ENDIAN)
val extraSize =
readShortLittleEndianFromOffset((zipEntryDescription.offsetInFile + LOCAL_FILE_HEADER_EXTRA_OFFSET))
getShort(zipEntryDescription.offsetInFile + LOCAL_FILE_HEADER_EXTRA_OFFSET)
position(
zipEntryDescription.offsetInFile + LOCAL_FILE_HEADER_SIZE + zipEntryDescription.fileNameSize + extraSize
@@ -57,39 +59,41 @@ fun MappedByteBuffer.contentsToByteArray(
}
fun MappedByteBuffer.parseCentralDirectory(): List<ZipEntryDescription> {
order(ByteOrder.LITTLE_ENDIAN)
val endOfCentralDirectoryOffset = (capacity() - END_OF_CENTRAL_DIR_SIZE downTo 0).first { offset ->
// header of "End of central directory"
readIntLittleEndianFromOffset(offset) == 0x06054b50
getInt(offset) == 0x06054b50
}
val entriesNumber = readShortLittleEndianFromOffset(endOfCentralDirectoryOffset + 10)
val offsetOfCentralDirectory = readIntLittleEndianFromOffset(endOfCentralDirectoryOffset + 16)
val entriesNumber = getShort(endOfCentralDirectoryOffset + 10)
val offsetOfCentralDirectory = getInt(endOfCentralDirectoryOffset + 16)
var currentOffset = offsetOfCentralDirectory
val result = mutableListOf<ZipEntryDescription>()
for (i in 0 until entriesNumber) {
val headerConst = readIntLittleEndianFromOffset(currentOffset)
val headerConst = getInt(currentOffset)
require(headerConst == 0x02014b50) {
"$i: $headerConst"
}
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 uncompressedSize = readIntLittleEndian()
val fileNameLength = readShortLittleEndian()
val extraLength = readShortLittleEndian()
val fileCommentLength = readShortLittleEndian()
val compressedSize = getInt(currentOffset + 20)
val uncompressedSize = getInt(currentOffset + 24)
val fileNameLength = getShort(currentOffset + 28).toInt()
val extraLength = getShort(currentOffset + 30).toInt()
val fileCommentLength = getShort(currentOffset + 32).toInt()
val offsetOfFileData = readIntLittleEndianFromOffset(currentOffset + 42)
val offsetOfFileData = getInt(currentOffset + 42)
val bytesForName = ByteArray(fileNameLength)
position(currentOffset + 46)
get(bytesForName)
val name = String(bytesForName)
@@ -114,29 +118,3 @@ fun MappedByteBuffer.parseCentralDirectory(): List<ZipEntryDescription> {
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
}