Class Codecs

java.lang.Object
io.bytestreams.codec.core.Codecs

public class Codecs extends Object
Unified entry point for creating all codec types.

This facade provides factory methods for number, string, hex, binary, boolean, list, composition, and object codecs.

Example usage:

// Number codecs
Codec<Integer> u8 = Codecs.uint8();
Codec<Long> i64 = Codecs.int64();

// String codecs
Codec<String> ascii = Codecs.ascii(10);
Codec<String> utf8 = Codecs.utf8();

// Constant bytes
Codec<byte[]> magic = Codecs.constant(new byte[] {0x4D, 0x5A});

// Numeric string codecs
Codec<Integer> bcd = Codecs.bcdInt(4);
Codec<Integer> asciiNum = Codecs.asciiInt(4);
Codec<Long> ebcdicNum = Codecs.ebcdicLong(10);

// Composition
Codec<String> prefixed = Codecs.prefixed(Codecs.uint16(), Codecs.utf8());
Codec<List<Integer>> list = Codecs.listOf(5, Codecs.uint8());

// Object codecs
SequentialObjectCodec<Msg> codec = Codecs.<Msg>sequential(Msg::new)
    .field("id", Codecs.int32(), Msg::getId, Msg::setId)
    .build();
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static enum 
    Policy for decoding a value whose terminator is absent at the end of the stream.
  • Method Summary

    Modifier and Type
    Method
    Description
    static Codec<String>
    Creates a variable-length US-ASCII string codec.
    static Codec<String>
    ascii(int length)
    Creates a fixed-length US-ASCII string codec.
    static Codec<String>
    ascii(Codec<Integer> lengthCodec)
    Creates a variable-length US-ASCII string codec where the code point count is encoded as a prefix.
    asciiBigInt(int digits)
    Creates an ASCII numeric codec for values wider than a long holds.
    static Codec<Integer>
    asciiInt(int digits)
    Creates a fixed-length ASCII numeric codec that decodes to Integer.
    static Codec<Long>
    asciiLong(int digits)
    Creates a fixed-length ASCII numeric codec that decodes to Long.
    bcdBigInt(int digits)
    Creates a BCD codec for values wider than a long holds.
    static Codec<Integer>
    bcdInt(int digits)
    Creates a fixed-length BCD (Binary Coded Decimal) codec that decodes to Integer.
    static Codec<Long>
    bcdLong(int digits)
    Creates a fixed-length BCD (Binary Coded Decimal) codec that decodes to Long.
    static Codec<byte[]>
    Creates a variable-length binary codec that reads all remaining bytes from the stream.
    static Codec<byte[]>
    binary(int length)
    Creates a fixed-length binary codec.
    static Codec<byte[]>
    binary(Codec<Integer> lengthCodec)
    Creates a variable-length binary codec where the byte count is encoded as a prefix.
    static Codec<Boolean>
    Creates a boolean codec (single byte: 0x00 = false, 0x01 = true).
    static <T,V> Codec<V>
    checked(Codec<V> valueCodec, Codec<T> checkCodec, Function<byte[],T> compute)
    Creates a codec for a value followed by a value computed over its bytes — an LRC, a CRC, a checksum or a MAC.
    static <T,V> ChoiceCodec.Builder<T,V>
    choice(Codec<T> tagCodec)
    Creates a new builder for a choice codec that encodes discriminated unions.
    static Codec<byte[]>
    constant(byte[] expected)
    Creates a constant codec that always writes the expected bytes on encode (ignoring the input value) and validates that the bytes match on decode.
    static Codec<String>
    Creates a variable-length EBCDIC (IBM1047) string codec.
    static Codec<String>
    ebcdic(int length)
    Creates a fixed-length EBCDIC (IBM1047) string codec.
    static Codec<String>
    ebcdic(Codec<Integer> lengthCodec)
    Creates a variable-length EBCDIC (IBM1047) string codec where the code point count is encoded as a prefix.
    ebcdicBigInt(int digits)
    Creates an EBCDIC numeric codec for values wider than a long holds.
    static Codec<Integer>
    ebcdicInt(int digits)
    Creates a fixed-length EBCDIC numeric codec that decodes to Integer.
    static Codec<Long>
    ebcdicLong(int digits)
    Creates a fixed-length EBCDIC numeric codec that decodes to Long.
    static Codec<Float>
    Creates a codec for float values (IEEE 754 single-precision, 4 bytes).
    static Codec<Float>
    Creates a codec for IEEE 754 single-precision values, encoded as 4-byte binary in the given byte order.
    static Codec<Double>
    Creates a codec for double values (IEEE 754 double-precision, 8 bytes).
    static Codec<Double>
    Creates a codec for IEEE 754 double-precision values, encoded as 8-byte binary in the given byte order.
    static Codec<String>
    hex()
    Creates a variable-length hex string codec.
    static Codec<String>
    hex(int length)
    Creates a fixed-length hex string codec.
    static Codec<String>
    hex(Codec<Integer> lengthCodec)
    Creates a variable-length hex string codec where the hex digit count is encoded as a prefix.
    static Codec<Short>
    Creates a codec for signed short values (-32768 to 32767), encoded as 2-byte big-endian binary.
    static Codec<Short>
    Creates a codec for signed short values (-32768 to 32767), encoded as 2-byte binary in the given byte order.
    static Codec<Integer>
    Creates a codec for signed integer values (-2147483648 to 2147483647), encoded as 4-byte big-endian binary.
    static Codec<Integer>
    Creates a codec for signed integer values (-2147483648 to 2147483647), encoded as 4-byte binary in the given byte order.
    static Codec<Long>
    Creates a codec for signed long values, encoded as 8-byte big-endian binary.
    static Codec<Long>
    Creates a codec for signed long values, encoded as 8-byte binary in the given byte order.
    static Codec<String>
    Creates a variable-length ISO-8859-1 (Latin-1) string codec.
    static Codec<String>
    latin1(int length)
    Creates a fixed-length ISO-8859-1 (Latin-1) string codec.
    static Codec<String>
    latin1(Codec<Integer> lengthCodec)
    Creates a variable-length ISO-8859-1 (Latin-1) string codec where the code point count is encoded as a prefix.
    static <V> Codec<V>
    lazy(Supplier<Codec<V>> supplier)
    Creates a lazy codec that defers resolution to first use, enabling recursive definitions.
    static <V> Codec<List<V>>
    listOf(int length, Codec<V> itemCodec)
    Creates a fixed-length list codec that encodes/decodes exactly length items.
    static <V> Codec<List<V>>
    listOf(Codec<Integer> lengthCodec, Codec<V> itemCodec)
    Creates a variable-length list codec where the item count is encoded as a prefix.
    static <V> Codec<List<V>>
    listOf(Codec<V> itemCodec)
    Creates a stream list codec that reads items until EOF.
    static Codec<String>
    ofCharset(Charset charset)
    Creates a variable-length string codec with the specified charset.
    static Codec<String>
    ofCharset(Charset charset, int length)
    Creates a fixed-length string codec with the specified charset.
    static Codec<String>
    ofCharset(Charset charset, Codec<Integer> lengthCodec)
    Creates a variable-length string codec where the code point count is encoded as a prefix.
    static Codec<Integer>
    packedInt(int digits)
    Creates a codec for signed packed decimal integers, the format COBOL declares as COMP-3.
    static Codec<Long>
    packedLong(int digits)
    Creates a codec for signed packed decimal longs, the format COBOL declares as COMP-3.
    static <A,B> PairCodec<A,B>
    pair(Codec<A> first, Codec<B> second)
    Creates a pair codec that encodes and decodes two values sequentially.
    static <V> Codec<V>
    prefixed(Codec<Integer> lengthCodec, Codec<V> valueCodec)
    Creates a variable-length codec where the byte count is encoded as a prefix.
    static <V> Codec<V>
    prefixed(Codec<Integer> lengthCodec, ToIntFunction<V> lengthOf, IntFunction<Codec<V>> codecFactory)
    Creates a variable-length codec where the item count is encoded as a prefix.
    static <T,V> Codec<List<V>>
    repeatWhile(Codec<T> peekCodec, Predicate<T> accepts, Codec<V> itemCodec)
    Creates a codec for a run of items that continues while a lookahead matches.
    sequential(Supplier<T> factory)
    Creates a new builder for a sequential object codec.
    tagged(Codec<K> tagCodec)
    Creates a new builder for a tagged object codec using TaggedData.
    static <T extends Tagged<T,K>, K>
    TaggedObjectCodec.Builder<T,K>
    tagged(Supplier<T> factory, Codec<K> tagCodec)
    Creates a new builder for a tagged object codec.
    static <V> Codec<V>
    terminated(Codec<V> valueCodec, byte[] terminator)
    Creates a variable-length codec where the value is followed by a terminator.
    static <V> Codec<V>
    terminated(Codec<V> valueCodec, byte[] terminator, Codecs.Termination termination)
    Creates a variable-length codec where the value is followed by a terminator, with an explicit policy for a final value that is not terminated.
    static <A,B,C> TripleCodec<A,B,C>
    triple(Codec<A> first, Codec<B> second, Codec<C> third)
    Creates a triple codec that encodes and decodes three values sequentially.
    static Codec<Integer>
    Creates a codec for unsigned short values (0 to 65535), encoded as 2-byte big-endian binary.
    static Codec<Integer>
    Creates a codec for unsigned short values (0 to 65535), encoded as 2-byte binary in the given byte order.
    static Codec<Integer>
    Creates a codec for unsigned three-byte values (0 to 16777215), encoded as big-endian binary.
    static Codec<Integer>
    Creates a codec for unsigned three-byte values (0 to 16777215), encoded as binary in the given byte order.
    static Codec<Long>
    Creates a codec for unsigned integer values (0 to 4294967295), encoded as 4-byte big-endian binary.
    static Codec<Long>
    Creates a codec for unsigned integer values (0 to 4294967295), encoded as 4-byte binary in the given byte order.
    static Codec<Integer>
    Creates a codec for unsigned byte values (0 to 255), encoded as 1-byte binary.
    static Codec<String>
    Creates a variable-length UTF-8 string codec.
    static Codec<String>
    utf8(int length)
    Creates a fixed-length UTF-8 string codec.
    static Codec<String>
    utf8(Codec<Integer> lengthCodec)
    Creates a variable-length UTF-8 string codec where the code point count is encoded as a prefix.
    static Codec<Integer>
    zonedInt(int digits)
    Creates a codec for EBCDIC zoned decimal integers, the format COBOL declares as DISPLAY.
    static Codec<Long>
    zonedLong(int digits)
    Creates a codec for EBCDIC zoned decimal longs, the format COBOL declares as DISPLAY.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • uint8

      public static Codec<Integer> uint8()
      Creates a codec for unsigned byte values (0 to 255), encoded as 1-byte binary.
      Returns:
      a new unsigned byte codec
    • uint16

      public static Codec<Integer> uint16()
      Creates a codec for unsigned short values (0 to 65535), encoded as 2-byte big-endian binary.
      Returns:
      a new unsigned short codec
      See Also:
    • uint16

      public static Codec<Integer> uint16(ByteOrder order)
      Creates a codec for unsigned short values (0 to 65535), encoded as 2-byte binary in the given byte order.

      The no-argument factory is big-endian. Little-endian is common in formats of PC and embedded origin, such as ZIP, RIFF and PE.

      Parameters:
      order - the byte order
      Returns:
      a new codec
      Throws:
      NullPointerException - if order is null
    • uint24

      public static Codec<Integer> uint24()
      Creates a codec for unsigned three-byte values (0 to 16777215), encoded as big-endian binary.

      Three-byte lengths appear in TLS records, MPEG-TS, RTP and some ISO 8583 length fields.

      Returns:
      a new unsigned three-byte codec
      See Also:
    • uint24

      public static Codec<Integer> uint24(ByteOrder order)
      Creates a codec for unsigned three-byte values (0 to 16777215), encoded as binary in the given byte order.

      The no-argument factory is big-endian.

      Parameters:
      order - the byte order
      Returns:
      a new codec
      Throws:
      NullPointerException - if order is null
    • uint32

      public static Codec<Long> uint32()
      Creates a codec for unsigned integer values (0 to 4294967295), encoded as 4-byte big-endian binary.
      Returns:
      a new unsigned integer codec
      See Also:
    • uint32

      public static Codec<Long> uint32(ByteOrder order)
      Creates a codec for unsigned integer values (0 to 4294967295), encoded as 4-byte binary in the given byte order.

      The no-argument factory is big-endian. Little-endian is common in formats of PC and embedded origin, such as ZIP, RIFF and PE.

      Parameters:
      order - the byte order
      Returns:
      a new codec
      Throws:
      NullPointerException - if order is null
    • int16

      public static Codec<Short> int16()
      Creates a codec for signed short values (-32768 to 32767), encoded as 2-byte big-endian binary.
      Returns:
      a new signed short codec
      See Also:
    • int16

      public static Codec<Short> int16(ByteOrder order)
      Creates a codec for signed short values (-32768 to 32767), encoded as 2-byte binary in the given byte order.

      The no-argument factory is big-endian. Little-endian is common in formats of PC and embedded origin, such as ZIP, RIFF and PE.

      Parameters:
      order - the byte order
      Returns:
      a new codec
      Throws:
      NullPointerException - if order is null
    • int32

      public static Codec<Integer> int32()
      Creates a codec for signed integer values (-2147483648 to 2147483647), encoded as 4-byte big-endian binary.
      Returns:
      a new signed integer codec
      See Also:
    • int32

      public static Codec<Integer> int32(ByteOrder order)
      Creates a codec for signed integer values (-2147483648 to 2147483647), encoded as 4-byte binary in the given byte order.

      The no-argument factory is big-endian. Little-endian is common in formats of PC and embedded origin, such as ZIP, RIFF and PE.

      Parameters:
      order - the byte order
      Returns:
      a new codec
      Throws:
      NullPointerException - if order is null
    • int64

      public static Codec<Long> int64()
      Creates a codec for signed long values, encoded as 8-byte big-endian binary.
      Returns:
      a new signed long codec
      See Also:
    • int64

      public static Codec<Long> int64(ByteOrder order)
      Creates a codec for signed long values, encoded as 8-byte binary in the given byte order.

      The no-argument factory is big-endian. Little-endian is common in formats of PC and embedded origin, such as ZIP, RIFF and PE.

      Parameters:
      order - the byte order
      Returns:
      a new codec
      Throws:
      NullPointerException - if order is null
    • float32

      public static Codec<Float> float32()
      Creates a codec for float values (IEEE 754 single-precision, 4 bytes).
      Returns:
      a new float codec
      See Also:
    • float32

      public static Codec<Float> float32(ByteOrder order)
      Creates a codec for IEEE 754 single-precision values, encoded as 4-byte binary in the given byte order.

      The no-argument factory is big-endian. Little-endian is common in formats of PC and embedded origin, such as ZIP, RIFF and PE.

      Parameters:
      order - the byte order
      Returns:
      a new codec
      Throws:
      NullPointerException - if order is null
    • float64

      public static Codec<Double> float64()
      Creates a codec for double values (IEEE 754 double-precision, 8 bytes).
      Returns:
      a new double codec
      See Also:
    • float64

      public static Codec<Double> float64(ByteOrder order)
      Creates a codec for IEEE 754 double-precision values, encoded as 8-byte binary in the given byte order.

      The no-argument factory is big-endian. Little-endian is common in formats of PC and embedded origin, such as ZIP, RIFF and PE.

      Parameters:
      order - the byte order
      Returns:
      a new codec
      Throws:
      NullPointerException - if order is null
    • ascii

      public static Codec<String> ascii(int length)
      Creates a fixed-length US-ASCII string codec.
      Parameters:
      length - the number of code points
      Returns:
      a new codec
    • ascii

      public static Codec<String> ascii()
      Creates a variable-length US-ASCII string codec.
      Returns:
      a new codec
    • ascii

      public static Codec<String> ascii(Codec<Integer> lengthCodec)
      Creates a variable-length US-ASCII string codec where the code point count is encoded as a prefix.
      Parameters:
      lengthCodec - the codec for the code point count prefix
      Returns:
      a new codec
    • utf8

      public static Codec<String> utf8(int length)
      Creates a fixed-length UTF-8 string codec.
      Parameters:
      length - the number of code points
      Returns:
      a new codec
    • utf8

      public static Codec<String> utf8()
      Creates a variable-length UTF-8 string codec.
      Returns:
      a new codec
    • utf8

      public static Codec<String> utf8(Codec<Integer> lengthCodec)
      Creates a variable-length UTF-8 string codec where the code point count is encoded as a prefix.
      Parameters:
      lengthCodec - the codec for the code point count prefix
      Returns:
      a new codec
    • latin1

      public static Codec<String> latin1(int length)
      Creates a fixed-length ISO-8859-1 (Latin-1) string codec.
      Parameters:
      length - the number of code points
      Returns:
      a new codec
    • latin1

      public static Codec<String> latin1()
      Creates a variable-length ISO-8859-1 (Latin-1) string codec.
      Returns:
      a new codec
    • latin1

      public static Codec<String> latin1(Codec<Integer> lengthCodec)
      Creates a variable-length ISO-8859-1 (Latin-1) string codec where the code point count is encoded as a prefix.
      Parameters:
      lengthCodec - the codec for the code point count prefix
      Returns:
      a new codec
    • ebcdic

      public static Codec<String> ebcdic(int length)
      Creates a fixed-length EBCDIC (IBM1047) string codec.
      Parameters:
      length - the number of code points
      Returns:
      a new codec
    • ebcdic

      public static Codec<String> ebcdic()
      Creates a variable-length EBCDIC (IBM1047) string codec.
      Returns:
      a new codec
    • ebcdic

      public static Codec<String> ebcdic(Codec<Integer> lengthCodec)
      Creates a variable-length EBCDIC (IBM1047) string codec where the code point count is encoded as a prefix.
      Parameters:
      lengthCodec - the codec for the code point count prefix
      Returns:
      a new codec
    • ofCharset

      public static Codec<String> ofCharset(Charset charset, int length)
      Creates a fixed-length string codec with the specified charset.
      Parameters:
      charset - the charset
      length - the number of code points
      Returns:
      a new codec
    • ofCharset

      public static Codec<String> ofCharset(Charset charset)
      Creates a variable-length string codec with the specified charset.
      Parameters:
      charset - the charset
      Returns:
      a new codec
    • ofCharset

      public static Codec<String> ofCharset(Charset charset, Codec<Integer> lengthCodec)
      Creates a variable-length string codec where the code point count is encoded as a prefix.

      For single-byte charsets, uses String.length() for the count (O(1)). For multibyte charsets, uses Strings.codePointCount(String) (O(n)).

      Parameters:
      charset - the charset
      lengthCodec - the codec for the code point count prefix
      Returns:
      a new codec
    • hex

      public static Codec<String> hex(int length)
      Creates a fixed-length hex string codec. Odd-length values are left-padded with '0' to align to byte boundaries.
      Parameters:
      length - the number of hex digits
      Returns:
      a new codec
    • hex

      public static Codec<String> hex()
      Creates a variable-length hex string codec. Odd-length values are left-padded with '0' to align to byte boundaries.
      Returns:
      a new codec
    • hex

      public static Codec<String> hex(Codec<Integer> lengthCodec)
      Creates a variable-length hex string codec where the hex digit count is encoded as a prefix. Odd-length values are left-padded with '0' to align to byte boundaries.
      Parameters:
      lengthCodec - the codec for the hex digit count prefix
      Returns:
      a new codec
    • bcdInt

      public static Codec<Integer> bcdInt(int digits)
      Creates a fixed-length BCD (Binary Coded Decimal) codec that decodes to Integer.

      Each byte holds two decimal digits (0–9) in its high and low nibbles. Odd-length digit counts are left-padded with a zero nibble.

      Codec<Integer> codec = Codecs.bcdInt(4);
      codec.encode(42, out);   // writes 0x00, 0x42
      codec.decode(in);        // reads 0x00, 0x42 → 42
      
      Parameters:
      digits - the number of BCD digits (1 to 9)
      Returns:
      a new BCD integer codec
      Throws:
      IllegalArgumentException - if digits is not between 1 and 9
    • bcdBigInt

      public static Codec<BigInteger> bcdBigInt(int digits)
      Creates a BCD codec for values wider than a long holds.

      bcdLong(int) stops at eighteen digits, which is what a long carries. This has no such limit.

      Parameters:
      digits - the number of digits
      Returns:
      a new BCD big integer codec
      Throws:
      IllegalArgumentException - if digits is not positive
    • bcdLong

      public static Codec<Long> bcdLong(int digits)
      Creates a fixed-length BCD (Binary Coded Decimal) codec that decodes to Long.

      Each byte holds two decimal digits (0–9) in its high and low nibbles. Odd-length digit counts are left-padded with a zero nibble.

      Codec<Long> codec = Codecs.bcdLong(10);
      codec.encode(1234567890L, out);  // writes 0x12, 0x34, 0x56, 0x78, 0x90
      codec.decode(in);                // reads 0x12, 0x34, 0x56, 0x78, 0x90 → 1234567890
      
      Parameters:
      digits - the number of BCD digits (1 to 18)
      Returns:
      a new BCD long codec
      Throws:
      IllegalArgumentException - if digits is not between 1 and 18
    • packedInt

      public static Codec<Integer> packedInt(int digits)
      Creates a codec for signed packed decimal integers, the format COBOL declares as COMP-3.

      Digits occupy a nibble each, two to a byte, with the final nibble carrying the sign. A five-digit field takes three bytes:

      Codec<Integer> amount = Codecs.packedInt(5);
      amount.encode(-12345, out);   // writes 12 34 5D
      

      Unlike bcdInt(int), which packs digits the same way but has no sign nibble and so cannot represent a negative value.

      Parameters:
      digits - the number of digits (1 to 9)
      Returns:
      a new packed decimal integer codec
      Throws:
      IllegalArgumentException - if digits is outside 1 to 9
    • packedLong

      public static Codec<Long> packedLong(int digits)
      Creates a codec for signed packed decimal longs, the format COBOL declares as COMP-3.

      Digits occupy a nibble each, two to a byte, with the final nibble carrying the sign. Encoding writes C for positive and D for negative; decoding also accepts A, E and F as positive and B as negative.

      Codec<Long> balance = Codecs.packedLong(11);
      

      Unlike bcdLong(int), which packs digits the same way but has no sign nibble and so cannot represent a negative value.

      Parameters:
      digits - the number of digits (1 to 18)
      Returns:
      a new packed decimal long codec
      Throws:
      IllegalArgumentException - if digits is outside 1 to 18
    • zonedInt

      public static Codec<Integer> zonedInt(int digits)
      Creates a codec for EBCDIC zoned decimal integers, the format COBOL declares as DISPLAY.

      One digit per byte as EBCDIC characters, with the sign held in the high nibble (the "zone") of the final byte:

      Codec<Integer> quantity = Codecs.zonedInt(3);
      quantity.encode(-123, out);   // writes F1 F2 D3
      

      Unlike ebcdicInt(int), which reads the same bytes as text and cannot represent a sign. Reading a signed field that way is the trap this codec closes: F1 F2 D3 is the EBCDIC string "12L", so the value decodes to something plausible with no error and the sign silently lost.

      Parameters:
      digits - the number of digits (1 to 9)
      Returns:
      a new zoned decimal integer codec
      Throws:
      IllegalArgumentException - if digits is outside 1 to 9
    • zonedLong

      public static Codec<Long> zonedLong(int digits)
      Creates a codec for EBCDIC zoned decimal longs, the format COBOL declares as DISPLAY.

      One digit per byte as EBCDIC characters, with the sign held in the high nibble of the final byte. Encoding writes zone C for positive and D for negative; decoding also accepts A, E and F as positive and B as negative.

      Leading bytes must carry the digit zone F, which rejects ASCII digits read as EBCDIC — they would otherwise decode to the right number by accident, both encodings holding the digit in the low nibble.

      Parameters:
      digits - the number of digits (1 to 18)
      Returns:
      a new zoned decimal long codec
      Throws:
      IllegalArgumentException - if digits is outside 1 to 18
    • asciiInt

      public static Codec<Integer> asciiInt(int digits)
      Creates a fixed-length ASCII numeric codec that decodes to Integer.

      The value is encoded as a zero-padded decimal string in US-ASCII.

      Codec<Integer> codec = Codecs.asciiInt(4);
      codec.encode(42, out);   // writes "0042" in ASCII
      codec.decode(in);        // reads "0042" in ASCII → 42
      
      Parameters:
      digits - the number of digits (1 to 9)
      Returns:
      a new ASCII integer codec
      Throws:
      IllegalArgumentException - if digits is not between 1 and 9
    • asciiLong

      public static Codec<Long> asciiLong(int digits)
      Creates a fixed-length ASCII numeric codec that decodes to Long.

      The value is encoded as a zero-padded decimal string in US-ASCII.

      Codec<Long> codec = Codecs.asciiLong(10);
      codec.encode(1234567890L, out);  // writes "1234567890" in ASCII
      codec.decode(in);                // reads "1234567890" in ASCII → 1234567890
      
      Parameters:
      digits - the number of digits (1 to 18)
      Returns:
      a new ASCII long codec
      Throws:
      IllegalArgumentException - if digits is not between 1 and 18
    • asciiBigInt

      public static Codec<BigInteger> asciiBigInt(int digits)
      Creates an ASCII numeric codec for values wider than a long holds.

      asciiLong(int) stops at eighteen digits. COBOL allows PIC 9(31), and long reference numbers exceed a long routinely.

      Parameters:
      digits - the number of digits
      Returns:
      a new ASCII big integer codec
      Throws:
      IllegalArgumentException - if digits is not positive
    • ebcdicInt

      public static Codec<Integer> ebcdicInt(int digits)
      Creates a fixed-length EBCDIC numeric codec that decodes to Integer.

      The value is encoded as a zero-padded decimal string in EBCDIC (IBM1047).

      Codec<Integer> codec = Codecs.ebcdicInt(4);
      codec.encode(42, out);   // writes "0042" in EBCDIC
      codec.decode(in);        // reads "0042" in EBCDIC → 42
      
      Parameters:
      digits - the number of digits (1 to 9)
      Returns:
      a new EBCDIC integer codec
      Throws:
      IllegalArgumentException - if digits is not between 1 and 9
    • ebcdicLong

      public static Codec<Long> ebcdicLong(int digits)
      Creates a fixed-length EBCDIC numeric codec that decodes to Long.

      The value is encoded as a zero-padded decimal string in EBCDIC (IBM1047).

      Codec<Long> codec = Codecs.ebcdicLong(10);
      codec.encode(1234567890L, out);  // writes "1234567890" in EBCDIC
      codec.decode(in);                // reads "1234567890" in EBCDIC → 1234567890
      
      Parameters:
      digits - the number of digits (1 to 18)
      Returns:
      a new EBCDIC long codec
      Throws:
      IllegalArgumentException - if digits is not between 1 and 18
    • ebcdicBigInt

      public static Codec<BigInteger> ebcdicBigInt(int digits)
      Creates an EBCDIC numeric codec for values wider than a long holds.

      ebcdicLong(int) stops at eighteen digits, which is what a long carries.

      Parameters:
      digits - the number of digits
      Returns:
      a new EBCDIC big integer codec
      Throws:
      IllegalArgumentException - if digits is not positive
    • choice

      public static <T,V> ChoiceCodec.Builder<T,V> choice(Codec<T> tagCodec)
      Creates a new builder for a choice codec that encodes discriminated unions.

      Each alternative is registered as a tag, a class and a codec, so decoding dispatches on the tag and encoding on the class without the two being able to disagree.

      Type Parameters:
      T - the tag type
      V - the base type of the discriminated union
      Parameters:
      tagCodec - the codec for the tag
      Returns:
      a new choice codec builder
    • lazy

      public static <V> Codec<V> lazy(Supplier<Codec<V>> supplier)
      Creates a lazy codec that defers resolution to first use, enabling recursive definitions.
      Type Parameters:
      V - the value type
      Parameters:
      supplier - supplies the codec on first use
      Returns:
      a new lazy codec
    • pair

      public static <A,B> PairCodec<A,B> pair(Codec<A> first, Codec<B> second)
      Creates a pair codec that encodes and decodes two values sequentially.
      Type Parameters:
      A - the first value type
      B - the second value type
      Parameters:
      first - the codec for the first value
      second - the codec for the second value
      Returns:
      a new pair codec
    • triple

      public static <A,B,C> TripleCodec<A,B,C> triple(Codec<A> first, Codec<B> second, Codec<C> third)
      Creates a triple codec that encodes and decodes three values sequentially.
      Type Parameters:
      A - the first value type
      B - the second value type
      C - the third value type
      Parameters:
      first - the codec for the first value
      second - the codec for the second value
      third - the codec for the third value
      Returns:
      a new triple codec
    • prefixed

      public static <V> Codec<V> prefixed(Codec<Integer> lengthCodec, Codec<V> valueCodec)
      Creates a variable-length codec where the byte count is encoded as a prefix.
      Type Parameters:
      V - the value type
      Parameters:
      lengthCodec - the codec for the byte count prefix
      valueCodec - the codec for the value
      Returns:
      a new variable byte-length codec
    • terminated

      public static <V> Codec<V> terminated(Codec<V> valueCodec, byte[] terminator)
      Creates a variable-length codec where the value is followed by a terminator.

      Bounds a value the same way prefixed(Codec, Codec) does — a length in front versus a sentinel behind — so the same value codecs work inside either. On decode, the bytes before the terminator are passed to the value codec as a bounded stream and the terminator is consumed, which is what makes read-until-EOF codecs such as ascii() and listOf(Codec) usable inside it.

      byte[] lf = "\n".getBytes(US_ASCII);
      Codec<String> line = Codecs.terminated(Codecs.ascii(), lf);
      

      The terminator is a byte[] rather than a String because the correct bytes depend on the encoding: a newline is 0x0A in ASCII but 0x25 in EBCDIC.

      Decoding reads one byte at a time, since the end of the value is not known in advance and outer codecs continue reading the same stream. Wrap unbuffered sources such as FileInputStream in a BufferedInputStream.

      On encode the value is written followed by the terminator. A value whose encoded bytes contain the terminator could not be decoded back, so it is rejected before anything is written. There is no escaping mechanism.

      Uses Codecs.Termination.OPTIONAL. For a fixed sequence of fields separated by a delimiter, prefer leaving the last field unwrapped over relying on this policy — the enclosing scope ends it, the wire format is then stated in the structure, and encoding round-trips exactly.

      Type Parameters:
      V - the value type
      Parameters:
      valueCodec - the codec for the value
      terminator - the terminating byte sequence (must be non-empty)
      Returns:
      a new terminated codec
      Throws:
      NullPointerException - if any argument is null
      IllegalArgumentException - if the terminator is empty
    • terminated

      public static <V> Codec<V> terminated(Codec<V> valueCodec, byte[] terminator, Codecs.Termination termination)
      Creates a variable-length codec where the value is followed by a terminator, with an explicit policy for a final value that is not terminated.

      The policy matters when the same codec is applied repeatedly and no position identifies the last value, such as reading a document as a list of lines where the final line may not be terminated:

      Codec<List<String>> lines = Codecs.listOf(Codecs.terminated(Codecs.ascii(), lf));
      
      Type Parameters:
      V - the value type
      Parameters:
      valueCodec - the codec for the value
      terminator - the terminating byte sequence (must be non-empty)
      termination - whether the terminator is required on decode
      Returns:
      a new terminated codec
      Throws:
      NullPointerException - if any argument is null
      IllegalArgumentException - if the terminator is empty
    • checked

      public static <T,V> Codec<V> checked(Codec<V> valueCodec, Codec<T> checkCodec, Function<byte[],T> compute)
      Creates a codec for a value followed by a value computed over its bytes — an LRC, a CRC, a checksum or a MAC.

      On encode the check is computed over exactly the bytes the value codec wrote. On decode it is computed over exactly the bytes the value codec read, and the field that follows must match.

      Codec<Frame> frame = Codecs.checked(frameCodec, Codecs.uint16(), Crc16::compute);
      

      The check function is yours to supply. Which polynomial, seed and bit order a protocol uses is specification knowledge, so no algorithm is built in.

      The value codec must consume exactly its own bytes, since the check field begins immediately afterwards. A read-until-EOF codec such as ascii() would swallow the check unless placed inside a bounded scope such as prefixed(Codec, Codec) or terminated(Codec, byte[]).

      Type Parameters:
      T - the check value type
      V - the value type
      Parameters:
      valueCodec - the codec for the value
      checkCodec - the codec for the check value
      compute - computes the check value from the bytes it covers
      Returns:
      a new checked codec
      Throws:
      NullPointerException - if any argument is null
    • prefixed

      public static <V> Codec<V> prefixed(Codec<Integer> lengthCodec, ToIntFunction<V> lengthOf, IntFunction<Codec<V>> codecFactory)
      Creates a variable-length codec where the item count is encoded as a prefix.
      Type Parameters:
      V - the value type
      Parameters:
      lengthCodec - the codec for the item count prefix
      lengthOf - a function that returns the item count for a given value
      codecFactory - a function that creates a codec for the given item count
      Returns:
      a new variable item-length codec
    • repeatWhile

      public static <T,V> Codec<List<V>> repeatWhile(Codec<T> peekCodec, Predicate<T> accepts, Codec<V> itemCodec)
      Creates a codec for a run of items that continues while a lookahead matches.

      Before each item, peekCodec decodes a value and accepts decides whether another item follows; the stream is then rewound so the item codec sees those bytes again. The run ends at the first value the predicate rejects, leaving the stream positioned at that value for whatever reads next.

      Codec<String> recordType = Codecs.ascii(2);
      
      Codec<List<Detail>> details =
          Codecs.repeatWhile(recordType, "D "::equals, Codecs.terminated(detailCodec, lf));
      

      The input stream must support mark; wrap unbuffered sources such as FileInputStream in a BufferedInputStream. A run ends at end of stream or at the first value the predicate rejects, consuming nothing in either case, so whatever reads next sees those bytes. Any other failure while reading the lookahead propagates — a discriminator that cannot be decoded is an error, not a terminator. The lookahead may read up to 8192 bytes; a codec that reads further cannot be rewound and is reported as an error.

      The item codec must consume input. One that does not would leave the lookahead unchanged and the run would not terminate.

      An empty run is valid. To require at least one item, add .validate(list -> !list.isEmpty(), "…").

      Encoding writes the items and nothing else — the discriminator must be part of each item's own encoding, or the result will not decode back.

      Type Parameters:
      T - the lookahead value type
      V - the item type
      Parameters:
      peekCodec - the codec for the lookahead value
      accepts - the condition indicating another item follows
      itemCodec - the codec for a single item
      Returns:
      a new codec for the run
      Throws:
      NullPointerException - if any argument is null
    • listOf

      public static <V> Codec<List<V>> listOf(int length, Codec<V> itemCodec)
      Creates a fixed-length list codec that encodes/decodes exactly length items.
      Type Parameters:
      V - the item type
      Parameters:
      length - the exact number of items
      itemCodec - the codec for individual list items
      Returns:
      a new fixed list codec
    • listOf

      public static <V> Codec<List<V>> listOf(Codec<V> itemCodec)
      Creates a stream list codec that reads items until EOF.

      The item codec must consume input. One that does not would leave the stream unchanged and the read would not terminate.

      Type Parameters:
      V - the item type
      Parameters:
      itemCodec - the codec for individual list items
      Returns:
      a new stream list codec
    • listOf

      public static <V> Codec<List<V>> listOf(Codec<Integer> lengthCodec, Codec<V> itemCodec)
      Creates a variable-length list codec where the item count is encoded as a prefix.
      Type Parameters:
      V - the item type
      Parameters:
      lengthCodec - the codec for the item count prefix
      itemCodec - the codec for individual list items
      Returns:
      a new codec
    • sequential

      public static <T> SequentialObjectCodec.Builder<T> sequential(Supplier<T> factory)
      Creates a new builder for a sequential object codec.
      Type Parameters:
      T - the type of object to encode/decode
      Parameters:
      factory - factory that creates new instances during decoding
      Returns:
      a new sequential object codec builder
    • tagged

      public static <T extends Tagged<T,K>, K> TaggedObjectCodec.Builder<T,K> tagged(Supplier<T> factory, Codec<K> tagCodec)
      Creates a new builder for a tagged object codec.
      Type Parameters:
      T - the type of object to encode/decode
      K - the tag key type
      Parameters:
      factory - factory that creates new instances during decoding
      tagCodec - the codec used to read and write tags
      Returns:
      a new tagged object codec builder
    • tagged

      public static <K> TaggedObjectCodec.Builder<TaggedData<K>, K> tagged(Codec<K> tagCodec)
      Creates a new builder for a tagged object codec using TaggedData.
      Type Parameters:
      K - the tag key type
      Parameters:
      tagCodec - the codec used to read and write tags
      Returns:
      a new tagged object codec builder
    • binary

      public static Codec<byte[]> binary(int length)
      Creates a fixed-length binary codec.
      Parameters:
      length - the number of bytes
      Returns:
      a new binary codec
    • binary

      public static Codec<byte[]> binary()
      Creates a variable-length binary codec that reads all remaining bytes from the stream.
      Returns:
      a new codec
    • binary

      public static Codec<byte[]> binary(Codec<Integer> lengthCodec)
      Creates a variable-length binary codec where the byte count is encoded as a prefix.
      Parameters:
      lengthCodec - the codec for the byte count prefix
      Returns:
      a new codec
    • constant

      public static Codec<byte[]> constant(byte[] expected)
      Creates a constant codec that always writes the expected bytes on encode (ignoring the input value) and validates that the bytes match on decode.

      Useful for magic numbers, version bytes, and protocol signatures. The value passed to encode is ignored; null is acceptable.

      Codec<byte[]> magic = Codecs.constant(new byte[] {0x4D, 0x5A});
      
      Parameters:
      expected - the expected byte sequence (must be non-null and non-empty)
      Returns:
      a new constant codec
      Throws:
      NullPointerException - if expected is null
      IllegalArgumentException - if expected is empty
    • bool

      public static Codec<Boolean> bool()
      Creates a boolean codec (single byte: 0x00 = false, 0x01 = true).
      Returns:
      a new boolean codec