Class: Takagi::CBOR::Decoder

Inherits:
Object
  • Object
show all
Defined in:
lib/takagi/cbor/decoder.rb

Overview

CBOR Decoder (RFC 8949)

Decodes CBOR binary format to Ruby objects. Optimized for IoT/CoAP workloads with minimal footprint.

Supported types:

  • Integers → Integer

  • Floats → Float

  • Text strings → String (UTF-8)

  • Byte strings → String (binary)

  • Arrays → Array

  • Maps → Hash (string keys)

  • Booleans → true/false

  • null → nil

  • Timestamps (tag 1) → Time

Security features:

  • Max nesting depth (prevents stack overflow)

  • Max collection size (prevents memory exhaustion)

Examples:

Basic decoding

Decoder.decode("\xA2ktempera...")
# => { "temperature" => 25.5, "humidity" => 60 }

Constant Summary collapse

MAJOR_TYPE_UNSIGNED_INT =

CBOR Major Types (RFC 8949 §3)

0
MAJOR_TYPE_NEGATIVE_INT =
1
MAJOR_TYPE_BYTE_STRING =
2
MAJOR_TYPE_TEXT_STRING =
3
MAJOR_TYPE_ARRAY =
4
MAJOR_TYPE_MAP =
5
MAJOR_TYPE_TAG =
6
MAJOR_TYPE_SIMPLE =
7
SIMPLE_FALSE =

Simple values (RFC 8949 §3.3)

20
SIMPLE_TRUE =
21
SIMPLE_NULL =
22
SIMPLE_FLOAT16 =
25
SIMPLE_FLOAT32 =
26
SIMPLE_FLOAT64 =
27
MAX_NESTING_DEPTH =

Security limits

100
MAX_COLLECTION_SIZE =
100_000
TAG_EPOCH_TIMESTAMP =

Tag values

1
MAJOR_TYPE_HANDLERS =
{
  MAJOR_TYPE_UNSIGNED_INT => :handle_unsigned_int,
  MAJOR_TYPE_NEGATIVE_INT => :handle_negative_int,
  MAJOR_TYPE_BYTE_STRING => :read_bytes,
  MAJOR_TYPE_TEXT_STRING => :read_string,
  MAJOR_TYPE_ARRAY => :read_array,
  MAJOR_TYPE_MAP => :read_map,
  MAJOR_TYPE_TAG => :read_tagged,
  MAJOR_TYPE_SIMPLE => :read_simple
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bytes) ⇒ Decoder

Initialize decoder with CBOR bytes

Parameters:

  • bytes (String)

    CBOR-encoded binary string



84
85
86
87
88
# File 'lib/takagi/cbor/decoder.rb', line 84

def initialize(bytes)
  @bytes = bytes.b
  @pos = 0
  @depth = 0
end

Class Method Details

.decode(bytes) ⇒ Object

Decode CBOR bytes to Ruby object

Examples:

Decoder.decode("\x18\x2A")         # => 42
Decoder.decode("ehello")           # => "hello"
Decoder.decode("\x83\x01\x02\x03") # => [1, 2, 3]

Parameters:

  • bytes (String)

    CBOR-encoded binary string

Returns:

  • (Object)

    Decoded Ruby object

Raises:



76
77
78
# File 'lib/takagi/cbor/decoder.rb', line 76

def decode(bytes)
  new(bytes).decode
end

Instance Method Details

#decodeObject

Decode CBOR bytes to Ruby object

Returns:

  • (Object)

    Decoded Ruby object

Raises:



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/takagi/cbor/decoder.rb', line 94

def decode
  check_depth!

  major_type, value = read_type_and_value
  handler = MAJOR_TYPE_HANDLERS[major_type]
  raise DecodeError, "Unknown major type: #{major_type}" unless handler

  send(handler, value)
rescue DecodeError, UnsupportedError
  raise
rescue StandardError => e
  raise DecodeError, "Decoding failed at position #{@pos}: #{e.message}"
end