gmsec 0.0.1

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.
@@ -0,0 +1,231 @@
1
+ class GMSEC::Field
2
+ extend GMSEC::API
3
+
4
+ bind :GMSEC_FIELD_OBJECT do |pointer|
5
+ gmsec_CreateField(pointer, status)
6
+ end
7
+
8
+ has :status
9
+
10
+ # Map GMSEC values to deftypes. Note that we list backward compatible aliases first.
11
+ GMSEC_TYPEDEF = {
12
+ GMSEC_TYPE_DOUBLE => :double,
13
+ GMSEC_TYPE_FLOAT => :float,
14
+ GMSEC_TYPE_LONG => :long,
15
+ GMSEC_TYPE_SHORT => :short,
16
+ GMSEC_TYPE_ULONG => :ulong,
17
+ GMSEC_TYPE_USHORT => :ushort,
18
+ GMSEC_TYPE_BOOL => :bool,
19
+ GMSEC_TYPE_CHAR => :char,
20
+ GMSEC_TYPE_F32 => :f32,
21
+ GMSEC_TYPE_F64 => :f64,
22
+ GMSEC_TYPE_I16 => :i16,
23
+ GMSEC_TYPE_I32 => :i32,
24
+ GMSEC_TYPE_STR => :str,
25
+ GMSEC_TYPE_U16 => :u16,
26
+ GMSEC_TYPE_U32 => :u32,
27
+ GMSEC_TYPE_UNSET => :unset}
28
+
29
+ TYPE_TO_GMSEC_VALUE = {
30
+ bool: GMSEC_TYPE_BOOL,
31
+ char: GMSEC_TYPE_CHAR,
32
+ double: GMSEC_TYPE_DOUBLE,
33
+ f32: GMSEC_TYPE_F32,
34
+ f64: GMSEC_TYPE_F64,
35
+ float: GMSEC_TYPE_FLOAT,
36
+ i16: GMSEC_TYPE_I16,
37
+ i32: GMSEC_TYPE_I32,
38
+ long: GMSEC_TYPE_LONG,
39
+ short: GMSEC_TYPE_SHORT,
40
+ str: GMSEC_TYPE_STR,
41
+ u16: GMSEC_TYPE_U16,
42
+ u32: GMSEC_TYPE_U32,
43
+ ulong: GMSEC_TYPE_ULONG,
44
+ unset: GMSEC_TYPE_UNSET,
45
+ ushort: GMSEC_TYPE_USHORT}
46
+
47
+ RUBY_TO_GMSEC_TYPE = {
48
+ FalseClass => :bool,
49
+ Fixnum => :i32,
50
+ Float => :double,
51
+ String => :str,
52
+ Symbol => :str,
53
+ TrueClass => :bool}
54
+
55
+ def initialize(name=nil, value=nil, type: nil)
56
+ if name
57
+ self.name = name
58
+ end
59
+
60
+ if type
61
+ self.type = type
62
+ end
63
+
64
+ if value
65
+ self.value = value
66
+ end
67
+ end
68
+
69
+ def name
70
+ with_string_pointer do |pointer|
71
+ gmsec_GetFieldName(self, pointer, status)
72
+ end
73
+ end
74
+
75
+ def name=(value)
76
+ gmsec_SetFieldName(self, value.to_s, status)
77
+ end
78
+
79
+ def value
80
+ field_type = "GMSEC_#{type.to_s.upcase}".to_sym
81
+ pointer = FFI::MemoryPointer.new(find_type(field_type))
82
+ send(get_field_value_method, self, pointer, status)
83
+ read_pointer_value(pointer)
84
+ end
85
+
86
+ def value=(value)
87
+ if type == :unset
88
+ # Guess what GMSEC type value is.
89
+ self.type = RUBY_TO_GMSEC_TYPE[value.class]
90
+ end
91
+
92
+ # Determind method on value type
93
+ method = "gmsec_SetFieldValue#{type.to_s.upcase}"
94
+
95
+ # Cast value based on value type.
96
+ value = case value
97
+ when Symbol
98
+ value.to_s
99
+ when TrueClass, FalseClass
100
+ value ? 1 : 0
101
+ else
102
+ value
103
+ end
104
+
105
+ # Cast value based on target type.
106
+ value = case type
107
+ when :bool
108
+ value ? 1 : 0
109
+ when :i16, :i32, :u16, :u32
110
+ value.to_i
111
+ when :f32, :f64
112
+ value.to_f
113
+ when :char
114
+ value.ord
115
+ when :str
116
+ value.to_s
117
+ else
118
+ raise RuntimeError.new("Error in assigning value to field: type '#{type}' not supported")
119
+ end
120
+
121
+ send(method, self, value, status)
122
+ end
123
+
124
+ def type
125
+ # Create a pointer to GMSEC_TYPE that we're going to read and convert to a symbol.
126
+ pointer = FFI::MemoryPointer.new(find_type(:GMSEC_TYPE))
127
+
128
+ gmsec_GetFieldType(self, pointer, status)
129
+
130
+ # Default to GMSEC_STR if type is not registered in GMSEC_DEF
131
+ GMSEC_TYPEDEF[pointer.read_ushort] || :str
132
+ end
133
+
134
+ def type=(type)
135
+ if type.nil?
136
+ raise TypeError.new("#{value.class} is not supported as a GMSEC type.")
137
+ end
138
+
139
+ field_type = TYPE_TO_GMSEC_VALUE[type]
140
+ gmsec_SetFieldType(self, field_type, status)
141
+
142
+ if status.is_error?
143
+ raise RuntimeError.new("Error in specifying type '#{type}': #{status}")
144
+ end
145
+ end
146
+
147
+ protected
148
+
149
+ def get_field_value_method
150
+ "gmsec_GetFieldValue#{type.to_s.upcase.split("_").last}"
151
+ end
152
+
153
+ def read_pointer_value(pointer)
154
+ case type
155
+ when :char
156
+ pointer.read_string(1)
157
+ when :bool
158
+ pointer.read_int == self.class.enum_type(:GMSEC_BOOL)[:GMSEC_TRUE]
159
+ when :short
160
+ pointer.read_short
161
+ when :ushort
162
+ pointer.read_ushort
163
+ when :long
164
+ pointer.read_long
165
+ when :double
166
+ pointer.read_double
167
+ when :str
168
+ pointer.read_pointer.read_string_to_null
169
+ when :i16
170
+ pointer.read_int16
171
+ when :i32
172
+ pointer.read_int32
173
+ when :i64
174
+ pointer.read_int64
175
+ when :u16
176
+ pointer.read_uint16
177
+ when :u32
178
+ pointer.read_uint32
179
+ when :f32, :float
180
+ pointer.read_float
181
+ when :f64
182
+ pointer.read_double
183
+ else
184
+ raise TypeError.new("#{type} is not a supported type.")
185
+ end
186
+ end
187
+
188
+ attach_function :gmsec_CreateField, [:pointer, GMSEC::Status], :void
189
+ attach_function :gmsec_DestroyField, [:pointer, GMSEC::Status], :void
190
+ attach_function :gmsec_GetFieldName, [self, :pointer, GMSEC::Status], :void
191
+ attach_function :gmsec_SetFieldName, [self, :string, GMSEC::Status], :void
192
+ attach_function :gmsec_SetFieldType, [self, :GMSEC_TYPE, GMSEC::Status], :void
193
+ attach_function :gmsec_GetFieldType, [self, :pointer, GMSEC::Status], :void
194
+ attach_function :gmsec_GetFieldValueCHAR, [self, :pointer, GMSEC::Status], :void
195
+ attach_function :gmsec_GetFieldValueBOOL, [self, :pointer, GMSEC::Status], :void
196
+ attach_function :gmsec_GetFieldValueSHORT, [self, :pointer, GMSEC::Status], :void
197
+ attach_function :gmsec_GetFieldValueUSHORT, [self, :pointer, GMSEC::Status], :void
198
+ attach_function :gmsec_GetFieldValueLONG, [self, :pointer, GMSEC::Status], :void
199
+ attach_function :gmsec_GetFieldValueULONG, [self, :pointer, GMSEC::Status], :void
200
+ attach_function :gmsec_GetFieldValueFLOAT, [self, :pointer, GMSEC::Status], :void
201
+ attach_function :gmsec_GetFieldValueDOUBLE, [self, :pointer, GMSEC::Status], :void
202
+ attach_function :gmsec_GetFieldValueSTRING, [self, :pointer, GMSEC::Status], :void
203
+ attach_function :gmsec_GetFieldValueSTR, [self, :pointer, GMSEC::Status], :void
204
+ attach_function :gmsec_GetFieldValueI16, [self, :pointer, GMSEC::Status], :void
205
+ attach_function :gmsec_GetFieldValueU16, [self, :pointer, GMSEC::Status], :void
206
+ attach_function :gmsec_GetFieldValueI32, [self, :pointer, GMSEC::Status], :void
207
+ attach_function :gmsec_GetFieldValueU32, [self, :pointer, GMSEC::Status], :void
208
+ attach_function :gmsec_GetFieldValueF32, [self, :pointer, GMSEC::Status], :void
209
+ attach_function :gmsec_GetFieldValueF64, [self, :pointer, GMSEC::Status], :void
210
+ attach_function :gmsec_GetFieldValueSTRING, [self, :pointer, GMSEC::Status], :void
211
+ attach_function :gmsec_GetFieldValueI64, [self, :pointer, GMSEC::Status], :void
212
+ attach_function :gmsec_SetFieldValueCHAR, [self, :GMSEC_CHAR, GMSEC::Status], :void
213
+ attach_function :gmsec_SetFieldValueBOOL, [self, :GMSEC_BOOL, GMSEC::Status], :void
214
+ attach_function :gmsec_SetFieldValueSHORT, [self, :GMSEC_SHORT, GMSEC::Status], :void
215
+ attach_function :gmsec_SetFieldValueUSHORT, [self, :GMSEC_USHORT, GMSEC::Status], :void
216
+ attach_function :gmsec_SetFieldValueLONG, [self, :GMSEC_LONG, GMSEC::Status], :void
217
+ attach_function :gmsec_SetFieldValueULONG, [self, :GMSEC_ULONG, GMSEC::Status], :void
218
+ attach_function :gmsec_SetFieldValueFLOAT, [self, :GMSEC_FLOAT, GMSEC::Status], :void
219
+ attach_function :gmsec_SetFieldValueDOUBLE, [self, :GMSEC_DOUBLE, GMSEC::Status], :void
220
+ attach_function :gmsec_SetFieldValueSTRING, [self, :GMSEC_STR, GMSEC::Status], :void
221
+ attach_function :gmsec_SetFieldValueSTR, [self, :GMSEC_STR, GMSEC::Status], :void
222
+ attach_function :gmsec_SetFieldValueI16, [self, :GMSEC_I16, GMSEC::Status], :void
223
+ attach_function :gmsec_SetFieldValueU16, [self, :GMSEC_U16, GMSEC::Status], :void
224
+ attach_function :gmsec_SetFieldValueI32, [self, :GMSEC_I32, GMSEC::Status], :void
225
+ attach_function :gmsec_SetFieldValueU32, [self, :GMSEC_U32, GMSEC::Status], :void
226
+ attach_function :gmsec_SetFieldValueF32, [self, :GMSEC_F32, GMSEC::Status], :void
227
+ attach_function :gmsec_SetFieldValueF64, [self, :GMSEC_F64, GMSEC::Status], :void
228
+ attach_function :gmsec_SetFieldValueI64, [self, :GMSEC_I64, GMSEC::Status], :void
229
+ attach_function :gmsec_UnSetField, [self, GMSEC::Status], :void
230
+ attach_function :gmsec_LookupFieldType, [:string], :GMSEC_TYPE
231
+ end
@@ -0,0 +1,211 @@
1
+ class GMSEC::Message
2
+ extend GMSEC::API
3
+
4
+ has :status
5
+
6
+ bind :GMSEC_MESSAGE_OBJECT
7
+
8
+ def load_fields_from_config_file(config_file, message_name)
9
+ config_file.get_message(message_name, message: self)
10
+ end
11
+
12
+ def type
13
+ pointer = FFI::MemoryPointer.new(find_type(:GMSEC_MSG_KIND))
14
+ gmsec_GetMsgKind(self, pointer, status)
15
+
16
+ if status.is_error?
17
+ raise RuntimeError.new("Error getting message type: #{status}")
18
+ end
19
+
20
+ case pointer.read_ushort
21
+ when GMSEC_MSG_PUBLISH
22
+ :publish
23
+ when GMSEC_MSG_REPLY
24
+ :reply
25
+ when GMSEC_MSG_REQUEST
26
+ :request
27
+ when GMSEC_MSG_UNSET
28
+ :unset
29
+ else
30
+ raise TypeError.new("Unrecognized GMSEC data type")
31
+ end
32
+ end
33
+
34
+ def type=(type)
35
+ value = case type
36
+ when :publish
37
+ GMSEC_MSG_PUBLISH
38
+ when :reply
39
+ GMSEC_MSG_REPLY
40
+ when :request
41
+ GMSEC_MSG_REQUEST
42
+ when :unset
43
+ GMSEC_MSG_REQUEST
44
+ else
45
+ raise TypeError.new("#{type} is not supported as a GMSEC type.")
46
+ end
47
+
48
+ gmsec_SetMsgKind(self, value, status)
49
+
50
+ if status.is_error?
51
+ raise RuntimeError.new("Error setting message type: #{status}")
52
+ end
53
+ end
54
+
55
+ def subject
56
+ with_string_pointer do |pointer|
57
+ gmsec_GetMsgSubject(self, pointer, status)
58
+
59
+ if status.is_error?
60
+ raise RuntimeError.new("Error getting message subject: #{status}")
61
+ end
62
+ end
63
+ end
64
+
65
+ def subject=(subject)
66
+ gmsec_SetMsgSubject(self, subject, status)
67
+
68
+ if status.is_error?
69
+ raise RuntimeError.new("Error setting message subject: #{status}")
70
+ end
71
+ end
72
+
73
+ def config=(config)
74
+ gmsec_MsgSetConfig(self, config, status)
75
+
76
+ if status.is_error?
77
+ raise RuntimeError.new("Error setting message config: #{status}")
78
+ end
79
+ end
80
+
81
+ def clear_fields
82
+ gmsec_MsgClearFields(self, status)
83
+
84
+ if status.is_error?
85
+ raise RuntimeError.new("Error clearing message fields: #{status}")
86
+ end
87
+ end
88
+
89
+ def clear_field(name)
90
+ gmsec_MsgClearField(self, name.to_s, status)
91
+
92
+ if status.is_error?
93
+ raise RuntimeError.new("Error clearing message field: #{status}")
94
+ end
95
+ end
96
+
97
+ def [](name)
98
+ field = GMSEC::Field.new
99
+ gmsec_MsgGetField(self, name.to_s, field, status)
100
+
101
+ case status.code
102
+ when GMSEC_STATUS_NO_ERROR
103
+ field.value
104
+ when !GMSEC_INVALID_FIELD_NAME
105
+ raise RuntimeError.new("Error getting message field: #{status}")
106
+ end
107
+ end
108
+
109
+ def []=(name, value)
110
+ self << GMSEC::Field.new(name, value)
111
+ end
112
+
113
+ def <<(data)
114
+ # We can append a single Field or multiple fields encapsulated as a Hash.
115
+ if data.is_a? GMSEC::Field
116
+ gmsec_MsgAddField(self, data, status)
117
+ elsif data.is_a? Hash
118
+ data.each do |key, value|
119
+ self << GMSEC::Field.new(key, value)
120
+ end
121
+ elsif data
122
+ raise TypeError.new("#{data.class} is not supported as a GMSEC field type.")
123
+ end
124
+
125
+ if status.is_error?
126
+ raise RuntimeError.new("Error adding data to message: #{status}")
127
+ end
128
+ end
129
+
130
+ def length
131
+ pointer = FFI::MemoryPointer.new(find_type(:GMSEC_I32))
132
+ gmsec_MsgGetFieldCount(self, pointer, status)
133
+ pointer.read_int32
134
+ end
135
+
136
+ def fields
137
+ Enumerator.new do |y|
138
+ field = GMSEC::Field.new
139
+ gmsec_MsgGetFirstField(self, field, status)
140
+
141
+ while status.code != GMSEC_FIELDS_END_REACHED && status.code == GMSEC_STATUS_NO_ERROR
142
+ y << field
143
+ gmsec_MsgGetNextField(self, field, status)
144
+ end
145
+
146
+ unless status.code == GMSEC_FIELDS_END_REACHED
147
+ raise RuntimeError.new("Error reading message fields: #{status}")
148
+ end
149
+ end
150
+ end
151
+
152
+ def to_s
153
+ ::Terminal::Table.new(title: subject, rows: to_h)
154
+ end
155
+
156
+ def to_h
157
+ Hash[fields.map{|field| [field.name, field.value]}]
158
+ end
159
+
160
+ def to_xml
161
+ with_string_pointer do |pointer|
162
+ gmsec_MsgToXML(self, pointer, status)
163
+
164
+ if status.is_error?
165
+ raise RuntimeError.new("Error converting message to xml: #{status}")
166
+ end
167
+ end
168
+ end
169
+
170
+ def from_xml(xml)
171
+ gmsec_MsgFromXML(self, xml, status).tap do |_|
172
+ if status.is_error?
173
+ raise RuntimeError.new("Error converting xml to message: #{status}")
174
+ end
175
+ end
176
+ end
177
+
178
+ def size
179
+ pointer = FFI::MemoryPointer.new(find_type(:GMSEC_U32))
180
+ gmsec_MsgGetSize(self, pointer, status)
181
+ pointer.read_uint32
182
+ end
183
+
184
+ def time
185
+ gmsec_MsgGetTime
186
+ end
187
+
188
+ def valid?
189
+ gmsec_isMsgValid(self) == self.class.enum_type(:GMSEC_BOOL)[:GMSEC_TRUE]
190
+ end
191
+
192
+ protected
193
+
194
+ attach_function :gmsec_SetMsgKind, [self, :GMSEC_MSG_KIND, GMSEC::Status], :void
195
+ attach_function :gmsec_GetMsgKind, [self, :pointer, GMSEC::Status], :void
196
+ attach_function :gmsec_SetMsgSubject, [self, :string, GMSEC::Status], :void
197
+ attach_function :gmsec_GetMsgSubject, [self, :pointer, GMSEC::Status], :void
198
+ attach_function :gmsec_MsgSetConfig, [self, GMSEC::Config, GMSEC::Status], :void
199
+ attach_function :gmsec_MsgClearFields, [self, GMSEC::Status], :void
200
+ attach_function :gmsec_MsgAddField, [self, GMSEC::Field, GMSEC::Status], :void
201
+ attach_function :gmsec_MsgClearField, [self, :string, GMSEC::Status], :void
202
+ attach_function :gmsec_MsgGetField, [self, :string, GMSEC::Field, GMSEC::Status], :void
203
+ attach_function :gmsec_MsgGetFieldCount, [self, :pointer, GMSEC::Status], :void
204
+ attach_function :gmsec_MsgGetFirstField, [self, GMSEC::Field, GMSEC::Status], :void
205
+ attach_function :gmsec_MsgGetNextField, [self, GMSEC::Field, GMSEC::Status], :void
206
+ attach_function :gmsec_MsgToXML, [self, :pointer, GMSEC::Status], :void
207
+ attach_function :gmsec_MsgFromXML, [self, :string, GMSEC::Status], :void
208
+ attach_function :gmsec_MsgGetSize, [self, :pointer, GMSEC::Status], :void
209
+ attach_function :gmsec_MsgGetTime, [], :string
210
+ attach_function :gmsec_isMsgValid, [self], :int
211
+ end
@@ -0,0 +1,30 @@
1
+ class GMSEC::Status
2
+ extend GMSEC::API
3
+
4
+ bind :GMSEC_STATUS_OBJECT do |pointer|
5
+ gmsec_CreateStatus(pointer)
6
+ end
7
+
8
+ def is_error?
9
+ gmsec_isStatusError(self) > 0
10
+ end
11
+
12
+ def to_s
13
+ gmsec_GetStatusString(self)
14
+ end
15
+
16
+ def code
17
+ gmsec_GetStatusCode(self)
18
+ end
19
+
20
+ protected
21
+
22
+ attach_function :gmsec_CreateStatus, [:pointer], :void
23
+ attach_function :gmsec_DestroyStatus, [:pointer], :void
24
+ attach_function :gmsec_GetStatus, [self], :string
25
+ attach_function :gmsec_GetStatusString, [self], :string
26
+ attach_function :gmsec_GetStatusClass, [self], find_type(:GMSEC_STATUS_CLASS)
27
+ attach_function :gmsec_GetStatusCode, [self], :uint
28
+ attach_function :gmsec_GetStatusCustomCode, [self], :int
29
+ attach_function :gmsec_isStatusError, [self], :int
30
+ end