Minor code improvement, with nicer JSON output for empty map

This commit is contained in:
Christian Basler 2017-11-30 07:41:54 +01:00
parent f1c7ad2afd
commit f1ecc8f767
2 changed files with 29 additions and 37 deletions

View File

@ -5,8 +5,6 @@ import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.util.*
import kotlin.collections.LinkedHashMap
/** /**
* Representation of a msgpack encoded map. It is recommended to use a [LinkedHashMap] to ensure the order * Representation of a msgpack encoded map. It is recommended to use a [LinkedHashMap] to ensure the order
@ -21,14 +19,18 @@ data class MPMap<K : MPType<*>, V : MPType<*>>(override val value: MutableMap<K,
@Throws(IOException::class) @Throws(IOException::class)
override fun pack(out: OutputStream) { override fun pack(out: OutputStream) {
val size = value.size val size = value.size
if (size < 16) { when {
out.write(0x80 + size) size < 16 -> {
} else if (size < 65536) { out.write(0x80 + size)
out.write(0xDE) }
out.write(ByteBuffer.allocate(2).putShort(size.toShort()).array()) size < 65536 -> {
} else { out.write(0xDE)
out.write(0xDF) out.write(ByteBuffer.allocate(2).putShort(size.toShort()).array())
out.write(ByteBuffer.allocate(4).putInt(size).array()) }
else -> {
out.write(0xDF)
out.write(ByteBuffer.allocate(4).putInt(size).array())
}
} }
for ((key, value1) in value) { for ((key, value1) in value) {
key.pack(out) key.pack(out)
@ -68,24 +70,15 @@ data class MPMap<K : MPType<*>, V : MPType<*>>(override val value: MutableMap<K,
override fun toString() = toJson() override fun toString() = toJson()
internal fun toJson(indent: String): String { internal fun toJson(indent: String) = if (value.entries.isEmpty()) {
val result = StringBuilder() "{}"
result.append("{\n") } else {
val iterator = value.entries.iterator() value.entries.joinToString(
val indent2 = indent + " " separator = ",\n",
while (iterator.hasNext()) { prefix = "{\n",
val item = iterator.next() postfix = "\n$indent}") { i ->
result.append(indent2) "$indent ${Utils.toJson(i.key, "$indent ")}: ${Utils.toJson(i.value, "$indent ")}"
result.append(Utils.toJson(item.key, indent2))
result.append(": ")
result.append(Utils.toJson(item.value, indent2))
if (iterator.hasNext()) {
result.append(',')
}
result.append('\n')
} }
result.append(indent).append("}")
return result.toString()
} }
override fun toJson(): String { override fun toJson(): String {
@ -100,15 +93,14 @@ data class MPMap<K : MPType<*>, V : MPType<*>>(override val value: MutableMap<K,
@Throws(IOException::class) @Throws(IOException::class)
override fun unpack(firstByte: Int, input: InputStream): MPMap<MPType<*>, MPType<*>> { override fun unpack(firstByte: Int, input: InputStream): MPMap<MPType<*>, MPType<*>> {
val size: Int val size: Int = when {
when { firstByte and 0xF0 == 0x80 -> firstByte and 0x0F
firstByte and 0xF0 == 0x80 -> size = firstByte and 0x0F firstByte == 0xDE -> input.read() shl 8 or input.read()
firstByte == 0xDE -> size = input.read() shl 8 or input.read() firstByte == 0xDF -> input.read() shl 24 or (input.read() shl 16) or (input.read() shl 8) or input.read()
firstByte == 0xDF -> size = input.read() shl 24 or (input.read() shl 16) or (input.read() shl 8) or input.read()
else -> throw IllegalArgumentException(String.format("Unexpected first byte 0x%02x", firstByte)) else -> throw IllegalArgumentException(String.format("Unexpected first byte 0x%02x", firstByte))
} }
val map = LinkedHashMap<MPType<*>, MPType<*>>() val map = LinkedHashMap<MPType<*>, MPType<*>>()
for (i in 0..size - 1) { for (i in 0 until size) {
val key = reader.read(input) val key = reader.read(input)
val value = reader.read(input) val value = reader.read(input)
map.put(key, value) map.put(key, value)

View File

@ -32,7 +32,7 @@ class ReaderTest {
fun `ensure demo json is parsed correctly`() { fun `ensure demo json is parsed correctly`() {
val read = Reader.read(stream("demo.mp")) val read = Reader.read(stream("demo.mp"))
assertThat(read, instanceOf(MPMap::class.java)) assertThat(read, instanceOf(MPMap::class.java))
assertThat(read.toString(), equalTo(string("demo.json"))) assertThat(read.toJson(), equalTo(string("demo.json")))
} }
@Test @Test
@ -63,7 +63,7 @@ class ReaderTest {
assertThat(read, instanceOf(MPArray::class.java)) assertThat(read, instanceOf(MPArray::class.java))
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
assertThat(read as MPArray<MPType<*>>, equalTo(array)) assertThat(read as MPArray<MPType<*>>, equalTo(array))
assertThat(read.toJson(), equalTo("[\n AQMDBw==,\n false,\n 3.141592653589793,\n 1.5,\n 42,\n {\n },\n null,\n \"yay! 🤓\"\n]")) assertThat(read.toJson(), equalTo("[\n AQMDBw==,\n false,\n 3.141592653589793,\n 1.5,\n 42,\n {},\n null,\n \"yay! 🤓\"\n]"))
} }
@Test @Test
@ -222,7 +222,7 @@ class ReaderTest {
private fun ensureMapIsEncodedAndDecodedCorrectly(size: Int) { private fun ensureMapIsEncodedAndDecodedCorrectly(size: Int) {
val nil = MPNil val nil = MPNil
val map = HashMap<MPInteger, MPNil>(size) val map = HashMap<MPInteger, MPNil>(size)
for (i in 0..size - 1) { for (i in 0 until size) {
map.put(i.mp, nil) map.put(i.mp, nil)
} }
val value = MPMap(map) val value = MPMap(map)
@ -236,7 +236,7 @@ class ReaderTest {
private fun stringWithLength(length: Int): String { private fun stringWithLength(length: Int): String {
val result = StringBuilder(length) val result = StringBuilder(length)
for (i in 0..length - 1) { for (i in 0 until length) {
result.append('a') result.append('a')
} }
return result.toString() return result.toString()