Class: CMF::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/cmf/builder.rb

Overview

Instances of the Builder class can create CMF messages.

Basic usage:

b = CMF::Builder.new
b.add(0, "value0")
b.add(1, "value1")

The CMF message can be output in octet form (one character per byte):

b.to_octet

or hex form (two characters per byte):

b.to_hex

Method calls can be chained together:

CMF::Builder.new.add(0, "value0").add(1, "value1").to_hex

A dictionary can be used to refer to tags by name rather than number:

b = CMF::Builder.new([:tag0, :tag1])
b.add(:tag0, "value0")
b.add(:tag1, "value1")

Messages can be built from an object:

b = CMF::Builder.new([:tag0, :tag1])
b.build({tag0: "value0", tag1: "value1"})

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dictionary = nil) ⇒ Builder

Creates a new instance of CMF::Builder.

Parameters:

  • dictionary (Hash, Array) (defaults to: nil)

    Optional. The dictionary mapping tag names to numbers. See Dictionary.validate.


41
42
43
44
# File 'lib/cmf/builder.rb', line 41

def initialize(dictionary = nil)
  @dictionary = Dictionary.validate(dictionary)
  reset
end

Instance Attribute Details

#dictionaryHash (readonly)

Returns The dictionary mapping tag names to numbers.

Returns:

  • (Hash)

    The dictionary mapping tag names to numbers.


35
36
37
# File 'lib/cmf/builder.rb', line 35

def dictionary
  @dictionary
end

Instance Method Details

#add(tag, value) ⇒ Builder

Adds a (tag, value) pair to the CMF message.

Parameters:

  • tag (Integer, Object)

    Must be an integer or a key in the dictionary.

  • value (String, Integer, Boolean, Float, Object)

    A string, integer, boolean, or float. All other types will be converted to a string by calling the to_s method on them. Strings with binary (ASCII-8BIT) encoding will be added as a Type::BYTE_ARRAY. All other strings will be added as a Type::STRING.

Returns:


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/cmf/builder.rb', line 82

def add(tag, value)
  case value
  when Integer
    add_int(tag, value)
  when String
    if value.encoding == Encoding::BINARY
      add_bytes(tag, value)
    else
      add_string(tag, value)
    end
  when TrueClass, FalseClass
    add_bool(tag, value)
  when Float
    add_double(tag, value)
  else
    add_string(tag, value)
  end

  self
end

#add_bool(tag, value) ⇒ Builder

Adds a (tag, boolean value) pair to the CMF message.

Parameters:

  • tag (Integer, Object)

    Must be an integer or a key in the dictionary.

  • value (Boolean, Object)

    A boolean value. Non-boolean values will be converted to boolean by testing their truthiness.

Returns:


159
160
161
162
163
# File 'lib/cmf/builder.rb', line 159

def add_bool(tag, value)
  write_tag(tag, value ? Type::BOOL_TRUE : Type::BOOL_FALSE)

  self
end

#add_bytes(tag, value) ⇒ Builder

Adds a (tag, byte_array value) pair to the CMF message.

Parameters:

  • tag (Integer, Object)

    Must be an integer or a key in the dictionary.

  • value (String, Object)

    A string value. Non-string values will be converted to strings by calling the to_s method on them.

Returns:


144
145
146
147
148
149
150
151
# File 'lib/cmf/builder.rb', line 144

def add_bytes(tag, value)
  value = value.to_s
  write_tag(tag, Type::BYTE_ARRAY)
  Varint.serialize(@io, value.bytesize)
  @io << value

  self
end

#add_double(tag, value) ⇒ Builder Also known as: add_float

Adds a (tag, float value) pair to the CMF message.

Parameters:

  • tag (Integer, Object)

    Must be an integer or a key in the dictionary.

  • value (Float, Object)

    A float value. Non-float values will be converted to floats by calling the to_f method on them.

Returns:


171
172
173
174
175
176
# File 'lib/cmf/builder.rb', line 171

def add_double(tag, value)
  write_tag(tag, Type::DOUBLE)
  @io << [value.to_f].pack('E')

  self
end

#add_int(tag, value) ⇒ Builder

Adds a (tag, integer value) pair to the CMF message.

Parameters:

  • tag (Integer, Object)

    Must be an integer or a key in the dictionary.

  • value (Integer, Object)

    An integer value. Non-integer values will be converted to integers by calling the to_i method on them.

Returns:


109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/cmf/builder.rb', line 109

def add_int(tag, value)
  value = value.to_i
  type = Type::POSITIVE_NUMBER
  if value < 0
    type = Type::NEGATIVE_NUMBER
    value *= -1
  end

  write_tag(tag, type)
  Varint.serialize(@io, value.abs)

  self
end

#add_string(tag, value) ⇒ Builder

Adds a (tag, string value) pair to the CMF message.

Parameters:

  • tag (Integer, Object)

    Must be an integer or a key in the dictionary.

  • value (String, Object)

    A string value. Non-string values will be converted to strings by calling the to_s method on them.

Returns:


129
130
131
132
133
134
135
136
# File 'lib/cmf/builder.rb', line 129

def add_string(tag, value)
  value = value.to_s
  write_tag(tag, Type::STRING)
  Varint.serialize(@io, value.bytesize)
  @io << value

  self
end

#build(obj) ⇒ Builder

Adds multiple (tag, value) pairs to the CMF message.

Parameters:

  • obj (Hash, #each)

    The object containing (tag, value) pairs. Can be a hash, or any object that responds to .each and yields (tag, value) pairs. Calls #add for each (tag, value) pair.

Returns:

See Also:


62
63
64
65
66
67
68
69
70
# File 'lib/cmf/builder.rb', line 62

def build(obj)
  obj.each do |key, values|
    Array(values).each do |value|
      add(key, value)
    end
  end

  self
end

#resetBuilder

Resets the CMF message.

Returns:


49
50
51
52
53
# File 'lib/cmf/builder.rb', line 49

def reset
  @io = StringIO.new(String.new) # A StringIO with ASCII-8BIT encoding

  self
end

#to_hexString

Returns A hex string, every 2 characters representing one byte of the CMF message.

Returns:

  • (String)

    A hex string, every 2 characters representing one byte of the CMF message.


187
188
189
# File 'lib/cmf/builder.rb', line 187

def to_hex
  to_octet.unpack('H*').first
end

#to_octetString

Returns An octet string, each character representing one byte of the CMF message.

Returns:

  • (String)

    An octet string, each character representing one byte of the CMF message.


181
182
183
# File 'lib/cmf/builder.rb', line 181

def to_octet
  @io.string
end