Use native endian mode from MappedByteBuffer
This commit is contained in:
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
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user