gmsec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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