Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -102,7 +102,7 @@ public class Base16: EncoderDecoder<Base16.Config> {
* 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 }

Expand Down Expand Up @@ -367,7 +367,7 @@ public class Base16: EncoderDecoder<Base16.Config> {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -122,7 +123,7 @@ public sealed class Base32<C: EncoderDecoder.Config>(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 }

Expand Down Expand Up @@ -260,7 +261,7 @@ public sealed class Base32<C: EncoderDecoder.Config>(config: C): EncoderDecoder<
} else {
"Missing check symbol. Expected[$checkSymbol]"
}
throw EncodingException(msg)
throw MalformedEncodingException(msg)
} else {
outSize--
}
Expand Down Expand Up @@ -525,7 +526,7 @@ public sealed class Base32<C: EncoderDecoder.Config>(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 }

Expand Down Expand Up @@ -866,7 +867,7 @@ public sealed class Base32<C: EncoderDecoder.Config>(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 }

Expand Down Expand Up @@ -1143,7 +1144,7 @@ public sealed class Base32<C: EncoderDecoder.Config>(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) {
Expand Down Expand Up @@ -1463,7 +1464,7 @@ public sealed class Base32<C: EncoderDecoder.Config>(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.
Expand All @@ -1472,7 +1473,7 @@ public sealed class Base32<C: EncoderDecoder.Config>(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

Expand All @@ -1483,14 +1484,14 @@ public sealed class Base32<C: EncoderDecoder.Config>(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
Expand Down Expand Up @@ -1559,10 +1560,6 @@ public sealed class Base32<C: EncoderDecoder.Config>(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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -142,7 +142,7 @@ public class Base64: EncoderDecoder<Base64.Config> {
* 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 }

Expand Down Expand Up @@ -456,7 +456,7 @@ public class Base64: EncoderDecoder<Base64.Config> {
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) {
Expand Down
5 changes: 5 additions & 0 deletions library/core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -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 <init> (Ljava/lang/String;)V
public fun <init> (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
Expand Down
5 changes: 5 additions & 0 deletions library/core/api/core.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ open class io.matthewnelson.encoding.core/EncodingSizeException : io.matthewnels
constructor <init>(kotlin/String, kotlin/Throwable?) // io.matthewnelson.encoding.core/EncodingSizeException.<init>|<init>(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 <init>(kotlin/String) // io.matthewnelson.encoding.core/MalformedEncodingException.<init>|<init>(kotlin.String){}[0]
constructor <init>(kotlin/String, kotlin/Throwable?) // io.matthewnelson.encoding.core/MalformedEncodingException.<init>|<init>(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 <get-config>(): #A // io.matthewnelson.encoding.core/Decoder.config.<get-config>|<get-config>(){}[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public sealed class Decoder<C: EncoderDecoder.Config>(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]")
}
}

Expand All @@ -132,7 +132,7 @@ public sealed class Decoder<C: EncoderDecoder.Config>(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."
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public abstract class EncoderDecoder<C: EncoderDecoder.Config>(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.
* */
Expand Down Expand Up @@ -85,7 +85,8 @@ public abstract class EncoderDecoder<C: EncoderDecoder.Config>(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
Expand Down Expand Up @@ -312,7 +313,7 @@ public abstract class EncoderDecoder<C: EncoderDecoder.Config>(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]")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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]
Expand Down Expand Up @@ -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]")
}
}
}
Loading