Added some variants to readers
This commit is contained in:
parent
a3282098b1
commit
66d7a267b2
@ -1,10 +1,12 @@
|
||||
package ru.dbotthepony.kstarbound.io
|
||||
|
||||
import com.google.gson.*
|
||||
import java.io.DataInputStream
|
||||
import java.io.InputStream
|
||||
import java.io.RandomAccessFile
|
||||
|
||||
/**
|
||||
* Интерфейс для чтения и записи двоичного формата Json от Chucklefish
|
||||
* Represents interface to read binary json format by Chucklefish
|
||||
*/
|
||||
object BinaryJson {
|
||||
const val TYPE_NULL = 0x01
|
||||
@ -25,7 +27,40 @@ object BinaryJson {
|
||||
TYPE_NULL -> JsonNull.INSTANCE
|
||||
TYPE_DOUBLE -> JsonPrimitive(reader.readDouble())
|
||||
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_ARRAY -> readArray(reader)
|
||||
TYPE_OBJECT -> readObject(reader)
|
||||
@ -65,6 +100,38 @@ object BinaryJson {
|
||||
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 {
|
||||
val values = reader.readVarInt() - 1
|
||||
|
||||
@ -84,4 +151,24 @@ object BinaryJson {
|
||||
|
||||
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
|
||||
|
||||
import java.io.DataInputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.RandomAccessFile
|
||||
@ -44,6 +45,46 @@ fun RandomAccessFile.readVarInt(): Int {
|
||||
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 {
|
||||
require(length >= 0) { "Invalid length $length" }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user