Module: BinaryCodec

Defined in:
lib/binary-codec/utilities.rb,
lib/binary-codec/types/blob.rb,
lib/binary-codec/types/hash.rb,
lib/binary-codec/types/uint.rb,
lib/binary-codec/types/issue.rb,
lib/binary-codec/binary_codec.rb,
lib/binary-codec/enums/fields.rb,
lib/binary-codec/types/amount.rb,
lib/binary-codec/types/currency.rb,
lib/binary-codec/types/path_set.rb,
lib/binary-codec/types/st_array.rb,
lib/binary-codec/enums/constants.rb,
lib/binary-codec/types/st_object.rb,
lib/binary-codec/types/vector256.rb,
lib/binary-codec/types/account_id.rb,
lib/binary-codec/enums/definitions.rb,
lib/binary-codec/serdes/bytes_list.rb,
lib/binary-codec/types/xchain_bridge.rb,
lib/binary-codec/serdes/binary_parser.rb,
lib/binary-codec/types/serialized_type.rb,
lib/binary-codec/serdes/binary_serializer.rb

Defined Under Namespace

Classes: AccountId, Amount, BinaryParser, BinarySerializer, Blob, BytesList, ComparableSerializedType, Currency, Definitions, FieldHeader, FieldInfo, FieldInstance, FieldLookup, Hash, Hash128, Hash160, Hash192, Hash256, Int32, Int64, Issue, PathSet, STArray, STObject, SerializedType, Uint, Uint128, Uint16, Uint160, Uint192, Uint256, Uint32, Uint384, Uint512, Uint64, Uint8, Uint96, Vector256, XChainBridge

Constant Summary collapse

HASH_PREFIX =

Hash prefixes for serialization.

{
  transaction_sig: 0x53545800, # 'STX\0'
  transaction_multi_sig: 0x534D5400, # 'SMT\0'
  validation: 0x56414C00, # 'VAL\0'
  proposal: 0x50525000 # 'PRP\0'
}.freeze
TYPE_WIDTH =
2
LEDGER_ENTRY_WIDTH =
2
TRANSACTION_TYPE_WIDTH =
2
TRANSACTION_RESULT_WIDTH =
1

Class Method Summary collapse

Class Method Details

.aligned16?(array) ⇒ Boolean

Determine if an array is 16-bit aligned

Returns:

  • (Boolean)


73
74
75
# File 'lib/binary-codec/utilities.rb', line 73

def self.aligned16?(array)
  (array.length % 2).zero?
end

.aligned32?(array) ⇒ Boolean

Determine if an array is 32-bit aligned

Returns:

  • (Boolean)


78
79
80
# File 'lib/binary-codec/utilities.rb', line 78

def self.aligned32?(array)
  (array.length % 4).zero?
end

.binary_to_json(hex) ⇒ Hash

Converts a hex string to its JSON representation.

Parameters:

  • hex (String)

    The hex string to convert.

Returns:

  • (Hash)

    The decoded JSON object.



25
26
27
28
29
# File 'lib/binary-codec/binary_codec.rb', line 25

def binary_to_json(hex)
  parser = make_parser(hex)
  st_object = SerializedType.get_type_by_name('STObject')
  JSON.parse(st_object.from_parser(parser).to_json)
end

.compare(array1, array2) ⇒ Object

Compare two arrays of any type



42
43
44
45
46
47
48
49
50
51
# File 'lib/binary-codec/utilities.rb', line 42

def self.compare(array1, array2)
  raise 'Cannot compare arrays of different length' if array1.length != array2.length

  array1.each_with_index do |value, i|
    return 1 if value > array2[i]
    return -1 if value < array2[i]
  end

  0
end

.compare16(array1, array2) ⇒ Object

Compares two 16-bit aligned arrays



59
60
61
62
63
# File 'lib/binary-codec/utilities.rb', line 59

def self.compare16(array1, array2)
  raise 'Array lengths must be even for 16-bit alignment' unless (array1.length % 2).zero? && (array2.length % 2).zero?

  array1.pack('C*').unpack('n*') <=> array2.pack('C*').unpack('n*')
end

.compare32(array1, array2) ⇒ Object

Compares two 32-bit aligned arrays



66
67
68
69
70
# File 'lib/binary-codec/utilities.rb', line 66

def self.compare32(array1, array2)
  raise 'Array lengths must be divisible by 4 for 32-bit alignment' unless (array1.length % 4).zero? && (array2.length % 4).zero?

  array1.pack('C*').unpack('N*') <=> array2.pack('C*').unpack('N*')
end

.compare8(array1, array2) ⇒ Object

Compares two 8-bit aligned arrays



54
55
56
# File 'lib/binary-codec/utilities.rb', line 54

def self.compare8(array1, array2)
  compare(array1, array2)
end

