Added some variants to readers
This commit is contained in:
parent
a3282098b1
commit
66d7a267b2
@ -1,10 +1,12 @@
|
|||||||
package ru.dbotthepony.kstarbound.io
|
package ru.dbotthepony.kstarbound.io
|
||||||
|
|
||||||
import com.google.gson.*
|
import com.google.gson.*
|
||||||
|
import java.io.DataInputStream
|
||||||
|
import java.io.InputStream
|
||||||
import java.io.RandomAccessFile
|
import java.io.RandomAccessFile
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Интерфейс для чтения и записи двоичного формата Json от Chucklefish
|
* Represents interface to read binary json format by Chucklefish
|
||||||
*/
|
*/
|
||||||
object BinaryJson {
|
object BinaryJson {
|
||||||
const val TYPE_NULL = 0x01
|
const val TYPE_NULL = 0x01
|
||||||
@ -25,7 +27,40 @@ object BinaryJson {
|
|||||||
TYPE_NULL -> JsonNull.INSTANCE
|
TYPE_NULL -> JsonNull.INSTANCE
|
||||||
TYPE_DOUBLE -> JsonPrimitive(reader.readDouble())
|
TYPE_DOUBLE -> JsonPrimitive(reader.readDouble())
|
||||||
TYPE_BOOLEAN -> JsonPrimitive(reader.readBoolean())
|
TYPE_BOOLEAN -> JsonPrimitive(reader.readBoolean())
|
||||||
TYPE_INT -> JsonPrimitive(reader.readVarLong())
|
TYPE_INT -> {
|
||||||
|
var read = reader.readVarLong()
|
||||||
|
val sign = read and 0x1L
|
||||||
|
read = read ushr 1
|
||||||
|
|
||||||
|
if (sign == 1L) {
|
||||||
|
JsonPrimitive(read - 1L)
|
||||||
|
} else {
|
||||||
|
JsonPrimitive(read)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TYPE_STRING -> JsonPrimitive(reader.readASCIIString(reader.readVarInt()))
|
||||||
|
TYPE_ARRAY -> readArray(reader)
|
||||||
|
TYPE_OBJECT -> readObject(reader)
|
||||||
|
else -> throw JsonParseException("Unknown element type $id")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readElement(reader: DataInputStream): JsonElement {
|
||||||
|
return when (val id = reader.read()) {
|
||||||
|
TYPE_NULL -> JsonNull.INSTANCE
|
||||||
|
TYPE_DOUBLE -> JsonPrimitive(reader.readDouble())
|
||||||
|
TYPE_BOOLEAN -> JsonPrimitive(reader.readBoolean())
|
||||||
|
TYPE_INT -> {
|
||||||
|
var read = reader.readVarLong()
|
||||||
|
val sign = read and 0x1L
|
||||||
|
read = read ushr 1
|
||||||
|
|
||||||
|
if (sign == 1L) {
|
||||||
|
JsonPrimitive(read - 1L)
|
||||||
|
} else {
|
||||||
|
JsonPrimitive(read)
|
||||||
|
}
|
||||||
|
}
|
||||||
TYPE_STRING -> JsonPrimitive(reader.readASCIIString(reader.readVarInt()))
|
TYPE_STRING -> JsonPrimitive(reader.readASCIIString(reader.readVarInt()))
|
||||||
TYPE_ARRAY -> readArray(reader)
|
TYPE_ARRAY -> readArray(reader)
|
||||||
TYPE_OBJECT -> readObject(reader)
|
TYPE_OBJECT -> readObject(reader)
|
||||||
@ -65,6 +100,38 @@ object BinaryJson {
|
|||||||
return build
|
return build
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun readObject(reader: DataInputStream): JsonObject {
|
||||||
|
val values = reader.readVarInt() - 1
|
||||||
|
|
||||||
|
if (values == -1) {
|
||||||
|
return JsonObject()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values < -1) {
|
||||||
|
throw JsonParseException("Tried to read json object with $values elements in it")
|
||||||
|
}
|
||||||
|
|
||||||
|
val build = JsonObject()
|
||||||
|
|
||||||
|
for (i in 0 .. values) {
|
||||||
|
val key: String
|
||||||
|
|
||||||
|
try {
|
||||||
|
key = reader.readASCIIString(reader.readVarInt())
|
||||||
|
} catch(err: Throwable) {
|
||||||
|
throw JsonParseException("Reading json object at $i", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
build.add(key, readElement(reader))
|
||||||
|
} catch(err: Throwable) {
|
||||||
|
throw JsonParseException("Reading json object at $i with name $key", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return build
|
||||||
|
}
|
||||||
|
|
||||||
fun readArray(reader: RandomAccessFile): JsonArray {
|
fun readArray(reader: RandomAccessFile): JsonArray {
|
||||||
val values = reader.readVarInt() - 1
|
val values = reader.readVarInt() - 1
|
||||||
|
|
||||||
@ -84,4 +151,24 @@ object BinaryJson {
|
|||||||
|
|
||||||
return build
|
return build
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun readArray(reader: DataInputStream): JsonArray {
|
||||||
|
val values = reader.readVarInt() - 1
|
||||||
|
|
||||||
|
if (values == -1) {
|
||||||
|
return JsonArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values < -1) {
|
||||||
|
throw JsonParseException("Tried to read json array with $values elements in it")
|
||||||
|
}
|
||||||
|
|
||||||
|
val build = JsonArray()
|
||||||
|
|
||||||
|
for (i in 0 .. values) {
|
||||||
|
build.add(readElement(reader))
|
||||||
|
}
|
||||||
|
|
||||||
|
return build
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package ru.dbotthepony.kstarbound.io
|
package ru.dbotthepony.kstarbound.io
|
||||||
|
|
||||||
|
import java.io.DataInputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.RandomAccessFile
|
import java.io.RandomAccessFile
|
||||||
@ -44,6 +45,46 @@ fun RandomAccessFile.readVarInt(): Int {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Читает Variable Length Integer как Long
|
||||||
|
*/
|
||||||
|
fun InputStream.readVarLong(): Long {
|
||||||
|
var result = 0L
|
||||||
|
var read = read()
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
result = (result shl 7) or (read.toLong() and 0x7FL)
|
||||||
|
|
||||||
|
if (read and 0x80 == 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
read = read()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Читает Variable Length Integer как Int
|
||||||
|
*/
|
||||||
|
fun InputStream.readVarInt(): Int {
|
||||||
|
var result = 0
|
||||||
|
var read = read()
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
result = (result shl 7) or (read and 0x7F)
|
||||||
|
|
||||||
|
if (read and 0x80 == 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
read = read()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
fun RandomAccessFile.readASCIIString(length: Int): String {
|
fun RandomAccessFile.readASCIIString(length: Int): String {
|
||||||
require(length >= 0) { "Invalid length $length" }
|
require(length >= 0) { "Invalid length $length" }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user