05nelsonm / encoding

A Kotlin Multiplatform library for configurable, streamable, efficient and extensible Encoding/Decoding with support for base16/32/64.
Apache License 2.0
33 stars 5 forks source link

`DeocderInput` should not call `EncoderDecoder.Config.decodeOutMaxSizeOrFail` #61

Closed 05nelsonm closed 1 year ago

05nelsonm commented 1 year ago

Currently the DecoderInput utility class takes in an EncoderDecoder.Config and calls it's decodeOutMaxSizeOrFail method from the DecoderInput.init block.

This should be a separate step. The EncoderDecoder.Config should have 4 methods:

public class DecoderInput private constructor(private val input: Any, internal val size: Int) {

    @Throws(EncodingException::class)
    public operator fun get(index: Int): Char get() {
        try {
            when (input) {
                is CharSequence -> input[index]
                is CharArray -> input[index]
                is ByteArray -> input[index].char
            }
        } catch (e: IndexOutOfBoundsException) {
            throw EncodingException("Index out of bounds", e)
        }
    }
}
public sealed class EncoderDecoder(config: Config): Encoder(config) {

    // ...

    public abstract class Config(
        @JvmField
        isLenient: Boolean?,
        @JvmField
        paddingByte: Byte?,
    ) {
        @Throws(EncodingException::class)
        protected abstract decodeOutMaxSizeOrFailProtected(lastRelevantCharacter: Int, input: DecoderInput): Int

        @Throws(EncodingException::class)
        public fun decodeOutMaxSizeOrFail(input: DecoderInput): Int {
            var lastRelevantChar = input.size
            while (size > 0) {
                val c = input[lastRelevantChar - 1]

                if (isLenient != null && c.isSpaceOrNewLine) {
                    if (isLenient) {
                        lastRelevantChar--
                        continue
                    } else {
                        throw EncodingException("...")
                    }
                }

                if (c.byte == paddingByte) {
                    lastRelevantChar--
                    continue
                }

                break
            }

            if (lastRelevantChar == 0) return 0
            val maxSize = decodeOutMaxSizeOrFailProtected(lastRelevantChar, input)
            if (maxSize < 0) throw EncodingSizeException("...")
            return maxSize
        }

        // ...

    }

    // ...
}