Skip to main content

GCR

Struct GCR 

Source
pub struct GCR { /* private fields */ }

Implementations§

Source§

impl GCR

Source

pub fn new() -> Self

Constructs a new GCR (Group Code Recording) instance with precomputed lookup tables for efficient encoding and decoding operations.

The GCR struct uses two lookup tables:

  • decode_mappings: A table that maps 5-bit encoded values (keys) to their decoded 4-bit values. This is used for decoding operations. Values that are considered invalid are initialized to 0xFF.
  • encode_mappings: A table that maps 4-bit decoded values into their respective 5-bit encoded counterparts, which is used for encoding operations.

The mapping pairs are predefined and represent the 4-bit to 5-bit encoding scheme:

(Encoded, Decoded)
(01010, 0), (01011, 1), (10010, 2), (10011, 3),
(01110, 4), (01111, 5), (10110, 6), (10111, 7),
(01001, 8), (11001, 9), (11010, 10), (11011, 11),
(01101, 12), (11101, 13), (11110, 14), (10101, 15)

Each (encoded, decoded) mapping is used to populate the appropriate indices in the lookup tables. For example:

  • decode_mappings[encoded] = decoded
  • encode_mappings[decoded] = encoded
§Returns

Returns an instance of the GCR struct with initialized decode_mappings and encode_mappings.

§Example
let gcr = GCR::new();
assert_eq!(gcr.decode_mappings[0b01010], 0); // Decodes "01010" to 0
assert_eq!(gcr.encode_mappings[0], 0b01010); // Encodes 0 to "01010"
Source

pub fn decode(&self, value: &[u8]) -> Option<Vec<u8>>

Decodes a slice of bytes using a specific decoding logic implemented in conjunction with the decode_quintuple method.

This method processes the given input slice value, dividing it into fixed-size chunks (of size QUINTUPLE_SIZE), and applies decoding logic to each chunk. The decoded bytes are collected and returned as a Vec<u8>.

§Parameters
  • value: A slice of bytes (&[u8]) that represents the encoded input to be decoded.
§Returns
  • Some(Vec<u8>): A Vec<u8> containing the decoded bytes, if decoding is successful.
  • None: Returned if decoding fails for any of the data chunks.
§Methodology
  1. The input slice value is iterated in fixed-size chunks. This is achieved using the chunks_exact method, which ensures efficient processing of chunks of size QUINTUPLE_SIZE.
  2. For each chunk, it is converted into a 64-bit integer by padding the upper 3 bytes with zeros.
  3. The method decode_quintuple (presumably implemented elsewhere in the code) is invoked with the 64-bit integer.
    • If decode_quintuple returns a valid result, the decoded data is appended to the result vector (result).
    • If decode_quintuple fails for any chunk, the function returns None.
  4. If all chunks are successfully decoded, the accumulated result is wrapped in Some and returned.
§Example
let decoder = MyDecoder::new(); // Assuming a struct that implements the method
let encoded_data: &[u8] = &[/* encoded bytes */];
if let Some(decoded_data) = decoder.decode(encoded_data) {
    println!("Decoded data: {:?}", decoded_data);
} else {
    println!("Failed to decode the data.");
}
§Note

The size of QUINTUPLE_SIZE and the implementation of the decode_quintuple method are critical for the proper functionality of this method. Ensure these are defined and implemented correctly in the same context.

§Assumptions
  • The QUINTUPLE_SIZE constant is defined and is less than or equal to 5.
  • The decode_quintuple function is implemented to correctly decode a u64 value into a Vec<u8>.
Source

pub fn encode(&self, value: &[u8]) -> Vec<u8>

Encodes the input byte slice (value) into a custom encoding format.

This function processes the input slice in chunks of 4 bytes, encoding each chunk into a new 5-byte segment by delegating the operation to the encode_quintuple method. The resulting encoded chunks are concatenated into a single vector of bytes.

§Parameters
  • value: A slice of bytes (&[u8]) representing the data to be encoded.
§Returns
  • Vec<u8>: A vector containing the concatenated encoding result of all 4-byte chunks, where each chunk is transformed into a 5-byte encoded segment.
§Details
  • The chunking is done using chunks_exact(4), ensuring that only complete chunks of 4 bytes are processed. If value’s length is not a multiple of 4, the remainder is ignored.
  • For each chunk, the encode_quintuple method is called to perform the encoding, returning an integer result that is then converted into its big-endian byte representation (to_be_bytes).
  • Only the last 5 bytes of the big-endian representation are used (as the encoded quintuple is presumed to require 5 bytes), and these are added to the result vector efficiently using extend_from_slice.
§Example
let encoder = Encoder::new();
let input: &[u8] = &[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC];
let output = encoder.encode(input);

// The output will contain the encoded representation of the first 4 bytes
// and then process additional 4-byte chunks as applicable.
§Note
  • QUINTUPLE_SIZE is assumed to be defined elsewhere in the module and represents the fixed size (5 bytes) of each encoded segment.
  • The encode_quintuple method is expected to be implemented for the object type of self and should return an integer representing the encoded form of a 4-byte chunk.
§Performance
  • The Vec::with_capacity is preallocated based on the number of chunks and quintuple size to improve efficiency.
  • This method disregards non-complete chunks (remainder of length % 4).

Auto Trait Implementations§

§

impl Freeze for GCR

§

impl RefUnwindSafe for GCR

§

impl Send for GCR

§

impl Sync for GCR

§

impl Unpin for GCR

§

impl UnsafeUnpin for GCR

§

impl UnwindSafe for GCR

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.