Class: Cosmos::StructureItem

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/cosmos/packets/structure_item.rb,
ext/cosmos/ext/structure/structure.c

Overview

Maintains knowledge of an item in a Structure. Multiple StructureItems compose a Structure.

Constant Summary collapse

DATA_TYPES =

Valid data types adds :DERIVED to those defined by BinaryAccessor

BinaryAccessor::DATA_TYPES << :DERIVED
LARGE_BUFFER_SIZE_BITS =

A large buffer size in bits (1 Megabyte)

1024 * 1024 * 8
@@create_index =
0

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, bit_offset, bit_size, data_type, endianness, array_size = nil, overflow = :ERROR) ⇒ StructureItem

Create a StructureItem by setting all the attributes. It calls all the setter routines to do the attribute verification and then verifies the overall integrity.

Parameters:

  • name (String)

    The item name

  • bit_offset (Integer)

    Offset to the item starting at 0

  • bit_size (Integer)

    Size of the items in bits

  • data_type (Symbol)
  • endianness (Symbol)
  • array_size (Integer, nil) (defaults to: nil)

    Size of the array item in bits. For example, if the bit_size is 8, an array_size of 16 holds two values.

  • overflow (Symbol) (defaults to: :ERROR)


88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/cosmos/packets/structure_item.rb', line 88

def initialize(name, bit_offset, bit_size, data_type, endianness, array_size = nil, overflow = :ERROR)
  @structure_item_constructed = false
  # Assignment order matters due to verifications!
  self.name = name
  self.endianness = endianness
  self.data_type = data_type
  self.bit_offset = bit_offset
  self.bit_size = bit_size
  self.array_size = array_size
  self.overflow = overflow
  self.overlap = false
  @create_index = @@create_index
  @@create_index += 1
  @structure_item_constructed = true
  verify_overall()
end

Instance Attribute Details

#array_sizeInteger?

The total number of bits in the binary buffer that create the array. The array size can be set to nil to indicate the StructureItem is not represented as an array. For example, if the bit_size is 8 bits, an array_size of 16 would result in two 8 bit items.

Returns:

  • (Integer, nil)

    Array size of the item in bits



63
64
65
# File 'lib/cosmos/packets/structure_item.rb', line 63

def array_size
  @array_size
end

#bit_offsetInteger

Indicates where in the binary buffer the StructureItem exists.

Returns:

  • (Integer)

    0 based bit offset



39
40
41
# File 'lib/cosmos/packets/structure_item.rb', line 39

def bit_offset
  @bit_offset
end

#bit_sizeInteger

The number of bits which represent this StructureItem in the binary buffer.

Returns:

  • (Integer)

    Size in bits



43
44
45
# File 'lib/cosmos/packets/structure_item.rb', line 43

def bit_size
  @bit_size
end

#data_typeSymbol

The data type is what kind of data this StructureItem represents when extracted from the binary buffer. :INT and :UINT are turned into Integers (Ruby Fixnum). :FLOAT are turned into floating point numbers (Ruby Float). :STRING is turned into an ASCII string (Ruby String). :BLOCK is turned into a binary buffer (Ruby String). :DERIVED is interpreted by the subclass and can result in any type.

Returns:



52
53
54
# File 'lib/cosmos/packets/structure_item.rb', line 52

def data_type
  @data_type
end

#endiannessSymbol

Used to interpret how to read the item from the binary data buffer.



56
57
58
# File 'lib/cosmos/packets/structure_item.rb', line 56

def endianness
  @endianness
end

#nameString

Name is used by higher level classes to access the StructureItem.

Returns:

  • (String)

    Name of the item



35
36
37
# File 'lib/cosmos/packets/structure_item.rb', line 35

def name
  @name
end

#overflowSymbol

How to handle overflow for :INT, :UINT, :STRING, and :BLOCK data types Note: Has no meaning for :FLOAT data types



68
69
70
# File 'lib/cosmos/packets/structure_item.rb', line 68

