From c7a51842078d38e8f9748cab16084b5656f4c42d Mon Sep 17 00:00:00 2001 From: Matthew Nelson Date: Tue, 9 Dec 2025 18:00:02 -0500 Subject: [PATCH] Add MalformedEncodingException type --- .../matthewnelson/encoding/base16/Base16.kt | 6 +- .../matthewnelson/encoding/base32/Base32.kt | 23 +++---- .../encoding/base32/internal/-Config.kt | 2 + .../matthewnelson/encoding/base64/Base64.kt | 6 +- library/core/api/core.api | 5 ++ library/core/api/core.klib.api | 5 ++ .../io/matthewnelson/encoding/core/Decoder.kt | 4 +- .../encoding/core/EncoderDecoder.kt | 7 ++- .../matthewnelson/encoding/core/Exceptions.kt | 26 ++++++++ .../encoding/core/util/FeedBuffer.kt | 8 ++- .../io/matthewnelson/encoding/utf8/UTF8.kt | 62 +++++++++---------- 11 files changed, 97 insertions(+), 57 deletions(-) diff --git a/library/base16/src/commonMain/kotlin/io/matthewnelson/encoding/base16/Base16.kt b/library/base16/src/commonMain/kotlin/io/matthewnelson/encoding/base16/Base16.kt index 96db7b68..bcbf693c 100644 --- a/library/base16/src/commonMain/kotlin/io/matthewnelson/encoding/base16/Base16.kt +++ b/library/base16/src/commonMain/kotlin/io/matthewnelson/encoding/base16/Base16.kt @@ -21,7 +21,7 @@ import io.matthewnelson.encoding.base16.internal.build import io.matthewnelson.encoding.core.Decoder import io.matthewnelson.encoding.core.Encoder import io.matthewnelson.encoding.core.EncoderDecoder -import io.matthewnelson.encoding.core.EncodingException +import io.matthewnelson.encoding.core.MalformedEncodingException import io.matthewnelson.encoding.core.util.DecoderInput import io.matthewnelson.encoding.core.util.FeedBuffer import kotlin.contracts.ExperimentalContracts @@ -102,7 +102,7 @@ public class Base16: EncoderDecoder { * allowed but ignored) during decoding operations. This is non-compliant with * `RFC 4648`. * - * If `false`, an [EncodingException] will be thrown. + * If `false`, a [MalformedEncodingException] will be thrown. * */ public fun isLenient(enable: Boolean): Builder = apply { _isLenient = enable } @@ -367,7 +367,7 @@ public class Base16: EncoderDecoder { diff += if (gea + lef == 2) -87 else 0 if (diff == 0) { - throw EncodingException("Char[${input}] is not a valid Base16 character") + throw MalformedEncodingException("Char[${input}] is not a valid $NAME character") } if (!hasBuffered) { diff --git a/library/base32/src/commonMain/kotlin/io/matthewnelson/encoding/base32/Base32.kt b/library/base32/src/commonMain/kotlin/io/matthewnelson/encoding/base32/Base32.kt index 6511388a..c905a8ad 100644 --- a/library/base32/src/commonMain/kotlin/io/matthewnelson/encoding/base32/Base32.kt +++ b/library/base32/src/commonMain/kotlin/io/matthewnelson/encoding/base32/Base32.kt @@ -26,6 +26,7 @@ import io.matthewnelson.encoding.core.Decoder import io.matthewnelson.encoding.core.Encoder import io.matthewnelson.encoding.core.EncoderDecoder import io.matthewnelson.encoding.core.EncodingException +import io.matthewnelson.encoding.core.MalformedEncodingException import io.matthewnelson.encoding.core.util.DecoderInput import io.matthewnelson.encoding.core.util.FeedBuffer import io.matthewnelson.encoding.core.util.LineBreakOutFeed @@ -122,7 +123,7 @@ public sealed class Base32(config: C): EncoderDecoder< * allowed but ignored) during decoding operations. This is non-compliant with * the Crockford spec. * - * If `false`, an [EncodingException] will be thrown. + * If `false`, a [MalformedEncodingException] will be thrown. * */ public fun isLenient(enable: Boolean): Builder = apply { _isLenient = enable } @@ -260,7 +261,7 @@ public sealed class Base32(config: C): EncoderDecoder< } else { "Missing check symbol. Expected[$checkSymbol]" } - throw EncodingException(msg) + throw MalformedEncodingException(msg) } else { outSize-- } @@ -525,7 +526,7 @@ public sealed class Base32(config: C): EncoderDecoder< * allowed but ignored) during decoding operations. This is non-compliant with * `RFC 4648`. * - * If `false`, an [EncodingException] will be thrown. + * If `false`, a [MalformedEncodingException] will be thrown. * */ public fun isLenient(enable: Boolean): Builder = apply { _isLenient = enable } @@ -866,7 +867,7 @@ public sealed class Base32(config: C): EncoderDecoder< * allowed but ignored) during decoding operations. This is non-compliant with * `RFC 4648`. * - * If `false`, an [EncodingException] will be thrown. + * If `false`, a [MalformedEncodingException] will be thrown. * */ public fun isLenient(enable: Boolean): Builder = apply { _isLenient = enable } @@ -1143,7 +1144,7 @@ public sealed class Base32(config: C): EncoderDecoder< val code = input.code val diff = code.decodeDiff() if (diff == 0) { - throw Diff0EncodingException("Char[$input] is not a valid Base32 character") + throw MalformedEncodingException("Char[$input] is not a valid ${name()} character") } if (iBuf < 7) { @@ -1463,7 +1464,7 @@ public sealed class Base32(config: C): EncoderDecoder< if (isCheckSymbolSet) { // If the set checkSymbol was not intended, it's only valid as the // very last character and the previous update call was invalid. - throw EncodingException("CheckSymbol[${_config.checkSymbol}] was set") + throw MalformedEncodingException("CheckSymbol[${_config.checkSymbol}] was set") } // Crockford allows for insertion of hyphens, which are to be ignored. @@ -1472,7 +1473,7 @@ public sealed class Base32(config: C): EncoderDecoder< try { super.consumeProtected(input) hadInput = true - } catch (e: Diff0EncodingException) { + } catch (e: MalformedEncodingException) { // decodeDiff returned 0. See if it's a check symbol. if (!input.isCheckSymbol()) throw e @@ -1483,14 +1484,14 @@ public sealed class Base32(config: C): EncoderDecoder< } // Have the wrong check symbol - throw EncodingException("Char[$input] IS a check symbol, but did not match config's CheckSymbol[${_config.checkSymbol}]", e) + throw MalformedEncodingException("Char[$input] IS a check symbol, but did not match config's CheckSymbol[${_config.checkSymbol}]", e) } } override fun doFinalProtected() { if (isClosed() || _config.finalizeWhenFlushed) { if (hadInput && _config.checkSymbol != null && !isCheckSymbolSet) { - throw EncodingException("Missing check symbol. Expected[${_config.checkSymbol}]") + throw MalformedEncodingException("Missing check symbol. Expected[${_config.checkSymbol}]") } isCheckSymbolSet = false hadInput = false @@ -1559,10 +1560,6 @@ public sealed class Base32(config: C): EncoderDecoder< } } - // Thrown by AbstractDecoderFeed when decodeDiff returns 0. - // Is for Crockford in order to check input for a check symbol. - private class Diff0EncodingException(message: String): EncodingException(message) - private class HyphenOutFeed( private val interval: Byte, private val out: Encoder.OutFeed, diff --git a/library/base32/src/commonMain/kotlin/io/matthewnelson/encoding/base32/internal/-Config.kt b/library/base32/src/commonMain/kotlin/io/matthewnelson/encoding/base32/internal/-Config.kt index b88cfe98..560a43ce 100644 --- a/library/base32/src/commonMain/kotlin/io/matthewnelson/encoding/base32/internal/-Config.kt +++ b/library/base32/src/commonMain/kotlin/io/matthewnelson/encoding/base32/internal/-Config.kt @@ -19,6 +19,7 @@ package io.matthewnelson.encoding.base32.internal import io.matthewnelson.encoding.base32.Base32 import io.matthewnelson.encoding.core.EncoderDecoder +import io.matthewnelson.encoding.core.EncodingSizeException internal inline fun ((Boolean, Boolean, Byte, Char?, Boolean, Boolean) -> Base32.Crockford.Config).build( b: Base32.Crockford.Builder, @@ -110,6 +111,7 @@ internal inline fun EncoderDecoder.Config.Companion.decodeOutMaxSize32(encodedSi return (encodedSize.toLong() * 5L / 8L).toInt() } +@Throws(EncodingSizeException::class) internal inline fun EncoderDecoder.Config.Companion.encodeOutSize64(unEncodedSize: Long, willBePadded: Boolean): Long { if (unEncodedSize > MAX_UNENCODED_SIZE) { throw outSizeExceedsMaxEncodingSizeException(unEncodedSize, Long.MAX_VALUE) diff --git a/library/base64/src/commonMain/kotlin/io/matthewnelson/encoding/base64/Base64.kt b/library/base64/src/commonMain/kotlin/io/matthewnelson/encoding/base64/Base64.kt index 369c1af7..2367fa61 100644 --- a/library/base64/src/commonMain/kotlin/io/matthewnelson/encoding/base64/Base64.kt +++ b/library/base64/src/commonMain/kotlin/io/matthewnelson/encoding/base64/Base64.kt @@ -21,7 +21,7 @@ import io.matthewnelson.encoding.base64.internal.build import io.matthewnelson.encoding.core.Decoder import io.matthewnelson.encoding.core.Encoder import io.matthewnelson.encoding.core.EncoderDecoder -import io.matthewnelson.encoding.core.EncodingException +import io.matthewnelson.encoding.core.MalformedEncodingException import io.matthewnelson.encoding.core.util.DecoderInput import io.matthewnelson.encoding.core.util.FeedBuffer import kotlin.contracts.ExperimentalContracts @@ -142,7 +142,7 @@ public class Base64: EncoderDecoder { * allowed but ignored) during decoding operations. This is non-compliant with * `RFC 4648`. * - * If `false`, an [EncodingException] will be thrown. + * If `false`, a [MalformedEncodingException] will be thrown. * */ public fun isLenient(enable: Boolean): Builder = apply { _isLenient = enable } @@ -456,7 +456,7 @@ public class Base64: EncoderDecoder { diff += if (eqSla + eqUSc == 1) k else 0 if (diff == 0) { - throw EncodingException("Char[$input] is not a valid Base64 character") + throw MalformedEncodingException("Char[$input] is not a valid $NAME character") } if (iBuf < 3) { diff --git a/library/core/api/core.api b/library/core/api/core.api index c47dc7f5..395c630a 100644 --- a/library/core/api/core.api +++ b/library/core/api/core.api @@ -180,6 +180,11 @@ public class io/matthewnelson/encoding/core/EncodingSizeException : io/matthewne public abstract interface annotation class io/matthewnelson/encoding/core/ExperimentalEncodingApi : java/lang/annotation/Annotation { } +public class io/matthewnelson/encoding/core/MalformedEncodingException : io/matthewnelson/encoding/core/EncodingException { + public fun (Ljava/lang/String;)V + public fun (Ljava/lang/String;Ljava/lang/Throwable;)V +} + public final class io/matthewnelson/encoding/core/_FeedKt { public static final fun use (Lio/matthewnelson/encoding/core/EncoderDecoder$Feed;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static final fun useFinally (Lio/matthewnelson/encoding/core/EncoderDecoder$Feed;Ljava/lang/Throwable;)V diff --git a/library/core/api/core.klib.api b/library/core/api/core.klib.api index 6924db4b..81e95cf3 100644 --- a/library/core/api/core.klib.api +++ b/library/core/api/core.klib.api @@ -175,6 +175,11 @@ open class io.matthewnelson.encoding.core/EncodingSizeException : io.matthewnels constructor (kotlin/String, kotlin/Throwable?) // io.matthewnelson.encoding.core/EncodingSizeException.|(kotlin.String;kotlin.Throwable?){}[0] } +open class io.matthewnelson.encoding.core/MalformedEncodingException : io.matthewnelson.encoding.core/EncodingException { // io.matthewnelson.encoding.core/MalformedEncodingException|null[0] + constructor (kotlin/String) // io.matthewnelson.encoding.core/MalformedEncodingException.|(kotlin.String){}[0] + constructor (kotlin/String, kotlin/Throwable?) // io.matthewnelson.encoding.core/MalformedEncodingException.|(kotlin.String;kotlin.Throwable?){}[0] +} + sealed class <#A: io.matthewnelson.encoding.core/EncoderDecoder.Config> io.matthewnelson.encoding.core/Decoder { // io.matthewnelson.encoding.core/Decoder|null[0] final val config // io.matthewnelson.encoding.core/Decoder.config|{}config[0] final fun (): #A // io.matthewnelson.encoding.core/Decoder.config.|(){}[0] diff --git a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Decoder.kt b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Decoder.kt index 26409641..0f1f54b8 100644 --- a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Decoder.kt +++ b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Decoder.kt @@ -118,7 +118,7 @@ public sealed class Decoder(public val config: C) { if (config.isLenient) { return } else { - throw EncodingException("Spaces and new lines are forbidden when isLenient[false]") + throw MalformedEncodingException("Spaces and new lines are forbidden when isLenient[false]") } } @@ -132,7 +132,7 @@ public sealed class Decoder(public val config: C) { if (_isPaddingSet) { // Trying to decode something else that is not // a space, new line, or padding. Fail. - throw EncodingException( + throw MalformedEncodingException( "Padding[${config.paddingChar}] was previously passed, " + "but decoding operations are still being attempted." ) diff --git a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/EncoderDecoder.kt b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/EncoderDecoder.kt index 3cb304d8..46fe6c58 100644 --- a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/EncoderDecoder.kt +++ b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/EncoderDecoder.kt @@ -51,7 +51,7 @@ public abstract class EncoderDecoder(config: C): Encod /** * If `true`, the characters ('\n', '\r', ' ', '\t') will be skipped over (i.e. - * allowed but ignored) during decoding operations. If `false`, an [EncodingException] + * allowed but ignored) during decoding operations. If `false`, a [MalformedEncodingException] * will be thrown when those characters are encountered. If `null`, those characters * are passed along to the [Decoder.Feed] implementation as input. * */ @@ -85,7 +85,8 @@ public abstract class EncoderDecoder(config: C): Encod /** * The character that is used when padding encoded output. This is used by [Decoder.Feed] * to mark input as "completing" such that further non-padding input can be exceptionally - * rejected. If the encoding specification does not use padding, `null` may be specified. + * rejected with a [MalformedEncodingException]. If the encoding specification does not + * use padding, `null` may be specified. * * **NOTE:** [Decoder.Feed] will not pass along padding characters to the [Decoder.Feed] * implementation; they will be automatically dropped. If this is undesirable, consider @@ -312,7 +313,7 @@ public abstract class EncoderDecoder(config: C): Encod lastRelevantChar-- continue } else { - throw EncodingException("Spaces and new lines are forbidden when isLenient[false]") + throw MalformedEncodingException("Spaces and new lines are forbidden when isLenient[false]") } } diff --git a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Exceptions.kt b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Exceptions.kt index 5a639d08..0cea507c 100644 --- a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Exceptions.kt +++ b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Exceptions.kt @@ -15,6 +15,15 @@ **/ package io.matthewnelson.encoding.core +import io.matthewnelson.encoding.core.util.FeedBuffer + +/** + * The `EncodingException` class is a generic encoding exception class that provide + * type safety for all the encoding related exception classes that extend from it. + * + * @see [EncodingSizeException] + * @see [MalformedEncodingException] + * */ public open class EncodingException: RuntimeException { final override val message: String @@ -25,7 +34,24 @@ public open class EncodingException: RuntimeException { } } +/** + * This exception is thrown to indicate that an [EncoderDecoder.Config] pre-calculation + * step for an operation failed. + * + * @see [EncoderDecoder.Config.outSizeExceedsMaxEncodingSizeException] + * */ public open class EncodingSizeException: EncodingException { public constructor(message: String): this(message, null) public constructor(message: String, cause: Throwable?): super(message, cause) } + +/** + * This exception is thrown to indicate an encoding/decoding operation failed due to + * malformed input, such as an invalid character or byte sequence. + * + * @see [FeedBuffer.truncatedInputEncodingException] + * */ +public open class MalformedEncodingException: EncodingException { + public constructor(message: String): this(message, null) + public constructor(message: String, cause: Throwable?): super(message, cause) +} diff --git a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/util/FeedBuffer.kt b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/util/FeedBuffer.kt index 519b1496..1aa87bb7 100644 --- a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/util/FeedBuffer.kt +++ b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/util/FeedBuffer.kt @@ -20,6 +20,7 @@ package io.matthewnelson.encoding.core.util import io.matthewnelson.encoding.core.Decoder import io.matthewnelson.encoding.core.Encoder import io.matthewnelson.encoding.core.EncodingException +import io.matthewnelson.encoding.core.MalformedEncodingException import kotlin.jvm.JvmField import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic @@ -29,6 +30,9 @@ import kotlin.jvm.JvmStatic * buffer their input until ready to output data via their * supplied [Decoder.OutFeed]/[Encoder.OutFeed]. * + * **NOTE:** This adds significant overhead to operations. + * It is far better, performance wise, to not use. + * * @see [Flush] * @see [Finalize] * @see [truncatedInputEncodingException] @@ -104,12 +108,12 @@ constructor( public companion object { /** - * Helper for generating a standard [EncodingException] when + * Helper for generating a standard [MalformedEncodingException] when * an illegal modulus is encountered while decoding. * */ @JvmStatic public fun truncatedInputEncodingException(modulus: Int): EncodingException { - return EncodingException("Truncated input. Illegal Modulus[$modulus]") + return MalformedEncodingException("Truncated input. Illegal Modulus[$modulus]") } } } diff --git a/library/utf8/src/commonMain/kotlin/io/matthewnelson/encoding/utf8/UTF8.kt b/library/utf8/src/commonMain/kotlin/io/matthewnelson/encoding/utf8/UTF8.kt index f9b5b826..68be17a5 100644 --- a/library/utf8/src/commonMain/kotlin/io/matthewnelson/encoding/utf8/UTF8.kt +++ b/library/utf8/src/commonMain/kotlin/io/matthewnelson/encoding/utf8/UTF8.kt @@ -20,7 +20,7 @@ package io.matthewnelson.encoding.utf8 import io.matthewnelson.encoding.core.Decoder import io.matthewnelson.encoding.core.Encoder import io.matthewnelson.encoding.core.EncoderDecoder -import io.matthewnelson.encoding.core.EncodingException +import io.matthewnelson.encoding.core.MalformedEncodingException import io.matthewnelson.encoding.core.util.DecoderInput import io.matthewnelson.encoding.utf8.internal.build import io.matthewnelson.encoding.utf8.internal.initializeKotlin @@ -207,8 +207,8 @@ public open class UTF8: EncoderDecoder { public val KOTLIN: ReplacementStrategy = initializeKotlin(U_003F, U_FFFD) /** - * A strategy which will throw an exception when any invalid sequence is encountered during - * text to UTF-8 byte, or UTF-8 byte to text transformations. + * A strategy which will throw a [MalformedEncodingException] when any invalid sequence is + * encountered during text to UTF-8 byte, or UTF-8 byte to text transformations. * * @see [ThrowOnInvalid] * */ @@ -323,7 +323,7 @@ public open class UTF8: EncoderDecoder { override fun replacementSize(): Int { currentSize = 0L checkNext = false - throw EncodingException("Malformed UTF-8 character sequence") + throw MalformedEncodingException("Malformed UTF-8 character sequence") } } else -> CharPreProcessor(strategy) @@ -333,8 +333,8 @@ public open class UTF8: EncoderDecoder { * Calculate the UTF-8 byte output size for the provided array and [ReplacementStrategy] for the * [UTF8] encoder/decoder. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ @JvmStatic @JvmName("sizeOf") @@ -344,8 +344,8 @@ public open class UTF8: EncoderDecoder { * Calculate the UTF-8 byte output size for the provided array and [ReplacementStrategy] for the * [UTF8.Config]. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ @JvmStatic @JvmName("sizeOf") @@ -354,8 +354,8 @@ public open class UTF8: EncoderDecoder { /** * Calculate the UTF-8 byte output size for the provided array and [ReplacementStrategy]. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ @JvmStatic @JvmName("sizeOf") @@ -369,8 +369,8 @@ public open class UTF8: EncoderDecoder { * Calculate the UTF-8 byte output size for the provided characters and [ReplacementStrategy] for the * [UTF8] encoder/decoder. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ @JvmStatic @JvmName("sizeOf") @@ -380,8 +380,8 @@ public open class UTF8: EncoderDecoder { * Calculate the UTF-8 byte output size for the provided characters and [ReplacementStrategy] for the * [UTF8.Config]. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ @JvmStatic @JvmName("sizeOf") @@ -390,8 +390,8 @@ public open class UTF8: EncoderDecoder { /** * Calculate the UTF-8 byte output size for the provided characters and [ReplacementStrategy]. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ @JvmStatic @JvmName("sizeOf") @@ -405,8 +405,8 @@ public open class UTF8: EncoderDecoder { * Calculate the UTF-8 byte output size for the provided characters and [ReplacementStrategy] for the * [UTF8] encoder/decoder. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ @JvmStatic @JvmName("sizeOf") @@ -416,8 +416,8 @@ public open class UTF8: EncoderDecoder { * Calculate the UTF-8 byte output size for the provided characters and [ReplacementStrategy] for the * [UTF8.Config]. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ @JvmStatic @JvmName("sizeOf") @@ -426,8 +426,8 @@ public open class UTF8: EncoderDecoder { /** * Calculate the UTF-8 byte output size for the provided characters and [ReplacementStrategy]. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ @JvmStatic @JvmName("sizeOf") @@ -452,8 +452,8 @@ public open class UTF8: EncoderDecoder { /** * Add input. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ public operator fun plus(input: Char) { val c = input.code @@ -481,8 +481,8 @@ public open class UTF8: EncoderDecoder { /** * Resets the [CharPreProcessor] and returns the final UTF-8 byte size of all accumulated input. * - * @throws [EncodingException] If an invalid character sequence is encountered and the [strategy] - * is [ReplacementStrategy.THROW]. + * @throws [MalformedEncodingException] If an invalid character sequence is encountered and the + * [strategy] is [ReplacementStrategy.THROW]. * */ public fun doFinal(): Long { val s = currentSize @@ -492,7 +492,7 @@ public open class UTF8: EncoderDecoder { return s + replacementSize() } - @Throws(EncodingException::class) + @Throws(MalformedEncodingException::class) protected open fun replacementSize(): Int = strategy.size private inline fun Int.process(): Boolean { @@ -536,7 +536,7 @@ public open class UTF8: EncoderDecoder { } ReplacementStrategy.THROW.size -> object : DecoderFeed(out) { override fun Decoder.OutFeed.outputReplacementSequence() { - throw EncodingException("Malformed UTF-8 character sequence") + throw MalformedEncodingException("Malformed UTF-8 character sequence") } } // "Should" never make it here... @@ -549,7 +549,7 @@ public open class UTF8: EncoderDecoder { return when (config.replacementStrategy.size) { ReplacementStrategy.THROW.size -> object : EncoderFeed(out) { override fun Encoder.OutFeed.outputReplacementChar() { - throw EncodingException("Malformed UTF-8 character sequence") + throw MalformedEncodingException("Malformed UTF-8 character sequence") } } else -> EncoderFeed(out) @@ -559,7 +559,7 @@ public open class UTF8: EncoderDecoder { // Chars -> Bytes private abstract inner class DecoderFeed(out: Decoder.OutFeed): Decoder.Feed(_out = out) { - @Throws(EncodingException::class) + @Throws(MalformedEncodingException::class) protected abstract fun Decoder.OutFeed.outputReplacementSequence() private var buf = 0 @@ -627,7 +627,7 @@ public open class UTF8: EncoderDecoder { // Bytes -> Chars private open inner class EncoderFeed(out: Encoder.OutFeed): Encoder.Feed(_out = out) { - @Throws(EncodingException::class) + @Throws(MalformedEncodingException::class) protected open fun Encoder.OutFeed.outputReplacementChar() { output('\ufffd') }