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)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/openc3/packets/structure_item.rb', line 93

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



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

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



49
50
51
# File 'lib/openc3/packets/structure_item.rb', line 49

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:



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

def data_type
  @data_type
end

#endiannessSymbol

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



64
65
66
# File 'lib/openc3/packets/structure_item.rb', line 64

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

#overflowSymbol

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



76
77
78
# File 'lib/openc3/packets/structure_item.rb', line 76

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



79
80
81
# File 'lib/openc3/packets/structure_item.rb', line 79

def overlap
  @overlap
end

Class Method Details

.from_json(hash) ⇒ Object



291
292
293
294
295
296
297
298
299
300
# File 'lib/openc3/packets/structure_item.rb', line 291

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



216
217
218
219
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
# File 'lib/openc3/packets/structure_item.rb', line 216

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_json(*a) ⇒ Object



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

def as_json(*a)
  hash = {}
  hash['name'] = self.name
  hash['key'] = self.key
  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



284
285
286
287
288
# File 'lib/openc3/packets/structure_item.rb', line 284

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

#create_indexObject



208
209
210
# File 'lib/openc3/packets/structure_item.rb', line 208

def create_index
  @create_index.to_i
end

#little_endian_bit_field?Boolean

Returns:

  • (Boolean)


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

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