.equal(array1, array2) ⇒ Object

Compare two byte arrays



36
37
38
39
# File 'lib/binary-codec/utilities.rb', line 36

def self.equal(array1, array2)
  return false unless array1.length == array2.length
  array1 == array2
end

.is_valid_x_address?(x_address) ⇒ Boolean

TODO: Marked for overhaul

Returns:

  • (Boolean)


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/binary-codec/utilities.rb', line 83

def self.is_valid_x_address?(x_address)
  return false unless x_address.is_a?(String) && x_address.start_with?('X')

  begin
    decoded = decode_x_address(x_address)
    return false if decoded[:account_id].nil? || decoded[:account_id].length != 20

    tag = decoded[:tag]
    return false if tag && (tag < 0 || tag > MAX_32_BIT_UNSIGNED_INT)

    true
  rescue StandardError
    false
  end
end

.json_to_binary(json) ⇒ String

Converts a JSON object to its binary representation.

Parameters:

  • json (Hash)

    The JSON object to convert.

Returns:

  • (String)

    The serialized hex string.



34
35
36
37
# File 'lib/binary-codec/binary_codec.rb', line 34

def json_to_binary(json)
  st_object = SerializedType.get_type_by_name('STObject')
  st_object.from(json).to_hex
end

.make_parser(bytes, definitions = nil) ⇒ BinaryParser

Creates a BinaryParser for the given bytes.

Parameters:

  • bytes (String, Array<Integer>)

    The bytes to parse (hex string or byte array).

  • definitions (Definitions, nil) (defaults to: nil)

    Optional definitions.

Returns:



18
19
20
# File 'lib/binary-codec/binary_codec.rb', line 18

def make_parser(bytes, definitions = nil)
  BinaryParser.new(bytes.is_a?(String) ? bytes : bytes_to_hex(bytes))
end

.read_uint16be(array, offset = 0) ⇒ Object

Read an unsigned 16-bit integer in big-endian format



11
12
13
# File 'lib/binary-codec/utilities.rb', line 11

def self.read_uint16be(array, offset = 0)
  (array[offset] << 8) + array[offset + 1]
end

.read_uint32be(array, offset = 0) ⇒ Object

Read an unsigned 32-bit integer in big-endian format



22
23
24
25
# File 'lib/binary-codec/utilities.rb', line 22

def self.read_uint32be(array, offset = 0)
  (array[offset] << 24) + (array[offset + 1] << 16) +
    (array[offset + 2] << 8) + array[offset + 3]
end

.signing_data(transaction, prefix = HASH_PREFIX[:transaction_sig], opts = {}) ⇒ Array<Integer>

Generates signing data for a transaction.

Parameters:

  • transaction (Hash)

    The transaction to serialize.

  • prefix (Integer) (defaults to: HASH_PREFIX[:transaction_sig])

    The prefix to add to the serialized data.

  • opts (Hash) (defaults to: {})

    Optional settings (e.g., :definitions, :signing_fields_only).

Returns:

  • (Array<Integer>)

    The serialized signing data.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/binary-codec/binary_codec.rb', line 44

def signing_data(transaction, prefix = HASH_PREFIX[:transaction_sig], opts = {})
  # 1. Start with the prefix bytes
  prefix_bytes = int_to_bytes(prefix, 4)

  # 2. Serialize the object, only including signing fields
  st_object_class = SerializedType.get_type_by_name('STObject')

  filter = if opts[:signing_fields_only]
             lambda { |field_name| Definitions.instance.get_field_instance(field_name).is_signing_field }
           else
             nil
           end

  serialized_bytes = st_object_class.from(transaction, filter).to_bytes

  prefix_bytes + serialized_bytes
end

.write_uint16be(array, value, offset = 0) ⇒ Object

Write a 16-bit unsigned integer in big-endian format



16
17
18
19
# File 'lib/binary-codec/utilities.rb', line 16

def self.write_uint16be(array, value, offset = 0)
  array[offset] = (value >> 8) & 0xFF
  array[offset + 1] = value & 0xFF
end

.write_uint32be(buffer, value, offset = 0) ⇒ Object

Write an unsigned 32-bit integer to a buffer in big-endian format



28
29
30
31
32
33
# File 'lib/binary-codec/utilities.rb', line 28

def self.write_uint32be(buffer, value, offset = 0)
  buffer[offset] = (value >> 24) & 0xFF
  buffer[offset + 1] = (value >> 16) & 0xFF
  buffer[offset + 2] = (value >> 8) & 0xFF
  buffer[offset + 3] = value & 0xFF
end

.write_uint8(array, value, offset = 0) ⇒ Object

Write an 8-bit unsigned integer



6
7
8
# File 'lib/binary-codec/utilities.rb', line 6

def self.write_uint8(array, value, offset = 0)
  array[offset] = value & 0xFF
end