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

BinaryAccessor::DATA_TYPES << :DERIVED << :ARRAY << :OBJECT
@@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)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/openc3/packets/structure_item.rb', line 110

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
  @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

#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

#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

#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

Class Method Details

.from_json(hash) ⇒ Object



324
325
326
327
328
329
330
331
332
333
334
# File 'lib/openc3/packets/structure_item.rb', line 324

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
  si = StructureItem.new(hash['name'], hash['bit_offset'], hash['bit_size'], data_type,
    endianness, hash['array_size'], overflow)
  si.key = hash['key'] || hash['name']
  si.variable_bit_size = hash['variable_bit_size']
  si
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.



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
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
312
313
# File 'lib/openc3/packets/structure_item.rb', line 249

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

  other_bit_offset = other.bit_offset
  other_bit_size = other.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.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.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.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_json(*a) ⇒ Object



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/openc3/packets/structure_item.rb', line 336

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
  hash['endianness'] = self.endianness
  hash['array_size'] = self.original_array_size
  hash['overflow'] = self.overflow
  if @variable_bit_size
    hash['variable_bit_size'] = @variable_bit_size
  end
  hash
end

#cloneObject Also known as: dup

Make a light weight clone of this item



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

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

#create_indexObject



241
242
243
# File 'lib/openc3/packets/structure_item.rb', line 241

def create_index
  @create_index.to_i
end

#little_endian_bit_field?Boolean

Returns:

  • (Boolean)


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

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