def overflow
  @overflow
end

#overlapBoolean

Returns Whether this structure item can overlap another item in the same packet.

Returns:

  • (Boolean)

    Whether this structure item can overlap another item in the same packet



71
72
73
# File 'lib/cosmos/packets/structure_item.rb', line 71

def overlap
  @overlap
end

Class Method Details

.from_json(hash) ⇒ Object



295
296
297
298
299
300
301
302
# File 'lib/cosmos/packets/structure_item.rb', line 295

def self.from_json(hash)
  # Convert strings to symbols
  endianness = hash['endianness'] ? hash['endianness'].intern : nil
  data_type = hash['data_type'] ? hash['data_type'].intern : nil
  overflow = hash['overflow'] ? hash['overflow'].intern : nil
  StructureItem.new(hash['name'], hash['bit_offset'], hash['bit_size'], data_type,
    endianness, hash['array_size'], overflow)
end

Instance Method Details

#<=>(other_item) ⇒ Object

Comparison Operator based on bit_offset. This means that StructureItems with different names or bit sizes are equal if they have the same bit offset.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/cosmos/packets/structure_item.rb', line 220

def <=>(other_item)
  return nil unless other_item.kind_of?(StructureItem)

  other_bit_offset = other_item.bit_offset
  other_bit_size = other_item.bit_size

  # Handle same bit offset case
  if (@bit_offset == 0) && (other_bit_offset == 0)
    # Both bit_offsets are 0 so sort by bit_size
    # This allows derived items with bit_size of 0 to be listed first
    # Compare based on bit size then create index
    if @bit_size == other_bit_size
      if @create_index
        if @create_index <= other_item.create_index
          return -1
        else
          return 1
        end
      else
        return 0
      end
    elsif @bit_size < other_bit_size
      return -1
    else
      return 1
    end
  end

  # Handle different bit offsets
  if ((@bit_offset >= 0) && (other_bit_offset >= 0)) || ((@bit_offset < 0) && (other_bit_offset < 0))
    # Both Have Same Sign
    if @bit_offset == other_bit_offset
      if @create_index
        if @create_index <= other_item.create_index
          return -1
        else
          return 1
        end
      else
        return 0
      end
    elsif @bit_offset <= other_bit_offset
      return -1
    else
      return 1
    end
  else
    # Different Signs
    if @bit_offset == other_bit_offset
      if @create_index
        if @create_index < other_item.create_index
          return -1
        else
          return 1
        end
      else
        return 0
      end
    elsif @bit_offset < other_bit_offset
      return 1
    else
      return -1
    end
  end
end

#as_jsonObject



304
305
306
307
308
309
310
311
312
313
314
# File 'lib/cosmos/packets/structure_item.rb', line 304

def as_json
  hash = {}
  hash['name'] = self.name
  hash['bit_offset'] = self.bit_offset
  hash['bit_size'] = self.bit_size
  hash['data_type'] = self.data_type
  hash['endianness'] = self.endianness
  hash['array_size'] = self.array_size
  hash['overflow'] = self.overflow
  hash
end

#cloneObject Also known as: dup

Make a light weight clone of this item



288
289
290
291
292
# File 'lib/cosmos/packets/structure_item.rb', line 288

def clone
  item = super()
  item.name = self.name.clone if self.name
  item
end

#create_indexObject



212
213
214
# File 'lib/cosmos/packets/structure_item.rb', line 212

def create_index
  @create_index.to_i
end

#little_endian_bit_field?Boolean

Returns:

  • (Boolean)


316
317
318
319
320
321
322
323
324
325
# File 'lib/cosmos/packets/structure_item.rb', line 316

def little_endian_bit_field?
  return false unless @endianness == :LITTLE_ENDIAN
  return false unless @data_type == :INT || @data_type == :UINT
  # If we're not byte aligned we're a bit field
  return true unless (@bit_offset % 8) == 0
  # If we don't have an even number of bytes we're a bit field
  return true unless even_byte_multiple()

  false
end