Coverage Summary for Class: GhostJsonReaderCaptureKt (com.ghost.serialization.parser)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| GhostJsonReaderCaptureKt |
100%
(1/1)
|
100%
(5/5)
|
60%
(21/35)
|
91.4%
(32/35)
|
79.4%
(158/199)
|
@file:OptIn(InternalGhostApi::class)
package com.ghost.serialization.parser
import com.ghost.serialization.InternalGhostApi
import com.ghost.serialization.parser.GhostJsonConstants as C
import com.ghost.serialization.types.RawJson
/**
* Captures the next complete JSON value as a [RawJson] view into this reader's buffer.
*/
fun GhostJsonReader.captureRawJson(): RawJson {
skipWhitespace()
val start = position
captureReaderValueBytes()
nextTokenByte = -1
val length = position - start
return if (isStreaming) {
RawJson.fromUtf8Bytes(captureReaderRangeBytes(start, length))
} else {
RawJson.fromBufferSlice(rawData, start, length)
}
}
/**
* Captures the next complete JSON value as a raw [ByteArray] without decoding.
*
* Same semantics as [GhostJsonFlatReader.captureRawJsonBytes] but operates on the
* [GhostJsonReader] (non-flat) byte-array source. The reader must be positioned at
* (or before) the first non-whitespace byte of the value.
*/
fun GhostJsonReader.captureRawJsonBytes(): ByteArray = captureRawJson().bytes
private fun GhostJsonReader.captureReaderValueBytes() {
val localLimit = limit
val first = getByte(position++)
when (first) {
C.OPEN_OBJ_INT, C.OPEN_ARR_INT -> {
var depth = 1
while (position < localLimit && depth > 0) {
when (getByte(position++)) {
C.QUOTE_INT -> captureReaderSkipStringBytes(localLimit)
C.OPEN_OBJ_INT, C.OPEN_ARR_INT -> depth++
C.CLOSE_OBJ_INT, C.CLOSE_ARR_INT -> depth--
}
}
}
C.QUOTE_INT -> captureReaderSkipStringBytes(localLimit)
C.TRUE_CHAR_INT -> position += 3
C.FALSE_CHAR_INT -> position += 4
C.NULL_CHAR_INT -> position += 3
else -> {
while (position < localLimit) {
val b = getByte(position)
if (b == C.COMMA_INT || b == C.CLOSE_OBJ_INT || b == C.CLOSE_ARR_INT || b <= C.SPACE_INT) break
position++
}
}
}
}
private fun GhostJsonReader.captureReaderSkipStringBytes(localLimit: Int) {
while (position < localLimit) {
when (getByte(position++)) {
C.QUOTE_INT -> return
C.BACKSLASH_INT -> if (position < localLimit) position++
}
}
}
private fun GhostJsonReader.captureReaderRangeBytes(start: Int, length: Int): ByteArray {
val result = ByteArray(length)
var index = 0
while (index < length) {
result[index] = getByte(start + index).toByte()
index++
}
return result
}