openc3 5.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +18 -0
- data/Guardfile +35 -0
- data/LICENSE.txt +727 -0
- data/README.md +37 -0
- data/Rakefile +131 -0
- data/bin/cstol_converter +1178 -0
- data/bin/openc3cli +531 -0
- data/bin/rubysloc +139 -0
- data/data/config/_array_params.yaml +23 -0
- data/data/config/_id_items.yaml +24 -0
- data/data/config/_id_params.yaml +58 -0
- data/data/config/_interfaces.yaml +214 -0
- data/data/config/_interfaces.yaml.err +1017 -0
- data/data/config/_items.yaml +20 -0
- data/data/config/_params.yaml +60 -0
- data/data/config/cmd_tlm_server.yaml +136 -0
- data/data/config/command.yaml +44 -0
- data/data/config/command_modifiers.yaml +160 -0
- data/data/config/command_telemetry.yaml +3 -0
- data/data/config/interface_modifiers.yaml +104 -0
- data/data/config/item_modifiers.yaml +221 -0
- data/data/config/microservice.yaml +78 -0
- data/data/config/param_item_modifiers.yaml +52 -0
- data/data/config/parameter_modifiers.yaml +200 -0
- data/data/config/plugins.yaml +80 -0
- data/data/config/protocols.yaml +290 -0
- data/data/config/screen.yaml +147 -0
- data/data/config/table_manager.yaml +89 -0
- data/data/config/table_parameter_modifiers.yaml +9 -0
- data/data/config/target.yaml +142 -0
- data/data/config/target_config.yaml +94 -0
- data/data/config/telemetry.yaml +87 -0
- data/data/config/telemetry_modifiers.yaml +159 -0
- data/data/config/tool.yaml +63 -0
- data/data/config/unknown.yaml +3 -0
- data/data/config/widgets.yaml +1505 -0
- data/ext/mkrf_conf.rb +49 -0
- data/ext/openc3/ext/array/array.c +122 -0
- data/ext/openc3/ext/array/extconf.rb +13 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
- data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
- data/ext/openc3/ext/config_parser/config_parser.c +280 -0
- data/ext/openc3/ext/config_parser/extconf.rb +13 -0
- data/ext/openc3/ext/crc/crc.c +351 -0
- data/ext/openc3/ext/crc/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
- data/ext/openc3/ext/packet/extconf.rb +13 -0
- data/ext/openc3/ext/packet/packet.c +318 -0
- data/ext/openc3/ext/platform/extconf.rb +13 -0
- data/ext/openc3/ext/platform/platform.c +134 -0
- data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
- data/ext/openc3/ext/string/extconf.rb +13 -0
- data/ext/openc3/ext/string/string.c +63 -0
- data/ext/openc3/ext/structure/structure.c +1719 -0
- data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
- data/ext/openc3/ext/telemetry/extconf.rb +13 -0
- data/ext/openc3/ext/telemetry/telemetry.c +336 -0
- data/lib/cosmos.rb +20 -0
- data/lib/cosmosc2.rb +20 -0
- data/lib/openc3/api/api.rb +39 -0
- data/lib/openc3/api/authorized_api.rb +30 -0
- data/lib/openc3/api/cmd_api.rb +451 -0
- data/lib/openc3/api/config_api.rb +58 -0
- data/lib/openc3/api/interface_api.rb +117 -0
- data/lib/openc3/api/limits_api.rb +375 -0
- data/lib/openc3/api/router_api.rb +117 -0
- data/lib/openc3/api/settings_api.rb +70 -0
- data/lib/openc3/api/target_api.rb +78 -0
- data/lib/openc3/api/tlm_api.rb +455 -0
- data/lib/openc3/bridge/bridge.rb +54 -0
- data/lib/openc3/bridge/bridge_config.rb +167 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
- data/lib/openc3/config/config_parser.rb +549 -0
- data/lib/openc3/config/meta_config_parser.rb +74 -0
- data/lib/openc3/conversions/conversion.rb +70 -0
- data/lib/openc3/conversions/generic_conversion.rb +83 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
- data/lib/openc3/conversions/processor_conversion.rb +70 -0
- data/lib/openc3/conversions/received_count_conversion.rb +38 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
- data/lib/openc3/conversions.rb +34 -0
- data/lib/openc3/core_ext/array.rb +416 -0
- data/lib/openc3/core_ext/binding.rb +29 -0
- data/lib/openc3/core_ext/class.rb +72 -0
- data/lib/openc3/core_ext/exception.rb +61 -0
- data/lib/openc3/core_ext/file.rb +83 -0
- data/lib/openc3/core_ext/hash.rb +37 -0
- data/lib/openc3/core_ext/io.rb +134 -0
- data/lib/openc3/core_ext/kernel.rb +42 -0
- data/lib/openc3/core_ext/math.rb +128 -0
- data/lib/openc3/core_ext/matrix.rb +156 -0
- data/lib/openc3/core_ext/objectspace.rb +36 -0
- data/lib/openc3/core_ext/openc3_io.rb +57 -0
- data/lib/openc3/core_ext/range.rb +27 -0
- data/lib/openc3/core_ext/socket.rb +38 -0
- data/lib/openc3/core_ext/string.rb +389 -0
- data/lib/openc3/core_ext/stringio.rb +33 -0
- data/lib/openc3/core_ext/time.rb +508 -0
- data/lib/openc3/core_ext.rb +36 -0
- data/lib/openc3/interfaces/interface.rb +498 -0
- data/lib/openc3/interfaces/linc_interface.rb +475 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
- data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
- data/lib/openc3/interfaces/serial_interface.rb +94 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
- data/lib/openc3/interfaces/stream_interface.rb +81 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
- data/lib/openc3/interfaces/udp_interface.rb +169 -0
- data/lib/openc3/interfaces.rb +44 -0
- data/lib/openc3/io/buffered_file.rb +109 -0
- data/lib/openc3/io/io_multiplexer.rb +80 -0
- data/lib/openc3/io/json_api_object.rb +208 -0
- data/lib/openc3/io/json_drb.rb +335 -0
- data/lib/openc3/io/json_drb_object.rb +114 -0
- data/lib/openc3/io/json_drb_rack.rb +84 -0
- data/lib/openc3/io/json_rpc.rb +420 -0
- data/lib/openc3/io/openc3_snmp.rb +58 -0
- data/lib/openc3/io/posix_serial_driver.rb +156 -0
- data/lib/openc3/io/raw_logger.rb +167 -0
- data/lib/openc3/io/raw_logger_pair.rb +77 -0
- data/lib/openc3/io/serial_driver.rb +105 -0
- data/lib/openc3/io/stderr.rb +43 -0
- data/lib/openc3/io/stdout.rb +43 -0
- data/lib/openc3/io/udp_sockets.rb +194 -0
- data/lib/openc3/io/win32_serial_driver.rb +196 -0
- data/lib/openc3/logs/log_writer.rb +302 -0
- data/lib/openc3/logs/packet_log_constants.rb +62 -0
- data/lib/openc3/logs/packet_log_reader.rb +345 -0
- data/lib/openc3/logs/packet_log_writer.rb +299 -0
- data/lib/openc3/logs/text_log_writer.rb +68 -0
- data/lib/openc3/logs.rb +25 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
- data/lib/openc3/microservices/decom_microservice.rb +136 -0
- data/lib/openc3/microservices/interface_microservice.rb +532 -0
- data/lib/openc3/microservices/log_microservice.rb +108 -0
- data/lib/openc3/microservices/microservice.rb +204 -0
- data/lib/openc3/microservices/plugin_microservice.rb +43 -0
- data/lib/openc3/microservices/reaction_microservice.rb +541 -0
- data/lib/openc3/microservices/reducer_microservice.rb +313 -0
- data/lib/openc3/microservices/router_microservice.rb +44 -0
- data/lib/openc3/microservices/text_log_microservice.rb +84 -0
- data/lib/openc3/microservices/timeline_microservice.rb +363 -0
- data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
- data/lib/openc3/models/activity_model.rb +319 -0
- data/lib/openc3/models/auth_model.rb +65 -0
- data/lib/openc3/models/cvt_model.rb +185 -0
- data/lib/openc3/models/environment_model.rb +58 -0
- data/lib/openc3/models/gem_model.rb +137 -0
- data/lib/openc3/models/info_model.rb +31 -0
- data/lib/openc3/models/interface_model.rb +281 -0
- data/lib/openc3/models/interface_status_model.rb +117 -0
- data/lib/openc3/models/metadata_model.rb +139 -0
- data/lib/openc3/models/metric_model.rb +59 -0
- data/lib/openc3/models/microservice_model.rb +206 -0
- data/lib/openc3/models/microservice_status_model.rb +74 -0
- data/lib/openc3/models/model.rb +204 -0
- data/lib/openc3/models/note_model.rb +122 -0
- data/lib/openc3/models/notification_model.rb +40 -0
- data/lib/openc3/models/ping_model.rb +35 -0
- data/lib/openc3/models/plugin_model.rb +292 -0
- data/lib/openc3/models/process_status_model.rb +76 -0
- data/lib/openc3/models/reaction_model.rb +322 -0
- data/lib/openc3/models/reducer_model.rb +65 -0
- data/lib/openc3/models/router_model.rb +35 -0
- data/lib/openc3/models/router_status_model.rb +27 -0
- data/lib/openc3/models/scope_model.rb +153 -0
- data/lib/openc3/models/settings_model.rb +55 -0
- data/lib/openc3/models/sorted_model.rb +167 -0
- data/lib/openc3/models/target_model.rb +759 -0
- data/lib/openc3/models/timeline_model.rb +154 -0
- data/lib/openc3/models/tool_config_model.rb +38 -0
- data/lib/openc3/models/tool_model.rb +262 -0
- data/lib/openc3/models/trigger_group_model.rb +186 -0
- data/lib/openc3/models/trigger_model.rb +330 -0
- data/lib/openc3/models/widget_model.rb +138 -0
- data/lib/openc3/operators/microservice_operator.rb +128 -0
- data/lib/openc3/operators/operator.rb +277 -0
- data/lib/openc3/packets/binary_accessor.rb +1207 -0
- data/lib/openc3/packets/commands.rb +373 -0
- data/lib/openc3/packets/json_packet.rb +134 -0
- data/lib/openc3/packets/limits.rb +271 -0
- data/lib/openc3/packets/limits_response.rb +53 -0
- data/lib/openc3/packets/packet.rb +1168 -0
- data/lib/openc3/packets/packet_config.rb +625 -0
- data/lib/openc3/packets/packet_item.rb +586 -0
- data/lib/openc3/packets/packet_item_limits.rb +162 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
- data/lib/openc3/packets/parsers/state_parser.rb +127 -0
- data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
- data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
- data/lib/openc3/packets/structure.rb +553 -0
- data/lib/openc3/packets/structure_item.rb +365 -0
- data/lib/openc3/packets/telemetry.rb +487 -0
- data/lib/openc3/processors/processor.rb +86 -0
- data/lib/openc3/processors/statistics_processor.rb +82 -0
- data/lib/openc3/processors/watermark_processor.rb +58 -0
- data/lib/openc3/processors.rb +24 -0
- data/lib/openc3/script/api_shared.rb +828 -0
- data/lib/openc3/script/calendar.rb +89 -0
- data/lib/openc3/script/commands.rb +227 -0
- data/lib/openc3/script/exceptions.rb +29 -0
- data/lib/openc3/script/extract.rb +161 -0
- data/lib/openc3/script/limits.rb +60 -0
- data/lib/openc3/script/script.rb +299 -0
- data/lib/openc3/script/script_runner.rb +238 -0
- data/lib/openc3/script/storage.rb +146 -0
- data/lib/openc3/script/suite.rb +542 -0
- data/lib/openc3/script/suite_results.rb +196 -0
- data/lib/openc3/script/suite_runner.rb +217 -0
- data/lib/openc3/script.rb +21 -0
- data/lib/openc3/streams/serial_stream.rb +167 -0
- data/lib/openc3/streams/stream.rb +63 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
- data/lib/openc3/system/system.rb +127 -0
- data/lib/openc3/system/system_config.rb +411 -0
- data/lib/openc3/system/target.rb +269 -0
- data/lib/openc3/system.rb +24 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
- data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
- data/lib/openc3/tools/table_manager/table.rb +77 -0
- data/lib/openc3/tools/table_manager/table_config.rb +273 -0
- data/lib/openc3/tools/table_manager/table_item.rb +90 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
- data/lib/openc3/tools/test_runner/test.rb +67 -0
- data/lib/openc3/top_level.rb +595 -0
- data/lib/openc3/topics/autonomic_topic.rb +52 -0
- data/lib/openc3/topics/calendar_topic.rb +44 -0
- data/lib/openc3/topics/command_decom_topic.rb +76 -0
- data/lib/openc3/topics/command_topic.rb +83 -0
- data/lib/openc3/topics/config_topic.rb +68 -0
- data/lib/openc3/topics/interface_topic.rb +73 -0
- data/lib/openc3/topics/limits_event_topic.rb +109 -0
- data/lib/openc3/topics/notifications_topic.rb +28 -0
- data/lib/openc3/topics/router_topic.rb +85 -0
- data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
- data/lib/openc3/topics/telemetry_topic.rb +36 -0
- data/lib/openc3/topics/timeline_topic.rb +45 -0
- data/lib/openc3/topics/topic.rb +53 -0
- data/lib/openc3/utilities/authentication.rb +141 -0
- data/lib/openc3/utilities/authorization.rb +51 -0
- data/lib/openc3/utilities/crc.rb +278 -0
- data/lib/openc3/utilities/csv.rb +153 -0
- data/lib/openc3/utilities/logger.rb +187 -0
- data/lib/openc3/utilities/message_log.rb +91 -0
- data/lib/openc3/utilities/metric.rb +141 -0
- data/lib/openc3/utilities/process_manager.rb +139 -0
- data/lib/openc3/utilities/quaternion.rb +257 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
- data/lib/openc3/utilities/s3.rb +202 -0
- data/lib/openc3/utilities/s3_autoload.rb +9 -0
- data/lib/openc3/utilities/s3_file_cache.rb +274 -0
- data/lib/openc3/utilities/simulated_target.rb +117 -0
- data/lib/openc3/utilities/sleeper.rb +51 -0
- data/lib/openc3/utilities/store.rb +23 -0
- data/lib/openc3/utilities/store_autoload.rb +237 -0
- data/lib/openc3/utilities/zip.rb +21 -0
- data/lib/openc3/utilities.rb +35 -0
- data/lib/openc3/version.rb +14 -0
- data/lib/openc3/win32/excel.rb +132 -0
- data/lib/openc3/win32/win32.rb +402 -0
- data/lib/openc3/win32/win32_main.rb +333 -0
- data/lib/openc3.rb +49 -0
- data/tasks/gemfile_stats.rake +113 -0
- data/tasks/spec.rake +30 -0
- data/templates/plugin-template/README.md +15 -0
- data/templates/plugin-template/Rakefile +12 -0
- data/templates/plugin-template/plugin.gemspec +23 -0
- data/templates/plugin-template/plugin.txt +9 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
- data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
- data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
- data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
- data/templates/plugin-template/targets/TARGET/target.txt +5 -0
- metadata +849 -0
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
|
7
|
+
# under the terms of the GNU Affero General Public License
|
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# Modified by OpenC3, Inc.
|
|
17
|
+
# All changes Copyright 2022, OpenC3, Inc.
|
|
18
|
+
# All Rights Reserved
|
|
19
|
+
|
|
20
|
+
require 'openc3/packets/binary_accessor'
|
|
21
|
+
require 'openc3/packets/structure_item'
|
|
22
|
+
require 'openc3/ext/packet' if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
|
|
23
|
+
|
|
24
|
+
module OpenC3
|
|
25
|
+
# Maintains knowledge of a raw binary structure. Uses structure_item to
|
|
26
|
+
# create individual structure items which are read and written by
|
|
27
|
+
# binary_accessor.
|
|
28
|
+
class Structure
|
|
29
|
+
# @return [Symbol] Default endianness for items in the structure. One of
|
|
30
|
+
# {BinaryAccessor::ENDIANNESS}
|
|
31
|
+
attr_reader :default_endianness
|
|
32
|
+
|
|
33
|
+
# @return [Hash] Items that make up the structure.
|
|
34
|
+
# Hash key is the item's name in uppercase
|
|
35
|
+
attr_reader :items
|
|
36
|
+
|
|
37
|
+
# @return [Array] Items sorted by bit_offset.
|
|
38
|
+
attr_reader :sorted_items
|
|
39
|
+
|
|
40
|
+
# @return [Integer] Defined length in bytes (not bits) of the structure
|
|
41
|
+
attr_reader :defined_length
|
|
42
|
+
|
|
43
|
+
# @return [Integer] Defined length in bits of the structure
|
|
44
|
+
attr_reader :defined_length_bits
|
|
45
|
+
|
|
46
|
+
# @return [Boolean] Flag indicating if the structure contains any variably
|
|
47
|
+
# sized items or not.
|
|
48
|
+
attr_reader :fixed_size
|
|
49
|
+
|
|
50
|
+
# @return [Boolean] Flag indicating if giving a buffer with less than
|
|
51
|
+
# required data size is allowed.
|
|
52
|
+
attr_accessor :short_buffer_allowed
|
|
53
|
+
|
|
54
|
+
if RUBY_ENGINE != 'ruby' or ENV['OPENC3_NO_EXT']
|
|
55
|
+
# Used to force encoding
|
|
56
|
+
ASCII_8BIT_STRING = "ASCII-8BIT".freeze
|
|
57
|
+
|
|
58
|
+
# String providing a single 0 byte
|
|
59
|
+
ZERO_STRING = "\000".freeze
|
|
60
|
+
|
|
61
|
+
# Structure constructor
|
|
62
|
+
#
|
|
63
|
+
# @param default_endianness [Symbol] Must be one of
|
|
64
|
+
# {BinaryAccessor::ENDIANNESS}. By default it uses
|
|
65
|
+
# BinaryAccessor::HOST_ENDIANNESS to determine the endianness of the host platform.
|
|
66
|
+
# @param buffer [String] Buffer used to store the structure
|
|
67
|
+
# @param item_class [Class] Class used to instantiate new structure items.
|
|
68
|
+
# Must be StructureItem or one of its subclasses.
|
|
69
|
+
def initialize(default_endianness = BinaryAccessor::HOST_ENDIANNESS, buffer = nil, item_class = StructureItem)
|
|
70
|
+
if (default_endianness == :BIG_ENDIAN) || (default_endianness == :LITTLE_ENDIAN)
|
|
71
|
+
@default_endianness = default_endianness
|
|
72
|
+
if buffer
|
|
73
|
+
raise TypeError, "wrong argument type #{buffer.class} (expected String)" unless String === buffer
|
|
74
|
+
|
|
75
|
+
@buffer = buffer.force_encoding(ASCII_8BIT_STRING)
|
|
76
|
+
else
|
|
77
|
+
@buffer = nil
|
|
78
|
+
end
|
|
79
|
+
@item_class = item_class
|
|
80
|
+
@items = {}
|
|
81
|
+
@sorted_items = []
|
|
82
|
+
@defined_length = 0
|
|
83
|
+
@defined_length_bits = 0
|
|
84
|
+
@pos_bit_size = 0
|
|
85
|
+
@neg_bit_size = 0
|
|
86
|
+
@fixed_size = true
|
|
87
|
+
@short_buffer_allowed = false
|
|
88
|
+
@mutex = nil
|
|
89
|
+
else
|
|
90
|
+
raise(ArgumentError, "Unknown endianness '#{default_endianness}', must be :BIG_ENDIAN or :LITTLE_ENDIAN")
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Read an item in the structure
|
|
95
|
+
#
|
|
96
|
+
# @param item [StructureItem] Instance of StructureItem or one of its subclasses
|
|
97
|
+
# @param value_type [Symbol] Not used. Subclasses should overload this
|
|
98
|
+
# parameter to check whether to perform conversions on the item.
|
|
99
|
+
# @param buffer [String] The binary buffer to read the item from
|
|
100
|
+
# @return Value based on the item definition. This could be a string, integer,
|
|
101
|
+
# float, or array of values.
|
|
102
|
+
def read_item(item, value_type = :RAW, buffer = @buffer)
|
|
103
|
+
return nil if item.data_type == :DERIVED
|
|
104
|
+
|
|
105
|
+
buffer = allocate_buffer_if_needed() unless buffer
|
|
106
|
+
if item.array_size
|
|
107
|
+
return BinaryAccessor.read_array(item.bit_offset, item.bit_size, item.data_type, item.array_size, buffer, item.endianness)
|
|
108
|
+
else
|
|
109
|
+
return BinaryAccessor.read(item.bit_offset, item.bit_size, item.data_type, buffer, item.endianness)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Get the length of the buffer used by the structure
|
|
114
|
+
#
|
|
115
|
+
# @return [Integer] Size of the buffer in bytes
|
|
116
|
+
def length
|
|
117
|
+
allocate_buffer_if_needed()
|
|
118
|
+
return @buffer.length
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Resize the buffer at least the defined length of the structure
|
|
122
|
+
def resize_buffer
|
|
123
|
+
if @buffer
|
|
124
|
+
# Extend data size
|
|
125
|
+
if @buffer.length < @defined_length
|
|
126
|
+
@buffer << (ZERO_STRING * (@defined_length - @buffer.length))
|
|
127
|
+
end
|
|
128
|
+
else
|
|
129
|
+
allocate_buffer_if_needed()
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
return self
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Allocate a buffer if not available
|
|
137
|
+
def allocate_buffer_if_needed
|
|
138
|
+
unless @buffer
|
|
139
|
+
@buffer = ZERO_STRING * @defined_length
|
|
140
|
+
@buffer.force_encoding(ASCII_8BIT_STRING)
|
|
141
|
+
end
|
|
142
|
+
return @buffer
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Indicates if any items have been defined for this structure
|
|
146
|
+
# @return [TrueClass or FalseClass]
|
|
147
|
+
def defined?
|
|
148
|
+
@sorted_items.length > 0
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Rename an existing item
|
|
152
|
+
#
|
|
153
|
+
# @param item_name [String] Name of the currently defined item
|
|
154
|
+
# @param new_item_name [String] New name for the item
|
|
155
|
+
def rename_item(item_name, new_item_name)
|
|
156
|
+
item = get_item(item_name)
|
|
157
|
+
item.name = new_item_name
|
|
158
|
+
@items.delete(item_name)
|
|
159
|
+
@items[new_item_name] = item
|
|
160
|
+
# Since @sorted_items contains the actual item reference it is
|
|
161
|
+
# updated when we set the item.name
|
|
162
|
+
item
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Define an item in the structure. This creates a new instance of the
|
|
166
|
+
# item_class as given in the constructor and adds it to the items hash. It
|
|
167
|
+
# also resizes the buffer to accomodate the new item.
|
|
168
|
+
#
|
|
169
|
+
# @param name [String] Name of the item. Used by the items hash to retrieve
|
|
170
|
+
# the item.
|
|
171
|
+
# @param bit_offset [Integer] Bit offset of the item in the raw buffer
|
|
172
|
+
# @param bit_size [Integer] Bit size of the item in the raw buffer
|
|
173
|
+
# @param data_type [Symbol] Type of data contained by the item. This is
|
|
174
|
+
# dependant on the item_class but by default see StructureItem.
|
|
175
|
+
# @param array_size [Integer] Set to a non nil value if the item is to
|
|
176
|
+
# represented as an array.
|
|
177
|
+
# @param endianness [Symbol] Endianness of this item. By default the
|
|
178
|
+
# endianness as set in the constructure is used.
|
|
179
|
+
# @param overflow [Symbol] How to handle value overflows. This is
|
|
180
|
+
# dependant on the item_class but by default see StructureItem.
|
|
181
|
+
# @return [StrutureItem] The struture item defined
|
|
182
|
+
def define_item(name, bit_offset, bit_size, data_type, array_size = nil, endianness = @default_endianness, overflow = :ERROR)
|
|
183
|
+
# Handle case-insensitive naming
|
|
184
|
+
name_upcase = name.upcase
|
|
185
|
+
|
|
186
|
+
# Create the item
|
|
187
|
+
item = @item_class.new(name_upcase, bit_offset, bit_size, data_type, endianness, array_size, overflow)
|
|
188
|
+
define(item)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Adds the given item to the items hash. It also resizes the buffer to
|
|
192
|
+
# accomodate the new item.
|
|
193
|
+
#
|
|
194
|
+
# @param item [StructureItem] The structure item to add
|
|
195
|
+
# @return [StrutureItem] The struture item defined
|
|
196
|
+
def define(item)
|
|
197
|
+
# Handle Overwriting Existing Item
|
|
198
|
+
if @items[item.name]
|
|
199
|
+
item_index = nil
|
|
200
|
+
@sorted_items.each_with_index do |sorted_item, index|
|
|
201
|
+
if sorted_item.name == item.name
|
|
202
|
+
item_index = index
|
|
203
|
+
break
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
@sorted_items.delete_at(item_index) if item_index < @sorted_items.length
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Add to Sorted Items
|
|
210
|
+
unless @sorted_items.empty?
|
|
211
|
+
last_item = @sorted_items[-1]
|
|
212
|
+
@sorted_items << item
|
|
213
|
+
# If the current item or last item have a negative offset then we have
|
|
214
|
+
# to re-sort. We also re-sort if the current item is less than the last
|
|
215
|
+
# item because we are inserting.
|
|
216
|
+
if last_item.bit_offset <= 0 or item.bit_offset <= 0 or item.bit_offset < last_item.bit_offset
|
|
217
|
+
@sorted_items = @sorted_items.sort
|
|
218
|
+
end
|
|
219
|
+
else
|
|
220
|
+
@sorted_items << item
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Add to the overall hash of defined items
|
|
224
|
+
@items[item.name] = item
|
|
225
|
+
# Update fixed size knowledge
|
|
226
|
+
@fixed_size = false if (item.data_type != :DERIVED and item.bit_size <= 0) or (item.array_size and item.array_size <= 0)
|
|
227
|
+
|
|
228
|
+
# Recalculate the overall defined length of the structure
|
|
229
|
+
update_needed = false
|
|
230
|
+
if item.bit_offset >= 0
|
|
231
|
+
if item.bit_size > 0
|
|
232
|
+
if item.array_size
|
|
233
|
+
if item.array_size >= 0
|
|
234
|
+
item_defined_length_bits = item.bit_offset + item.array_size
|
|
235
|
+
else
|
|
236
|
+
item_defined_length_bits = item.bit_offset
|
|
237
|
+
end
|
|
238
|
+
else
|
|
239
|
+
item_defined_length_bits = item.bit_offset + item.bit_size
|
|
240
|
+
end
|
|
241
|
+
if item_defined_length_bits > @pos_bit_size
|
|
242
|
+
@pos_bit_size = item_defined_length_bits
|
|
243
|
+
update_needed = true
|
|
244
|
+
end
|
|
245
|
+
else
|
|
246
|
+
if item.bit_offset > @pos_bit_size
|
|
247
|
+
@pos_bit_size = item.bit_offset
|
|
248
|
+
update_needed = true
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
else
|
|
252
|
+
if item.bit_offset.abs > @neg_bit_size
|
|
253
|
+
@neg_bit_size = item.bit_offset.abs
|
|
254
|
+
update_needed = true
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
if update_needed
|
|
258
|
+
@defined_length_bits = @pos_bit_size + @neg_bit_size
|
|
259
|
+
@defined_length = @defined_length_bits / 8
|
|
260
|
+
@defined_length += 1 if @defined_length_bits % 8 != 0
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# Resize the buffer if necessary
|
|
264
|
+
resize_buffer() if @buffer
|
|
265
|
+
|
|
266
|
+
return item
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Define an item at the end of the structure. This creates a new instance of the
|
|
270
|
+
# item_class as given in the constructor and adds it to the items hash. It
|
|
271
|
+
# also resizes the buffer to accomodate the new item.
|
|
272
|
+
#
|
|
273
|
+
# @param name (see #define_item)
|
|
274
|
+
# @param bit_size (see #define_item)
|
|
275
|
+
# @param data_type (see #define_item)
|
|
276
|
+
# @param array_size (see #define_item)
|
|
277
|
+
# @param endianness (see #define_item)
|
|
278
|
+
# @param overflow (see #define_item)
|
|
279
|
+
# @return (see #define_item)
|
|
280
|
+
def append_item(name, bit_size, data_type, array_size = nil, endianness = @default_endianness, overflow = :ERROR)
|
|
281
|
+
raise ArgumentError, "Can't append an item after a variably sized item" if !@fixed_size
|
|
282
|
+
if data_type == :DERIVED
|
|
283
|
+
return define_item(name, 0, bit_size, data_type, array_size, endianness, overflow)
|
|
284
|
+
else
|
|
285
|
+
return define_item(name, @defined_length_bits, bit_size, data_type, array_size, endianness, overflow)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Adds an item at the end of the structure. It adds the item to the items
|
|
290
|
+
# hash and resizes the buffer to accomodate the new item.
|
|
291
|
+
#
|
|
292
|
+
# @param item (see #define)
|
|
293
|
+
# @return (see #define)
|
|
294
|
+
def append(item)
|
|
295
|
+
raise ArgumentError, "Can't append an item after a variably sized item" if !@fixed_size
|
|
296
|
+
|
|
297
|
+
if item.data_type == :DERIVED
|
|
298
|
+
item.bit_offset = 0
|
|
299
|
+
else
|
|
300
|
+
item.bit_offset = @defined_length_bits
|
|
301
|
+
end
|
|
302
|
+
return define(item)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# @param name [String] Name of the item to look up in the items Hash
|
|
306
|
+
# @return [StructureItem] StructureItem or one of its subclasses
|
|
307
|
+
def get_item(name)
|
|
308
|
+
item = @items[name.upcase]
|
|
309
|
+
raise ArgumentError, "Unknown item: #{name}" unless item
|
|
310
|
+
|
|
311
|
+
return item
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# @param item [#name] Instance of StructureItem or one of its subclasses.
|
|
315
|
+
# The name method will be used to look up the item and set it to the new instance.
|
|
316
|
+
def set_item(item)
|
|
317
|
+
if @items[item.name]
|
|
318
|
+
@items[item.name] = item
|
|
319
|
+
else
|
|
320
|
+
raise ArgumentError, "Unknown item: #{item.name} - Ensure item name is uppercase"
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# @param name [String] Name of the item to delete in the items Hash
|
|
325
|
+
def delete_item(name)
|
|
326
|
+
item = @items[name.upcase]
|
|
327
|
+
raise ArgumentError, "Unknown item: #{name}" unless item
|
|
328
|
+
|
|
329
|
+
# Find the item to delete in the sorted_items array
|
|
330
|
+
item_index = nil
|
|
331
|
+
@sorted_items.each_with_index do |sorted_item, index|
|
|
332
|
+
if sorted_item.name == item.name
|
|
333
|
+
item_index = index
|
|
334
|
+
break
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
@sorted_items.delete_at(item_index)
|
|
338
|
+
@items.delete(name.upcase)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Write a value to the buffer based on the item definition
|
|
342
|
+
#
|
|
343
|
+
# @param item [StructureItem] Instance of StructureItem or one of its subclasses
|
|
344
|
+
# @param value [Object] Value based on the item definition. This could be
|
|
345
|
+
# a string, integer, float, or array of values.
|
|
346
|
+
# @param value_type [Symbol] Not used. Subclasses should overload this
|
|
347
|
+
# parameter to check whether to perform conversions on the item.
|
|
348
|
+
# @param buffer [String] The binary buffer to write the value to
|
|
349
|
+
def write_item(item, value, value_type = :RAW, buffer = @buffer)
|
|
350
|
+
buffer = allocate_buffer_if_needed() unless buffer
|
|
351
|
+
if item.array_size
|
|
352
|
+
BinaryAccessor.write_array(value, item.bit_offset, item.bit_size, item.data_type, item.array_size, buffer, item.endianness, item.overflow)
|
|
353
|
+
else
|
|
354
|
+
BinaryAccessor.write(value, item.bit_offset, item.bit_size, item.data_type, buffer, item.endianness, item.overflow)
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
# Read an item in the structure by name
|
|
359
|
+
#
|
|
360
|
+
# @param name [String] Name of an item to read
|
|
361
|
+
# @param value_type [Symbol] Not used. Subclasses should overload this
|
|
362
|
+
# parameter to check whether to perform conversions on the item.
|
|
363
|
+
# @param buffer [String] The binary buffer to read the item from
|
|
364
|
+
# @return Value based on the item definition. This could be an integer,
|
|
365
|
+
# float, or array of values.
|
|
366
|
+
def read(name, value_type = :RAW, buffer = @buffer)
|
|
367
|
+
return read_item(get_item(name), value_type, buffer)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# Write an item in the structure by name
|
|
371
|
+
#
|
|
372
|
+
# @param name [Object] Name of the item to write
|
|
373
|
+
# @param value [Object] Value based on the item definition. This could be
|
|
374
|
+
# a string, integer, float, or array of values.
|
|
375
|
+
# @param value_type [Symbol] Not used. Subclasses should overload this
|
|
376
|
+
# parameter to check whether to perform conversions on the item.
|
|
377
|
+
# @param buffer [String] The binary buffer to write the value to
|
|
378
|
+
def write(name, value, value_type = :RAW, buffer = @buffer)
|
|
379
|
+
write_item(get_item(name), value, value_type, buffer)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
# Read all items in the structure into an array of arrays
|
|
383
|
+
# [[item name, item value], ...]
|
|
384
|
+
#
|
|
385
|
+
# @param value_type [Symbol] Not used. Subclasses should overload this
|
|
386
|
+
# parameter to check whether to perform conversions on the item.
|
|
387
|
+
# @param buffer [String] The binary buffer to write the value to
|
|
388
|
+
# @param top [Boolean] Indicates if this is a top level call for the mutex
|
|
389
|
+
# @return [Array<Array>] Array of two element arrays containing the item
|
|
390
|
+
# name as element 0 and item value as element 1.
|
|
391
|
+
def read_all(value_type = :RAW, buffer = @buffer, top = true)
|
|
392
|
+
item_array = []
|
|
393
|
+
synchronize_allow_reads(top) do
|
|
394
|
+
@sorted_items.each { |item| item_array << [item.name, read_item(item, value_type, buffer)] }
|
|
395
|
+
end
|
|
396
|
+
return item_array
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# Create a string that shows the name and value of each item in the structure
|
|
400
|
+
#
|
|
401
|
+
# @param value_type [Symbol] Not used. Subclasses should overload this
|
|
402
|
+
# parameter to check whether to perform conversions on the item.
|
|
403
|
+
# @param indent [Integer] Amount to indent before printing the item name
|
|
404
|
+
# @param buffer [String] The binary buffer to write the value to
|
|
405
|
+
# @param ignored [Array<String>] List of items to ignore when building the string
|
|
406
|
+
# @return [String] String formatted with all the item names and values
|
|
407
|
+
def formatted(value_type = :RAW, indent = 0, buffer = @buffer, ignored = nil)
|
|
408
|
+
indent_string = ' ' * indent
|
|
409
|
+
string = ''
|
|
410
|
+
synchronize_allow_reads(true) do
|
|
411
|
+
@sorted_items.each do |item|
|
|
412
|
+
next if ignored && ignored.include?(item.name)
|
|
413
|
+
|
|
414
|
+
if (item.data_type != :BLOCK) ||
|
|
415
|
+
(item.data_type == :BLOCK and value_type != :RAW and
|
|
416
|
+
item.respond_to? :read_conversion and item.read_conversion)
|
|
417
|
+
string << "#{indent_string}#{item.name}: #{read_item(item, value_type, buffer)}\n"
|
|
418
|
+
else
|
|
419
|
+
value = read_item(item, value_type, buffer)
|
|
420
|
+
if String === value
|
|
421
|
+
string << "#{indent_string}#{item.name}:\n"
|
|
422
|
+
string << value.formatted(1, 16, ' ', indent + 2)
|
|
423
|
+
else
|
|
424
|
+
string << "#{indent_string}#{item.name}: #{value}\n"
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
return string
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
# Get the buffer used by the structure. The current buffer is copied and
|
|
433
|
+
# thus modifications to the returned buffer will have no effect on the
|
|
434
|
+
# structure items.
|
|
435
|
+
#
|
|
436
|
+
# @param copy [TrueClass/FalseClass] Whether to copy the buffer
|
|
437
|
+
# @return [String] Data buffer backing the structure
|
|
438
|
+
def buffer(copy = true)
|
|
439
|
+
local_buffer = allocate_buffer_if_needed()
|
|
440
|
+
if copy
|
|
441
|
+
return local_buffer.dup
|
|
442
|
+
else
|
|
443
|
+
return local_buffer
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# Set the buffer to be used by the structure. The buffer is copied and thus
|
|
448
|
+
# further modifications to the buffer have no effect on the structure
|
|
449
|
+
# items.
|
|
450
|
+
#
|
|
451
|
+
# @param buffer [String] Buffer of data to back the stucture items
|
|
452
|
+
def buffer=(buffer)
|
|
453
|
+
synchronize() do
|
|
454
|
+
internal_buffer_equals(buffer)
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
# Make a light weight clone of this structure. This only creates a new buffer
|
|
459
|
+
# of data. The defined structure items are the same.
|
|
460
|
+
#
|
|
461
|
+
# @return [Structure] A copy of the current structure with a new underlying
|
|
462
|
+
# buffer of data
|
|
463
|
+
def clone
|
|
464
|
+
structure = super()
|
|
465
|
+
# Use instance_variable_set since we have overriden buffer= to do
|
|
466
|
+
# additional work that isn't neccessary here
|
|
467
|
+
structure.instance_variable_set("@buffer".freeze, @buffer.clone) if @buffer
|
|
468
|
+
return structure
|
|
469
|
+
end
|
|
470
|
+
alias dup clone
|
|
471
|
+
|
|
472
|
+
# Enable the ability to read and write item values as if they were methods
|
|
473
|
+
# to the class
|
|
474
|
+
def enable_method_missing
|
|
475
|
+
extend(MethodMissing)
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
protected
|
|
479
|
+
|
|
480
|
+
MUTEX = Mutex.new
|
|
481
|
+
|
|
482
|
+
def setup_mutex
|
|
483
|
+
return if @mutex
|
|
484
|
+
|
|
485
|
+
MUTEX.synchronize do
|
|
486
|
+
@mutex ||= Mutex.new
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
# Take the structure mutex to ensure the buffer does not change while you perform activities
|
|
491
|
+
def synchronize
|
|
492
|
+
setup_mutex()
|
|
493
|
+
@mutex.synchronize { || yield }
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
# Take the structure mutex to ensure the buffer does not change while you perform activities
|
|
497
|
+
# This versions allows reads to happen if a top level function has already taken the mutex
|
|
498
|
+
# @param top [Boolean] If true this will take the mutex and set an allow reads flag to allow
|
|
499
|
+
# lower level calls to go forward without getting the mutex
|
|
500
|
+
def synchronize_allow_reads(top = false)
|
|
501
|
+
@mutex_allow_reads ||= false
|
|
502
|
+
setup_mutex()
|
|
503
|
+
if top
|
|
504
|
+
@mutex.synchronize do
|
|
505
|
+
@mutex_allow_reads = Thread.current
|
|
506
|
+
begin
|
|
507
|
+
yield
|
|
508
|
+
ensure
|
|
509
|
+
@mutex_allow_reads = false
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
else
|
|
513
|
+
got_mutex = @mutex.try_lock
|
|
514
|
+
if got_mutex
|
|
515
|
+
begin
|
|
516
|
+
yield
|
|
517
|
+
ensure
|
|
518
|
+
@mutex.unlock
|
|
519
|
+
end
|
|
520
|
+
elsif @mutex_allow_reads == Thread.current
|
|
521
|
+
yield
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
module MethodMissing
|
|
527
|
+
# Method missing provides reading/writing item values as if they were methods to the class
|
|
528
|
+
def method_missing(name, value = nil)
|
|
529
|
+
if value
|
|
530
|
+
# Strip off the equals sign before looking up the item
|
|
531
|
+
return write(name.to_s[0..-2], value)
|
|
532
|
+
else
|
|
533
|
+
return read(name.to_s)
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
def internal_buffer_equals(buffer)
|
|
539
|
+
raise ArgumentError, "Buffer class is #{buffer.class} but must be String" unless String === buffer
|
|
540
|
+
|
|
541
|
+
@buffer = buffer.dup
|
|
542
|
+
@buffer.force_encoding('ASCII-8BIT'.freeze)
|
|
543
|
+
if @buffer.length != @defined_length
|
|
544
|
+
if @buffer.length < @defined_length
|
|
545
|
+
resize_buffer()
|
|
546
|
+
raise "Buffer length less than defined length" unless @short_buffer_allowed
|
|
547
|
+
elsif @fixed_size and @defined_length != 0
|
|
548
|
+
raise "Buffer length greater than defined length"
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
end # class Structure
|
|
553
|
+
end
|