Module: Solace::Utils::Codecs

Defined in:
lib/solace/utils/codecs.rb

Overview

Module for encoding and decoding data

Since:

  • 0.0.1

Class Method Summary collapse

Class Method Details

.base58_to_binary(string) ⇒ String

Decodes a Base58 string into a binary string

Parameters:

  • string (String)

    The Base58 encoded string

Returns:

  • (String)

    The decoded binary string

Since:

  • 0.0.1



114
115
116
# File 'lib/solace/utils/codecs.rb', line 114

def self.base58_to_binary(string)
  base58_to_bytes(string).pack('C*')
end

.base58_to_bytes(string) ⇒ String

Decodes a Base58 string into a sequence of bytes

Parameters:

  • string (String)

    The Base58 encoded string

Returns:

  • (String)

    The decoded bytes

Since:

  • 0.0.1



130
131
132
# File 'lib/solace/utils/codecs.rb', line 130

def self.base58_to_bytes(string)
  Base58.base58_to_binary(string, :bitcoin).bytes
end

.base64_to_bytestream(base64) ⇒ StringIO

Creates a StringIO from a base64 string.

Parameters:

  • base64 (String)

    The base64 string to decode

Returns:

  • (StringIO)

    A StringIO object containing the decoded bytes

Since:

  • 0.0.1



18
19
20
# File 'lib/solace/utils/codecs.rb', line 18

def self.base64_to_bytestream(base64)
  StringIO.new(Base64.decode64(base64))
end

.binary_to_base58(binary) ⇒ String

Encodes a sequence of bytes in Base58 format

Parameters:

  • binary (String)

    The bytes to encode

Returns:

  • (String)

    The Base58 encoded string

Since:

  • 0.0.1



106
107
108
# File 'lib/solace/utils/codecs.rb', line 106

def self.binary_to_base58(binary)
  Base58.binary_to_base58(binary, :bitcoin)
end

.bytes_to_base58(bytes) ⇒ String

Encodes a sequence of bytes in Base58 format

Parameters:

  • bytes (String)

    The bytes to encode

Returns:

  • (String)

    The Base58 encoded string

Since:

  • 0.0.1



122
123
124
# File 'lib/solace/utils/codecs.rb', line 122

def self.bytes_to_base58(bytes)
  binary_to_base58(bytes.pack('C*'))
end

.decode_compact_u16(stream) ⇒ Integer

Decodes a compact-u16 (ShortVec) value from an IO-like object.

Reads bytes one at a time, accumulating the result until the MSB is 0.

Parameters:

  • stream (IO, StringIO)

    The input to read bytes from.

Returns:

  • (Integer, Integer)

    The decoded value and the number of bytes read.

Since:

  • 0.0.1



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/solace/utils/codecs.rb', line 66

def self.decode_compact_u16(stream)
  value = 0
  shift = 0
  bytes_read = 0

  loop do
    byte = stream.read(1)
    raise EOFError, 'Unexpected end of input while decoding compact-u16' unless byte

    byte = byte.ord
    value |= (byte & 0x7F) << shift
    bytes_read += 1
    break if byte.nobits?(0x80)

    shift += 7
  end

  [value, bytes_read]
end

.decode_le_u64(stream) ⇒ Integer

Decodes a little-endian u64 value from a sequence of bytes

Parameters:

  • stream (IO, StringIO)

    The input to read bytes from.

Returns:

  • (Integer)

    The decoded u64 value

Since:

  • 0.0.1



98
99
100
# File 'lib/solace/utils/codecs.rb', line 98

def self.decode_le_u64(stream)
  stream.read(8).unpack1('Q<')
end

.encode_compact_u16(u16) ⇒ String

Encodes a compact-u16 value in a compact form (shortvec)

Parameters:

  • u16 (Integer)

    The compact-u16 value to encode

Returns:

  • (String)

    The compactly encoded compact-u16 value

Since:

  • 0.0.1



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/solace/utils/codecs.rb', line 26

def self.encode_compact_u16(u16)
  out = []

  loop do
    # In general, n >> 7 shifts the bits of n to the right by
    # 7 positions, effectively dividing n by 128 and discarding
    # the remainder (integer division). This is commonly used in
    # encoding schemes to process one "byte" (7 bits) at a time.
    if (u16 >> 7).zero?
      out << u16
      break
    end
    # The expression out << ((n & 0x7F) | 0x80) is used in variable-length
    # integer encoding, such as the compact-u16 encoding.
    #
    # n & 0x7F:
    #   - 0x7F is 127 in decimal, or 0111 1111 in binary.
    #   - n & 0x7F masks out all but the lowest 7 bits of n. This extracts the least significant 7 bits of n.
    #
    # (n & 0x7F) | 0x80:
    #   - 0x80 is 128 in decimal, or 1000 0000 in binary.
    #   - | (bitwise OR) sets the highest bit (the 8th bit) to 1.
    #   - This is a signal that there are more bytes to come in the encoding (i.e., the value hasn't been fully
    #     encoded yet).
    #
    # out << ...:
    #   - This appends the resulting byte to the out array.
    out << ((u16 & 0x7F) | 0x80)
    u16 >>= 7
  end

  out.pack('C*')
end

.encode_le_u64(u64) ⇒ String

Encodes a u64 value in little-endian format

Parameters:

  • u64 (Integer)

    The u64 value to encode

Returns:

  • (String)

    The little-endian encoded u64 value

Since:

  • 0.0.1



90
91
92
# File 'lib/solace/utils/codecs.rb', line 90

def self.encode_le_u64(u64)
  [u64].pack('Q<') # 64-bit little-endian
end

.valid_base58?(string) ⇒ Boolean

Checks if a string is a valid Base58 string

Parameters:

  • string (String)

    The string to check

Returns:

  • (Boolean)

    True if the string is a valid Base58 string, false otherwise

Since:

  • 0.0.1



138
139
140
141
142
143
144
145
# File 'lib/solace/utils/codecs.rb', line 138

def self.valid_base58?(string)
  return false if string.nil? || string.empty?

  Base58.decode(string)
  true
rescue StandardError => _e
  false
end