Class: OpenC3::StructureItem

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/openc3/packets/structure_item.rb,
ext/openc3/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, :ARRAY, :OBJECT to those defined by BinaryAccessor

[:INT, :UINT, :FLOAT, :STRING, :BLOCK, :BOOL, :OBJECT, :ARRAY, :ANY, :DERIVED]
@@create_index =
0

Instance Attribute 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)


122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/openc3/packets/structure_item.rb', line 122

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.key = name # Key defaults to name as given (not upcased)
  self.endianness = endianness
  self.data_type = data_type
  self.bit_offset = bit_offset
  @original_bit_offset = self.bit_offset
  self.bit_size = bit_size
  @original_bit_size = self.bit_size
  self.array_size = array_size
  @original_array_size = self.array_size
  self.overflow = overflow
  self.overlap = false
  self.variable_bit_size = nil
  self.hidden = false
  self.parent_item = nil
  self.structure = nil
  @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



81
82
83
# File 'lib/openc3/packets/structure_item.rb', line 81

def array_size
  @array_size
end

#bit_offsetInteger

Indicates where in the binary buffer the StructureItem exists.

Returns:

  • (Integer)

    0 based bit offset



45
46
47
# File 'lib/openc3/packets/structure_item.rb', line 45

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



55
56
57
# File 'lib/openc3/packets/structure_item.rb', line 55

def bit_size
  @bit_size
end

#create_indexInteger (readonly)

Returns Incrementing value that shows relative order items are created.

Returns:

  • (Integer)

    Incrementing value that shows relative order items are created



99
100
101
# File 'lib/openc3/packets/structure_item.rb', line 99

def create_index
  @create_index
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. :ARRAY is an array of unknown types :OBJECT is a Hash type object

Returns:



70
71
72
# File 'lib/openc3/packets/structure_item.rb', line 70

def data_type
  @data_type
end

#endiannessSymbol

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



74
75
76
# File 'lib/openc3/packets/structure_item.rb', line 74

def endianness
  @endianness
end

#hiddenBoolean

Returns Indicates if item should be listed in items and in read all type methods.

Returns:

  • (Boolean)

    Indicates if item should be listed in items and in read all type methods



102
103
104
# File 'lib/openc3/packets/structure_item.rb', line 102

def hidden
  @hidden
end

#keyObject

Key is used to access into nested structures during decom if applicable



41
42
43
# File 'lib/openc3/packets/structure_item.rb', line 41

def key
  @key
end

#nameString

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

Returns:

  • (String)

    Name of the item



38
39
40
# File 'lib/openc3/packets/structure_item.rb', line 38

def name
  @name
end

#original_array_sizeInteger

Original array size when the structure is first defined

Returns:

  • (Integer)

    total array size in bits



85
86
87
# File 'lib/openc3/packets/structure_item.rb', line 85

def original_array_size
  @original_array_size
end

#original_bit_offsetInteger

Original bit offset when the structure is first defined Will reflect the bit offset with all variable sized items at their minimum size

Returns:

  • (Integer)

    0 based bit offset



51
52
53
# File 'lib/openc3/packets/structure_item.rb', line 51

def original_bit_offset
  @original_bit_offset
end

#original_bit_sizeInteger (readonly)

Original bit size when the structure is first defined

Returns:

  • (Integer)

    0 based bit offset



59
60
61
# File 'lib/openc3/packets/structure_item.rb', line 59

def original_bit_size
  @original_bit_size
end

#overflowSymbol

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



90
91
92
# File 'lib/openc3/packets/structure_item.rb', line 90

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



93
94
95
# File 'lib/openc3/packets/structure_item.rb', line 93

def overlap
  @overlap
end

#parent_itemStructureItem

Returns Parent structure item.

Returns:



105
106
107
# File 'lib/openc3/packets/structure_item.rb', line 105

def parent_item
  @parent_item
end

#structureStructure

Returns Structure associated with item.

Returns:

  • (Structure)

    Structure associated with item



108
109
110
# File 'lib/openc3/packets/structure_item.rb', line 108

def structure
  @structure
end

#variable_bit_sizeHash

Returns Variable bit size information.

Returns:

  • (Hash)

    Variable bit size information



96
97
98
# File 'lib/openc3/packets/structure_item.rb', line 96

def variable_bit_size
  @variable_bit_size
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.



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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/openc3/packets/structure_item.rb', line 258

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

  other_original_bit_offset = other.original_bit_offset

  # Derived items should be first in the list with multiple derived sorted
  # by create_index
  if @data_type == :DERIVED
    if other.data_type != :DERIVED
      return -1
    else
      if @create_index <= other.create_index
        return -1
      else
        return 1
      end
    end
  elsif other.data_type == :DERIVED
    return 1
  end

  # Handle non-derived items
  if ((@original_bit_offset >= 0) && (other_original_bit_offset >= 0)) || ((@original_bit_offset < 0) && (other_original_bit_offset < 0))
    # Both Have Same Sign
    if @original_bit_offset == other_original_bit_offset
      # New Variable Bit Size items are before regular items
      if @variable_bit_size
        if not other.variable_bit_size
          return -1
        end
        # If both variable_bit_size use create index
      elsif other.variable_bit_size
        return 1
      end

      if @create_index <= other.create_index
        return -1
      else
        return 1
      end
    elsif @original_bit_offset <= other_original_bit_offset
      return -1
    else
      return 1
    end
  else
    # Different Signs
    if @original_bit_offset < other_original_bit_offset
      return 1
    else
      return -1
    end
  end
end

#as_json(*a) ⇒ Object



323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/openc3/packets/structure_item.rb', line 323

def as_json(*a)
  hash = {}
  hash['name'] = self.name
  hash['key'] = self.key
  hash['bit_offset'] = self.original_bit_offset
  hash['bit_size'] = self.original_bit_size
  hash['data_type'] = self.data_type.to_s
  hash['endianness'] = self.endianness.to_s
  hash['overflow'] = self.overflow.to_s
  hash['overlap'] = self.overlap
  hash['create_index'] = self.create_index
  hash['hidden'] = self.hidden
  if self.original_array_size
    hash['array_size'] = self.original_array_size
  end
  if @variable_bit_size
    hash['variable_bit_size'] = @variable_bit_size
  end
  if self.parent_item
    hash['parent_item'] = self.parent_item.as_json
  end
  if self.structure
    hash['structure'] = self.structure.as_json
  end

  hash
end

#cloneObject Also known as: dup

Make a light weight clone of this item



315
316
317
318
319
320
# File 'lib/openc3/packets/structure_item.rb', line 315

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

#little_endian_bit_field?Boolean

Returns:

  • (Boolean)


351
352
353
354
355
356
357
358
359
360
# File 'lib/openc3/packets/structure_item.rb', line 351

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