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.
Files changed (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. metadata +849 -0
@@ -0,0 +1,53 @@
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/utilities/store'
21
+
22
+ module OpenC3
23
+ class Topic
24
+ if RUBY_VERSION < "3"
25
+ # Delegate all unknown class methods to delegate to the EphemeralStore
26
+ def self.method_missing(message, *args, &block)
27
+ EphemeralStore.public_send(message, *args, &block)
28
+ end
29
+ else
30
+ # Delegate all unknown class methods to delegate to the EphemeralStore
31
+ def self.method_missing(message, *args, **kwargs, &block)
32
+ EphemeralStore.public_send(message, *args, **kwargs, &block)
33
+ end
34
+ end
35
+
36
+ def self.clear_topics(topics, maxlen = 0)
37
+ topics.each { |topic| EphemeralStore.xtrim(topic, maxlen) }
38
+ end
39
+
40
+ def self.topics(scope, key)
41
+ EphemeralStore
42
+ .scan_each(match: "#{scope}__#{key}__*", type: 'stream', count: 100)
43
+ .to_a # Change the enumerator into an array
44
+ .uniq # Scan can return duplicates so ensure unique
45
+ .sort # Sort not entirely necessary but nice
46
+ end
47
+
48
+ def self.get_cnt(topic)
49
+ _, packet = EphemeralStore.get_newest_message(topic)
50
+ packet ? packet["received_count"].to_i : 0
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,141 @@
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/version'
21
+
22
+ module OpenC3
23
+
24
+ # Basic exception for known errors
25
+ class OpenC3AuthenticationError < StandardError; end
26
+
27
+ class OpenC3AuthenticationRetryableError < OpenC3AuthenticationError; end
28
+
29
+ # OpenC3 base / open source authentication code
30
+ class OpenC3Authentication
31
+ def initialize()
32
+ @token = ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
33
+ if @token.nil?
34
+ raise OpenC3AuthenticationError, "Authentication requires environment variables OPENC3_API_PASSWORD or OPENC3_SERVICE_PASSWORD"
35
+ end
36
+ end
37
+
38
+ # Load the token from the environment
39
+ def token()
40
+ @token
41
+ end
42
+ end
43
+
44
+ # OpenC3 enterprise Keycloak authentication code
45
+ class OpenC3KeycloakAuthentication < OpenC3Authentication
46
+ # {
47
+ # "access_token": "",
48
+ # "expires_in": 600,
49
+ # "refresh_expires_in": 1800,
50
+ # "refresh_token": "",
51
+ # "token_type": "bearer",
52
+ # "id_token": "",
53
+ # "not-before-policy": 0,
54
+ # "session_state": "",
55
+ # "scope": "openid email profile"
56
+ # }
57
+
58
+ # @param url [String] The url of the openc3 or keycloak in the cluster
59
+ def initialize(url)
60
+ @url = url
61
+ @auth_mutex = Mutex.new
62
+ @refresh_token = nil
63
+ @expires_at = nil
64
+ @refresh_expires_at = nil
65
+ @token = nil
66
+ @log = [nil, nil]
67
+ end
68
+
69
+ # Load the token from the environment
70
+ def token()
71
+ @auth_mutex.synchronize do
72
+ @log = [nil, nil]
73
+ current_time = Time.now.to_i
74
+ if @token.nil?
75
+ _make_token(current_time)
76
+ elsif @refresh_expires_at < current_time
77
+ _make_token(current_time)
78
+ elsif @expires_at < current_time
79
+ _refresh_token(current_time)
80
+ end
81
+ end
82
+ "Bearer #{@token}"
83
+ end
84
+
85
+ private
86
+
87
+ # Make the token and save token to instance
88
+ def _make_token(current_time)
89
+ client_id = ENV['OPENC3_API_CLIENT'] || 'api'
90
+ data = "username=#{ENV['OPENC3_API_USER']}&password=#{ENV['OPENC3_API_PASSWORD']}"
91
+ data << "&client_id=#{client_id}"
92
+ data << '&grant_type=password&scope=openid'
93
+ headers = {
94
+ 'Content-Type' => 'application/x-www-form-urlencoded',
95
+ 'User-Agent' => "OpenC3KeycloakAuthorization / #{OPENC3_VERSION} (ruby/openc3/lib/utilities/authentication)",
96
+ }
97
+ oath = _make_request(headers, data)
98
+ @token = oath['access_token']
99
+ @refresh_token = oath['refresh_token']
100
+ @expires_at = current_time + oath['expires_in']
101
+ @refresh_expires_at = current_time + oath['refresh_expires_in']
102
+ end
103
+
104
+ # Refresh the token and save token to instance
105
+ def _refresh_token(current_time)
106
+ client_id = ENV['OPENC3_API_CLIENT'] || 'api'
107
+ data = "client_id=#{client_id}&refresh_token=#{@refresh_token}&grant_type=refresh_token"
108
+ headers = {
109
+ 'Content-Type' => 'application/x-www-form-urlencoded',
110
+ 'User-Agent' => "OpenC3KeycloakAuthorization / #{OPENC3_VERSION} (ruby/openc3/lib/utilities/authentication)",
111
+ }
112
+ oath = _make_request(headers, data)
113
+ @token = oath["access_token"]
114
+ @refresh_token = oath["refresh_token"]
115
+ @expires_at = current_time + oath["expires_in"]
116
+ @refresh_expires_at = current_time + oath["refresh_expires_in"]
117
+ end
118
+
119
+ # Make the post request to keycloak
120
+ def _make_request(headers, data)
121
+ uri = URI("#{@url}/auth/realms/openc3/protocol/openid-connect/token")
122
+ @log[0] = "request uri: #{uri.to_s} header: #{headers.to_s} body: #{data.to_s}"
123
+ STDOUT.puts @log[0] if JsonDRb.debug?
124
+ saved_verbose = $VERBOSE; $VERBOSE = nil
125
+ begin
126
+ resp = HTTPClient.new().post(uri, :body => data, :header => headers)
127
+ ensure
128
+ $VERBOSE = saved_verbose
129
+ end
130
+ @log[1] = "response status: #{resp.status} header: #{resp.headers} body: #{resp.body}"
131
+ STDOUT.puts @log[1] if JsonDRb.debug?
132
+ if resp.status >= 200 && resp.status <= 299
133
+ return JSON.parse(resp.body, :allow_nan => true, :create_additions => true)
134
+ elsif resp.status >= 500 && resp.status <= 599
135
+ raise OpenC3AuthenticationRetryableError, "authentication request retryable #{@log[0]} ::: #{@log[1]}"
136
+ else
137
+ raise OpenC3AuthenticationError, "authentication request failed #{@log[0]} ::: #{@log[1]}"
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,51 @@
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/models/auth_model'
21
+
22
+ begin
23
+ require 'openc3-enterprise/utilities/authorization'
24
+ rescue LoadError
25
+ # If we're not in openc3-enterprise we define our own
26
+ module OpenC3
27
+ class AuthError < StandardError
28
+ end
29
+
30
+ class ForbiddenError < StandardError
31
+ end
32
+
33
+ module Authorization
34
+ private
35
+
36
+ # Raises an exception if unauthorized, otherwise does nothing
37
+ def authorize(permission: nil, target_name: nil, packet_name: nil, interface_name: nil, router_name: nil, scope: nil, token: nil)
38
+ raise AuthError.new("Scope is required") unless scope
39
+
40
+ if $openc3_authorize
41
+ raise AuthError.new("Token is required") unless token
42
+ raise AuthError.new("Token is invalid for '#{permission}' permission") unless OpenC3::AuthModel.verify(token, permission: permission)
43
+ end
44
+ end
45
+
46
+ def user_info(_token)
47
+ {} # EE does stuff here
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,278 @@
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/ext/crc' if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
21
+
22
+ module OpenC3
23
+ # Abstract base class which {Crc16}, {Crc32} and {Crc64} use. Do NOT use this
24
+ # class directly but instead use one of the subclasses.
25
+ class Crc
26
+ BIT_REVERSE_TABLE = [
27
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
28
+ 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
29
+ 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
30
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
31
+ 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
32
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
33
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
34
+ 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
35
+ 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
36
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
37
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
38
+ 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
39
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
40
+ 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
41
+ 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
42
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
43
+ ]
44
+
45
+ # @return [Integer] The polynomial used when calcuating the CRC
46
+ attr_reader :poly
47
+ # @return [Integer] Seed value used to start the calulation
48
+ attr_reader :seed
49
+ # @return [Boolean] Whether the result is XORed with 0xFFFF
50
+ attr_reader :xor
51
+ # @return [Boolean] Whether to bit reverse each byte
52
+ attr_reader :reflect
53
+ # @return [String] Binary lookup table used to perform the calculation
54
+ attr_reader :table
55
+
56
+ # Creates a CRC algorithm instance.
57
+ #
58
+ # @param poly [Integer] Polynomial to use when calculating the CRC
59
+ # @param seed [Integer] Seed value to start the calculation
60
+ # @param xor [Boolean] Whether to XOR the CRC result with 0xFFFF
61
+ # @param reflect [Boolean] Whether to bit reverse each byte of data before
62
+ # calculating the CRC
63
+ def initialize(poly, seed, xor, reflect)
64
+ @poly = poly
65
+ @seed = seed
66
+ @xor = xor
67
+ @reflect = reflect
68
+ if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
69
+ @table = ''
70
+ else
71
+ @table = []
72
+ end
73
+
74
+ # Determine which class we're using: Crc16, Crc32, Crc64
75
+ @bit_size = self.class.name[-2..-1].to_i
76
+ case @bit_size
77
+ when 16
78
+ pack = 'S'
79
+ filter_mask = 0xFFFF
80
+ when 32
81
+ pack = 'I'
82
+ filter_mask = 0xFFFFFFFF
83
+ when 64
84
+ pack = 'Q'
85
+ filter_mask = 0xFFFFFFFFFFFFFFFF
86
+ end
87
+ if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
88
+ (0..255).each do |index|
89
+ @table << [compute_table_entry(index, @bit_size)].pack(pack)
90
+ end
91
+ else
92
+ (0..255).each do |index|
93
+ @table << (compute_table_entry(index, @bit_size) & filter_mask)
94
+ end
95
+ end
96
+ end
97
+
98
+ # @!method calc(data, seed = nil)
99
+ # Calculates the CRC across the data buffer using the optional seed.
100
+ # Implemented in C for speed.
101
+ #
102
+ # @param data [String] String buffer of binary data to calculate a CRC on
103
+ # @param seed [Integer|nil] Seed value to start the calculation. Pass nil
104
+ # to use the default seed set in the constructor.
105
+ # @return [Integer] The CRC value
106
+
107
+ # Bit reverse the 8 bit value
108
+ # @param value [Integer]
109
+ # @return [Integer] Bit reversed value
110
+ def bit_reverse_8(value)
111
+ BIT_REVERSE_TABLE[value & 0xFF]
112
+ end
113
+
114
+ def bit_reverse_16(value)
115
+ (BIT_REVERSE_TABLE[value & 0xFF] << 8) |
116
+ (BIT_REVERSE_TABLE[(value >> 8) & 0xFF])
117
+ end
118
+
119
+ def bit_reverse_32(value)
120
+ (BIT_REVERSE_TABLE[value & 0xFF] << 24) |
121
+ (BIT_REVERSE_TABLE[(value >> 8) & 0xFF] << 16) |
122
+ (BIT_REVERSE_TABLE[(value >> 16) & 0xFF] << 8) |
123
+ (BIT_REVERSE_TABLE[(value >> 24) & 0xFF])
124
+ end
125
+
126
+ def bit_reverse_64(value)
127
+ (BIT_REVERSE_TABLE[value & 0x00000000000000FF] << 56) |
128
+ (BIT_REVERSE_TABLE[(value >> 8) & 0x00000000000000FF] << 48) |
129
+ (BIT_REVERSE_TABLE[(value >> 16) & 0x00000000000000FF] << 40) |
130
+ (BIT_REVERSE_TABLE[(value >> 24) & 0x00000000000000FF] << 32) |
131
+ (BIT_REVERSE_TABLE[(value >> 32) & 0x00000000000000FF] << 24) |
132
+ (BIT_REVERSE_TABLE[(value >> 40) & 0x00000000000000FF] << 16) |
133
+ (BIT_REVERSE_TABLE[(value >> 48) & 0x00000000000000FF] << 8) |
134
+ (BIT_REVERSE_TABLE[(value >> 56) & 0x00000000000000FF])
135
+ end
136
+
137
+ if RUBY_ENGINE != 'ruby' or ENV['OPENC3_NO_EXT']
138
+ def calc(data, seed = @seed)
139
+ crc = seed
140
+
141
+ case @bit_size
142
+ when 16
143
+ right_shift = 8
144
+ filter_mask = 0xFFFF
145
+ final_bit_reverse = method(:bit_reverse_16)
146
+ when 32
147
+ right_shift = 24
148
+ filter_mask = 0xFFFFFFFF
149
+ final_bit_reverse = method(:bit_reverse_32)
150
+ when 64
151
+ right_shift = 56
152
+ filter_mask = 0xFFFFFFFFFFFFFFFF
153
+ final_bit_reverse = method(:bit_reverse_64)
154
+ end
155
+
156
+ if @reflect
157
+ data.each_byte do |byte|
158
+ crc = ((crc << 8) & filter_mask) ^ @table[(crc >> right_shift) ^ bit_reverse_8(byte)]
159
+ end
160
+
161
+ if @xor
162
+ return final_bit_reverse.call(crc ^ filter_mask)
163
+ else
164
+ return final_bit_reverse.call(crc)
165
+ end
166
+ else
167
+ data.each_byte do |byte|
168
+ crc = ((crc << 8) & filter_mask) ^ @table[(crc >> right_shift) ^ byte]
169
+ end
170
+
171
+ if @xor
172
+ return crc ^ filter_mask
173
+ else
174
+ return crc
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ protected
181
+
182
+ # Compute a single entry in the crc lookup table
183
+ def compute_table_entry(index, digits)
184
+ # Start by shifting the index
185
+ crc = index << (digits - 8)
186
+
187
+ # The mask is 0x8000 for Crc16, 0x80000000 for Crc32, etc
188
+ mask = (1 << (digits - 1))
189
+
190
+ 8.times do
191
+ if (crc & mask) != 0
192
+ crc = (crc << 1) ^ @poly
193
+ else
194
+ crc = crc << 1
195
+ end
196
+ end
197
+
198
+ # XOR the mask and or back in the top bit to get all ones
199
+ mask = ~mask | mask
200
+ return (crc & mask)
201
+ end
202
+ end
203
+
204
+ # Calculates 16-bit CRCs over a buffer of data.
205
+ class Crc16 < Crc
206
+ # CRC-16-CCITT default polynomial
207
+ DEFAULT_POLY = 0x1021
208
+ # Seed for 16-bit CRC
209
+ DEFAULT_SEED = 0xFFFF
210
+
211
+ # Creates a 16 bit CRC algorithm instance. By default it is initialzed to
212
+ # use the CRC-16-CCITT algorithm.
213
+ #
214
+ # @param poly [Integer] Polynomial to use when calculating the CRC
215
+ # @param seed [Integer] Seed value to start the calculation
216
+ # @param xor [Boolean] Whether to XOR the CRC result with 0xFFFF
217
+ # @param reflect [Boolean] Whether to bit reverse each byte of data before
218
+ # calculating the CRC
219
+ def initialize(poly = DEFAULT_POLY,
220
+ seed = DEFAULT_SEED,
221
+ xor = false,
222
+ reflect = false)
223
+ super(poly, seed, xor, reflect)
224
+ end
225
+
226
+ alias calculate_crc16 calc
227
+ end # class Crc16
228
+
229
+ # Calculates 32-bit CRCs over a buffer of data.
230
+ class Crc32 < Crc
231
+ # CRC-32 default polynomial
232
+ DEFAULT_POLY = 0x04C11DB7
233
+ # Default Seed for 32-bit CRC
234
+ DEFAULT_SEED = 0xFFFFFFFF
235
+
236
+ # Creates a 32 bit CRC algorithm instance. By default it is initialzed to
237
+ # use the CRC-32 algorithm.
238
+ #
239
+ # @param poly [Integer] Polynomial to use when calculating the CRC
240
+ # @param seed [Integer] Seed value to start the calculation
241
+ # @param xor [Boolean] Whether to XOR the CRC result with 0xFFFF
242
+ # @param reflect [Boolean] Whether to bit reverse each byte of data before
243
+ # calculating the CRC
244
+ def initialize(poly = DEFAULT_POLY,
245
+ seed = DEFAULT_SEED,
246
+ xor = true,
247
+ reflect = true)
248
+ super(poly, seed, xor, reflect)
249
+ end
250
+
251
+ alias calculate_crc32 calc
252
+ end
253
+
254
+ # Calculates 64-bit CRCs over a buffer of data.
255
+ class Crc64 < Crc
256
+ # CRC-64-ECMA default polynomial
257
+ DEFAULT_POLY = 0x42F0E1EBA9EA3693
258
+ # Default Seed for 64-bit CRC
259
+ DEFAULT_SEED = 0xFFFFFFFFFFFFFFFF
260
+
261
+ # Creates a 64 bit CRC algorithm instance. By default it is initialzed to
262
+ # use the algorithm.
263
+ #
264
+ # @param poly [Integer] Polynomial to use when calculating the CRC
265
+ # @param seed [Integer] Seed value to start the calculation
266
+ # @param xor [Boolean] Whether to XOR the CRC result with 0xFFFF
267
+ # @param reflect [Boolean] Whether to bit reverse each byte of data before
268
+ # calculating the CRC
269
+ def initialize(poly = DEFAULT_POLY,
270
+ seed = DEFAULT_SEED,
271
+ xor = true,
272
+ reflect = true)
273
+ super(poly, seed, xor, reflect)
274
+ end
275
+
276
+ alias calculate_crc64 calc
277
+ end
278
+ end
@@ -0,0 +1,153 @@
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 'csv'
21
+
22
+ module OpenC3
23
+ # Reads in a comma separated values (CSV) configuration file and
24
+ # allows access via the Hash bracket syntax. It allows the user to write
25
+ # back data to the configuration file to store state.
26
+ class CSV
27
+ # @return [String] The name of the archive file
28
+ attr_reader :archive_file
29
+
30
+ # @param input_file [String] CSV filename to read
31
+ def initialize(input_file)
32
+ @filename = input_file
33
+ @hash = {}
34
+ @archive = nil
35
+ @archive_file = ""
36
+ Object::CSV.read(input_file).each do |line|
37
+ next if line[0].strip()[0] == '#' # Ignore Ruby comment lines
38
+
39
+ @hash[line[0]] = line[1..-1]
40
+ end
41
+ end
42
+
43
+ # @return [Array<String>] All the values in the first column of the CSV file.
44
+ # These values are used as keys to access the data in columns 2-n.
45
+ def keys
46
+ @hash.keys
47
+ end
48
+
49
+ # @return [Array<String>] The values in columns 2-n corresponding to the
50
+ # given key in column 1. The values are always returned as Strings so the
51
+ # user must convert if necessary.
52
+ def [](index)
53
+ @hash[index]
54
+ end
55
+
56
+ # Convenience method to access a value by key and convert it to a boolean.
57
+ # The csv value must be 'TRUE' or 'FALSE' (case doesn't matter)
58
+ # and will be converted to Ruby true or false values.
59
+ #
60
+ # @param item [String] Key to access the value
61
+ # @param index [Integer] Which value to return
62
+ # @return [Boolean] Single value converted to a boolean (true or false)
63
+ def bool(item, index = 0)
64
+ raise "#{item} not found" unless keys.include?(item)
65
+
66
+ if Range === index
67
+ @hash[item][index].map do |x|
68
+ case x.upcase
69
+ when 'TRUE'
70
+ true
71
+ when 'FALSE'
72
+ false
73
+ else
74
+ raise "#{item} value of #{x} not boolean. Must be 'TRUE' 'or 'FALSE'."
75
+ end
76
+ end
77
+ else
78
+ case @hash[item][index].upcase
79
+ when 'TRUE'
80
+ true
81
+ when 'FALSE'
82
+ false
83
+ else
84
+ raise "#{item} value of #{@hash[item][index]} not boolean. Must be 'TRUE' 'or 'FALSE'."
85
+ end
86
+ end
87
+ end
88
+ alias boolean bool
89
+
90
+ # Convenience method to access a value by key and convert it to an integer
91
+ #
92
+ # @param item [String] Key to access the value
93
+ # @param index [Integer] Which value to return
94
+ # @return [Integer] Single value converted to an integer
95
+ def int(item, index = 0)
96
+ raise "#{item} not found" unless keys.include?(item)
97
+
98
+ if Range === index
99
+ @hash[item][index].map { |x| x.to_i }
100
+ else
101
+ @hash[item][index].to_i
102
+ end
103
+ end
104
+ alias integer int
105
+
106
+ # Convenience method to access a value by key and convert it to a float
107
+ #
108
+ # @param item [String] Key to access the value
109
+ # @param index [Integer] Which value to return
110
+ # @return [Float] Single value converted to a float
111
+ def float(item, index = 0)
112
+ raise "#{item} not found" unless keys.include?(item)
113
+
114
+ if Range === index
115
+ @hash[item][index].map { |x| x.to_f }
116
+ else
117
+ @hash[item][index].to_f
118
+ end
119
+ end
120
+
121
+ # Convenience method to access a value by key and convert it to a string
122
+ #
123
+ # @param item [String] Key to access the value
124
+ # @param index [Integer] Which value to return
125
+ # @return [String] Single value converted to a string
126
+ def string(item, index = 0)
127
+ raise "#{item} not found" unless keys.include?(item)
128
+
129
+ if Range === index
130
+ @hash[item][index].map { |x| x.to_s }
131
+ else
132
+ @hash[item][index].to_s
133
+ end
134
+ end
135
+ alias str string
136
+
137
+ # Convenience method to access a value by key and convert it to a symbol
138
+ #
139
+ # @param item [String] Key to access the value
140
+ # @param index [Integer] Which value to return
141
+ # @return [Symbol] Single value converted to a symbol
142
+ def symbol(item, index = 0)
143
+ raise "#{item} not found" unless keys.include?(item)
144
+
145
+ if Range === index
146
+ @hash[item][index].map { |x| x.intern }
147
+ else
148
+ @hash[item][index].intern
149
+ end
150
+ end
151
+ alias sym symbol
152
+ end
153
+ end