@@ -159,46 +159,91 @@ namespace mtconnect::pipeline {
159
159
Forward m_forward;
160
160
};
161
161
162
- const static map<std::string_view,KeyToken> ConditionMap {
163
- { " nativeCode" , KeyToken::NATIVE_CODE },
164
- { " conditionId" , KeyToken::CONDITION_ID },
165
- { " qualifier" , KeyToken::QUALIFIER },
166
- { " nativeSeverity" , KeyToken::NATIVE_SEVERITY },
167
- { " level" , KeyToken::LEVEL },
168
- { " value" , KeyToken::VALUE },
169
- { " message" , KeyToken::VALUE },
170
- };
171
-
172
- // / @brief SAX Parser handler for JSON Parsing
173
- struct FieldHandler : rj::BaseReaderHandler<rj::UTF8<>, FieldHandler>
162
+ struct VectorHandler : rj::BaseReaderHandler<rj::UTF8<>, VectorHandler>
174
163
{
175
- FieldHandler (ParserContext &context )
176
- : m_context(context )
164
+ VectorHandler (entity::Vector &vector )
165
+ : m_value(vector )
177
166
{
178
167
}
179
168
180
169
bool Null ()
181
170
{
182
- m_context.m_value = " UNAVAILABLE" ;
171
+ return true ;
172
+ }
173
+
174
+ bool Int (int i) { return Double (i); }
175
+ bool Uint (unsigned i) { return Double (i); }
176
+ bool Int64 (int64_t i) { return Double (i); }
177
+ bool Uint64 (uint64_t i) { return Double (i); }
178
+
179
+ bool Double (double d)
180
+ {
181
+ m_value.push_back (d);
182
+ return true ;
183
+ }
184
+
185
+ bool Default ()
186
+ {
187
+ LOG (warning) << " Invalid vector value, expected only doubles" ;
188
+ return false ;
189
+ }
190
+
191
+ bool EndArray (rj::SizeType count)
192
+ {
193
+ m_done = true ;
194
+ if (m_value.size () != count)
195
+ {
196
+ LOG (warning) << " Invalid array of values, size: " << m_value.size ()
197
+ << " , expected: " << count;
198
+ return false ;
199
+ }
200
+ return true ;
201
+ }
202
+
203
+ bool operator ()(rj::Reader &reader, rj::StringStream &buff)
204
+ {
205
+ while (!reader.IterativeParseComplete () && !m_done)
206
+ {
207
+ if (!reader.IterativeParseNext <rj::kParseNanAndInfFlag >(buff, *this ))
208
+ {
209
+ LOG (warning) << " Cannot parse double vector" ;
210
+ m_value.clear ();
211
+ return false ;
212
+ }
213
+ }
214
+
215
+ return true ;
216
+ }
217
+
218
+ entity::Vector &m_value;
219
+ bool m_done { false };
220
+ };
221
+
222
+ // / @brief SAX Parser handler for JSON Parsing
223
+ struct ValueHandler : rj::BaseReaderHandler<rj::UTF8<>, ValueHandler>
224
+ {
225
+ bool Null ()
226
+ {
227
+ m_value.emplace <nullptr_t >();
183
228
return true ;
184
229
}
185
230
186
231
bool Bool (bool b)
187
232
{
188
- m_context. m_value = b ;
233
+ m_value. emplace < bool >(b) ;
189
234
return true ;
190
235
}
191
236
bool Int (int i) { return Int64 (i); }
192
237
bool Uint (unsigned i) { return Int64 (i); }
238
+ bool Uint64 (uint64_t i) { return Int64 (i); }
193
239
bool Int64 (int64_t i)
194
240
{
195
- m_context. m_value = i ;
241
+ m_value. emplace < int64_t >(i) ;
196
242
return true ;
197
243
}
198
- bool Uint64 (uint64_t i) { return Int64 (i); }
199
- bool Double (double d)
244
+ bool Double (double d)
200
245
{
201
- m_context. m_value = d ;
246
+ m_value. emplace < double >(d) ;
202
247
return true ;
203
248
}
204
249
bool RawNumber (const Ch *str, rj::SizeType length, bool copy)
@@ -207,29 +252,127 @@ namespace mtconnect::pipeline {
207
252
}
208
253
bool String (const Ch *str, rj::SizeType length, bool copy)
209
254
{
210
- m_context. m_value = std::string (str, length);
255
+ m_value. emplace < std::string> (str, length);
211
256
return true ;
212
257
}
213
258
bool StartObject ()
214
259
{
260
+ // We use an entity pointer to signal we have a property set.
261
+ // The PropertiesHandler will map each of the properties in the object
262
+ // to the properties.
263
+ m_value.emplace <EntityPtr>();
215
264
return true ;
216
265
}
217
266
bool Key (const Ch *str, rj::SizeType length, bool copy)
218
267
{
219
268
return false ;
220
269
}
221
270
bool EndObject (rj::SizeType memberCount) { return true ; }
222
- bool StartArray () { return true ; }
223
- bool EndArray (rj::SizeType elementCount) { return true ; }
271
+ bool StartArray ()
272
+ {
273
+ m_value.emplace <Vector>();
274
+ return true ;
275
+ }
276
+ bool EndArray (rj::SizeType elementCount)
277
+ {
278
+ return false ;
279
+ }
224
280
225
- bool operator ()(rj::Reader &reader, rj::StringStream &buff)
281
+ entity::Value operator ()(rj::Reader &reader, rj::StringStream &buff)
226
282
{
227
283
auto success = (!reader.IterativeParseComplete () &&
228
284
reader.IterativeParseNext <rj::kParseNanAndInfFlag >(buff, *this ));
229
- return success;
285
+ if (!success)
286
+ {
287
+ LOG (warning) << " Cannot get value for json mapper" ;
288
+ m_value = monostate ();
289
+ }
290
+ else if (holds_alternative<Vector>(m_value))
291
+ {
292
+ VectorHandler handler (get<Vector>(m_value));
293
+ handler (reader, buff);
294
+ }
295
+ return m_value;
230
296
}
231
297
232
- ParserContext &m_context;
298
+ entity::Value m_value { std::monostate () };
299
+ bool m_done { true };
300
+ };
301
+
302
+ const static map<std::string_view, std::string_view> PropertyMap {
303
+ { " value" , " VALUE" },
304
+ { " message" , " VALUE" }
305
+ };
306
+
307
+ struct PropertiesHandler : rj::BaseReaderHandler<rj::UTF8<>, PropertiesHandler>
308
+ {
309
+ PropertiesHandler (entity::Properties &props)
310
+ : m_props(props)
311
+ {
312
+ }
313
+
314
+ bool Default ()
315
+ {
316
+ LOG (warning) << " Expecting an object with keys and values" ;
317
+ return false ;
318
+ }
319
+
320
+
321
+ bool Key (const Ch *str, rj::SizeType length, bool copy)
322
+ {
323
+ std::string_view sv (str, length);
324
+ auto f = PropertyMap.find (sv);
325
+ if (f != PropertyMap.end ())
326
+ {
327
+ m_key = f->second ;
328
+ }
329
+ else
330
+ {
331
+ m_key = sv;
332
+ }
333
+
334
+ return true ;
335
+ }
336
+
337
+ bool StartObject ()
338
+ {
339
+ LOG (warning) << " Expecting not expecting sub-objects" ;
340
+ return false ;
341
+ }
342
+
343
+ bool EndObject (rj::SizeType memberCount)
344
+ {
345
+ m_done = true ;
346
+ return true ;
347
+ }
348
+
349
+ bool operator ()(rj::Reader &reader, rj::StringStream &buff)
350
+ {
351
+ while (!reader.IterativeParseComplete () && !m_done)
352
+ {
353
+ if (!reader.IterativeParseNext <rj::kParseNanAndInfFlag >(buff, *this ))
354
+ return false ;
355
+ else if (m_done)
356
+ break ;
357
+
358
+ ValueHandler handler;
359
+ auto value = handler (reader, buff);
360
+ if (!std::holds_alternative<std::monostate>(value) && !m_key.empty ())
361
+ {
362
+ m_props.insert_or_assign (m_key, value);
363
+ }
364
+ else
365
+ {
366
+ LOG (warning) << " Could not map " << m_key;
367
+ }
368
+ }
369
+
370
+ return true ;
371
+ }
372
+
373
+ entity::Properties &m_props;
374
+ bool m_done { false };
375
+ std::string m_key;
233
376
};
234
377
235
378
struct DataItemHandler : rj::BaseReaderHandler<rj::UTF8<>, DataItemHandler>
@@ -319,6 +462,7 @@ namespace mtconnect::pipeline {
319
462
: m_context(context)
320
463
{
321
464
}
465
+
322
466
323
467
bool Default ()
324
468
{
@@ -427,9 +571,28 @@ namespace mtconnect::pipeline {
427
571
428
572
default :
429
573
{
430
- FieldHandler handler (m_context);
431
- if (!handler (reader, buff))
574
+ ValueHandler handler;
575
+ auto value = handler (reader, buff);
576
+ if (std::holds_alternative<std::monostate>(value))
432
577
return false ;
578
+ else if (std::holds_alternative<EntityPtr>(value))
579
+ {
580
+ PropertiesHandler props (m_context.m_props );
581
+ if (!props (reader, buff))
582
+ return false ;
583
+ auto value = m_context.m_props .find (" VALUE" );
584
+ if (value == m_context.m_props .end () && holds_alternative<monostate>(value->second ))
585
+ {
586
+ LOG (warning) << " value was not given for data item " << m_context.m_dataItem ->getId ();
587
+ return false ;
588
+ }
589
+ m_context.m_value = value->second ;
590
+ m_context.m_props .erase (value);
591
+ }
592
+ else
593
+ {
594
+ m_context.m_value = value;
595
+ }
433
596
m_context.send ();
434
597
break ;
435
598
}
@@ -461,13 +624,17 @@ namespace mtconnect::pipeline {
461
624
}
462
625
bool EndObject (rj::SizeType memberCount)
463
626
{
464
- m_context.m_state = ParserState::NONE;
627
+ return true ;
628
+ }
629
+ bool EndArray (rj::SizeType memberCount)
630
+ {
631
+ m_complete = true ;
465
632
return true ;
466
633
}
467
634
468
635
bool operator ()(rj::Reader &reader, rj::StringStream &buff)
469
636
{
470
- while (!reader.IterativeParseComplete ())
637
+ while (!reader.IterativeParseComplete () && !m_complete )
471
638
{
472
639
if (!reader.IterativeParseNext <rj::kParseNanAndInfFlag >(buff, *this ))
473
640
return false ;
@@ -480,6 +647,7 @@ namespace mtconnect::pipeline {
480
647
else
481
648
{
482
649
LOG (warning) << " Only objects allowed as members of top level array" ;
650
+ return false ;
483
651
}
484
652
}
485
653
@@ -508,7 +676,11 @@ namespace mtconnect::pipeline {
508
676
return true ;
509
677
}
510
678
bool EndObject (rj::SizeType memberCount) { return true ; }
511
- bool StartArray () { return true ; }
679
+ bool StartArray ()
680
+ {
681
+ m_state = ParserState::ARRAY;
682
+ return true ;
683
+ }
512
684
bool EndArray (rj::SizeType elementCount) { return true ; }
513
685
514
686
bool operator ()(rj::Reader &reader, rj::StringStream &buff)
0 commit comments