Coverage Summary for Class: ProtoJsonFlatReaderBase64Kt (com.ghost.serialization.parser)

Class Class, % Method, % Branch, % Line, % Instruction, %
ProtoJsonFlatReaderBase64Kt 100% (1/1) 100% (1/1) 37% (17/46) 70.3% (26/37) 59.7% (163/273)


 @file:OptIn(InternalGhostApi::class)
 
 package com.ghost.serialization.parser
 
 import com.ghost.serialization.InternalGhostApi
 import com.ghost.serialization.acquireScratchBuffer
 import com.ghost.serialization.releaseScratchBuffer
 import com.ghost.serialization.parser.GhostJsonConstants as C
 
 internal fun GhostProtoJsonFlatReader.readProtoBytes(): ByteArray {
     val decodedString = readQuotedString()
     val lut = C.BASE64_LUT
     val length = decodedString.length
     
     val outputBuffer = acquireScratchBuffer(length)
     var outputPosition = 0
     val chunk = IntArray(4)
     var chunkIndex = 0
     
     try {
         for (charIndex in 0 until length) {
             val byteCode = decodedString[charIndex].code
             if (byteCode <= C.SPACE_INT) continue
             chunk[chunkIndex++] = byteCode
             if (chunkIndex == 4) {
                 // Chars outside the LUT's range (any non-Latin-1 code unit) are never valid
                 // base64 alphabet members — bounds-check rather than indexing lut[] directly,
                 // since a raw index would throw ArrayIndexOutOfBoundsException instead of the
                 // documented parse error.
                 val value0 = if (chunk[0] < lut.size) lut[chunk[0]] else -1
                 val value1 = if (chunk[1] < lut.size) lut[chunk[1]] else -1
                 val value2 = if (chunk[2] < lut.size) lut[chunk[2]] else -1
                 val value3 = if (chunk[3] < lut.size) lut[chunk[3]] else -1
 
                 if (value0 < 0 || value1 < 0 || value2 == -1 || value3 == -1) {
                     throwError(C.ERR_INVALID_BASE64)
                 }
                 outputBuffer[outputPosition++] = ((value0 shl 2) or (value1 ushr 4)).toByte()
                 if (value2 != -2) {
                     outputBuffer[outputPosition++] = ((value1 shl 4) or (value2 ushr 2)).toByte()
                     if (value3 != -2) {
                         outputBuffer[outputPosition++] = ((value2 shl 6) or value3).toByte()
                     }
                 }
                 chunkIndex = 0
             }
         }
         
         if (chunkIndex > 0) {
             while (chunkIndex < 4) {
                 chunk[chunkIndex++] = C.EQUALS_INT
             }
             val value0 = if (chunk[0] < lut.size) lut[chunk[0]] else -1
             val value1 = if (chunk[1] < lut.size) lut[chunk[1]] else -1
             val value2 = if (chunk[2] < lut.size) lut[chunk[2]] else -1
             val value3 = if (chunk[3] < lut.size) lut[chunk[3]] else -1
 
             if (value0 >= 0 && value1 >= 0) {
                 outputBuffer[outputPosition++] = ((value0 shl 2) or (value1 ushr 4)).toByte()
                 if (value2 != -2 && value2 >= 0) {
                     outputBuffer[outputPosition++] = ((value1 shl 4) or (value2 ushr 2)).toByte()
                 }
             }
         }
         
         return outputBuffer.copyOf(outputPosition)
     } finally {
         releaseScratchBuffer(outputBuffer)
     }
 }