Module org.firebirdsql.jaybird
Package org.firebirdsql.extern.decimal

# Class DenselyPackedDecimalCodec

java.lang.Object
org.firebirdsql.extern.decimal.DenselyPackedDecimalCodec

public final class DenselyPackedDecimalCodec extends Object
Provides conversion between Densely Packed Decimal encoding and `BigInteger`.

Densely packed decimals are encoded in groups of three digits, which are encoded in 10 bits per group.

See: A Summary of Densely Packed Decimal encoding

The implementation is tied to the needs of the IEEE-754 decimal encoding and decoding of this library, so it may be quirky for other purposes.

This implementation can be made to behave as for `n * 3` digits by constructing it for `n * 3 + 1` digits and calling `decodeValue(int, int, byte[])` with `0` for the second parameter (`firstDigit`).

Author:
  Mark Rotteveel

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `DenselyPackedDecimalCodec(int numberOfDigits)`
  Creates a densely packed decimal coder for the specified number of digits.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `BigInteger`
  `decodeValue(int signum, int firstDigit, byte[] decBytes)`
  Decodes a densely packed decimal from a byte array to a `BigInteger`.
  `BigInteger`
  `decodeValue(int signum, int firstDigit, byte[] decBytes, int lsbIndex)`
  Decodes a densely packed decimal from a byte array to a `BigInteger`.
  `int`
  `encodeValue(BigInteger value, byte[] decBytes)`
  Encodes a `BigInteger` to a densely packed decimal in a byte array.
  `int`
  `encodeValue(BigInteger value, byte[] decBytes, int lsbIndex)`
  Encodes a `BigInteger` to a densely packed decimal in a byte array.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### DenselyPackedDecimalCodec

    public DenselyPackedDecimalCodec(int numberOfDigits)
    Creates a densely packed decimal coder for the specified number of digits.

    Current implementation only supports decoding and encoding `n * 3 + 1` number of digits with `n > 0`, where the most significant digit is provided by the caller during decoding.

    Parameters:
      `numberOfDigits` - Number of digits that this coder will decode or encode
    Throws:
      `IllegalArgumentException` - When `numberOfDigits` is not `n * 3 + 1` with `n > 0`

- ## Method Details

  - ### decodeValue

    public BigInteger decodeValue(int signum, int firstDigit, byte[] decBytes)
    Decodes a densely packed decimal from a byte array to a `BigInteger`.

    Digits are read from the end of the array to the front.

    Parameters:
      `signum` - Signum value (values other than `Signum.NEGATIVE` are considered positive!)
      `firstDigit` - First, most significant, digit (`0 <= firstDigit <= 9`)
      `decBytes` - Byte array with the densely packed decimal, with the least significant byte at index `length - 1`
    Returns:
      A `BigInteger` with the decoded value
    Throws:
      `IllegalArgumentException` - When `firstDigit` is out of range, or `decBytes` is too small for the necessary number of bytes
    See Also:
      - `decodeValue(int, int, byte[], int)`

  - ### decodeValue

    public BigInteger decodeValue(int signum, int firstDigit, byte[] decBytes, int lsbIndex)
    Decodes a densely packed decimal from a byte array to a `BigInteger`.

    Digits are read from `lsbIndex` of the array to the front.

    Parameters:
      `signum` - Signum value (values other than `Signum.NEGATIVE` are considered positive!)
      `firstDigit` - First, most significant, digit (`0 <= firstDigit <= 9`)
      `decBytes` - Byte array with the densely packed decimal, with the least significant byte at index `lsbIndex`
      `lsbIndex` - Index of the least significant byte (or the last byte)
    Returns:
      A `BigInteger` with the decoded value
    Throws:
      `IndexOutOfBoundsException` - If `lsbIndex` is not valid for `decBytes`
      `IllegalArgumentException` - When `firstDigit` is out of range, or `lsbIndex` is too small for the necessary number of bytes

  - ### encodeValue

    public int encodeValue(BigInteger value, byte[] decBytes)
    Encodes a `BigInteger` to a densely packed decimal in a byte array.

    Digits are written from the end of the array to the front. The most significant digit is not encoded into the array, but instead returned to the caller.

    Parameters:
      `value` - `BigInteger` with the value to encode
      `decBytes` - Target byte array for the densely packed decimal, with the least significant byte to be written at index `length - 1`. The implementation assumes the array is zero-filled for the bits to be populated by this method.
    Returns:
      First, most significant, digit (`0 <= firstDigit <= 9`) to be encoded separately
    Throws:
      `IndexOutOfBoundsException` - If `lsbIndex` is not valid for `decBytes`
      `IllegalArgumentException` - When `lsbIndex` is too small for the necessary number of bytes
    See Also:
      - `encodeValue(BigInteger, byte[], int)`

  - ### encodeValue

    public int encodeValue(BigInteger value, byte[] decBytes, int lsbIndex)
    Encodes a `BigInteger` to a densely packed decimal in a byte array.

    Digits are written from `lsbIndex` of the array to the front. The most significant digit is not encoded into the array, but instead returned to the caller.

    Parameters:
      `value` - `BigInteger` with the value to encode
      `decBytes` - Target byte array for the densely packed decimal, with the least significant byte to be written at index `lsbIndex`. The implementation assumes the array is zero-filled for the bits to be populated by this method.
      `lsbIndex` - Index for the least significant byte (or the last byte)
    Returns:
      First, most significant, digit (`0 <= firstDigit <= 9`) to be encoded separately
    Throws:
      `IndexOutOfBoundsException` - If `lsbIndex` is not valid for `decBytes`
      `IllegalArgumentException` - When `lsbIndex` is too small for the necessary number of bytes