OpenDDS  Snapshot(2023/04/28-20:55)
JsonValueReader.h
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.opendds.org/license.html
4  */
5 
6 #ifndef OPENDDS_DCPS_JSON_VALUE_READER_H
7 #define OPENDDS_DCPS_JSON_VALUE_READER_H
8 
9 #if defined OPENDDS_RAPIDJSON && !defined OPENDDS_SAFETY_PROFILE
10 # define OPENDDS_HAS_JSON_VALUE_READER 1
11 #else
12 # define OPENDDS_HAS_JSON_VALUE_READER 0
13 #endif
14 
15 #if OPENDDS_HAS_JSON_VALUE_READER
16 
17 #include "dcps_export.h"
18 #include "ValueReader.h"
19 #include "RapidJsonWrapper.h"
20 #include "TypeSupportImpl.h"
21 #include "Definitions.h"
22 
23 #include <iosfwd>
24 #include <sstream>
25 
26 #if !defined (ACE_LACKS_PRAGMA_ONCE)
27 #pragma once
28 #endif /* ACE_LACKS_PRAGMA_ONCE */
29 
31 
32 namespace OpenDDS {
33 namespace DCPS {
34 
35 /// Convert JSON to values.
36 template <typename InputStream = rapidjson::StringStream>
37 class JsonValueReader
38  : public ValueReader,
39  public rapidjson::BaseReaderHandler<rapidjson::UTF8<> > {
40 public:
41  explicit JsonValueReader(InputStream& input_stream)
42  : token_type_(kUnknown)
43  , input_stream_(input_stream)
44  , bool_value_(false)
45  , int_value_(0)
46  , uint_value_(0)
47  , int64_value_(0)
48  , uint64_value_(0)
49  , double_value_(0)
50  {
51  reader_.IterativeParseInit();
52  }
53 
54  bool begin_struct();
55  bool end_struct();
56  bool begin_struct_member(XTypes::MemberId& member_id, const MemberHelper& helper);
57  bool end_struct_member();
58 
59  bool begin_union();
60  bool end_union();
61  bool begin_discriminator();
62  bool end_discriminator();
63  bool begin_union_member();
64  bool end_union_member();
65 
66  bool begin_array();
67  bool end_array();
68  bool begin_sequence();
69  bool elements_remaining();
70  bool end_sequence();
71  bool begin_element();
72  bool end_element();
73 
74  bool read_boolean(ACE_CDR::Boolean& value);
75  bool read_byte(ACE_CDR::Octet& value);
76 #if OPENDDS_HAS_EXPLICIT_INTS
77  bool read_int8(ACE_CDR::Int8& value);
78  bool read_uint8(ACE_CDR::UInt8& value);
79 #endif
80  bool read_int16(ACE_CDR::Short& value);
81  bool read_uint16(ACE_CDR::UShort& value);
82  bool read_int32(ACE_CDR::Long& value);
83  bool read_uint32(ACE_CDR::ULong& value);
84  bool read_int64(ACE_CDR::LongLong& value);
85  bool read_uint64(ACE_CDR::ULongLong& value);
86  bool read_float32(ACE_CDR::Float& value);
87  bool read_float64(ACE_CDR::Double& value);
88  bool read_float128(ACE_CDR::LongDouble& value);
89  bool read_fixed(OpenDDS::FaceTypes::Fixed& value);
90  bool read_char8(ACE_CDR::Char& value);
91  bool read_char16(ACE_CDR::WChar& value);
92  bool read_string(std::string& value);
93  bool read_wstring(std::wstring& value);
94  bool read_long_enum(ACE_CDR::Long& value, const EnumHelper& helper);
95 
96  bool Null() { token_type_ = kNull; return true; }
97  bool Bool(bool b) { token_type_ = kBool; bool_value_ = b; return true; }
98  bool Int(int i) { token_type_ = kInt; int_value_ = i; return true; }
99  bool Uint(unsigned i) { token_type_ = kUint; uint_value_ = i; return true; }
100  bool Int64(int64_t i) { token_type_ = kInt64; int64_value_ = i; return true; }
101  bool Uint64(uint64_t i) { token_type_ = kUint64; uint64_value_ = i; return true; }
102  bool Double(double d) { token_type_ = kDouble; double_value_ = d; return true; }
103  bool RawNumber(const Ch* /* str */, rapidjson::SizeType /* length */, bool /* copy */) { token_type_ = kRawNumber; return true; }
104  bool String(const Ch* str, rapidjson::SizeType length, bool /* copy */)
105  {
106  token_type_ = kString;
107  string_value_ = std::string(str, length);
108  return true;
109  }
110  bool StartObject() { token_type_ = kStartObject; return true; }
111  bool Key(const Ch* str, rapidjson::SizeType /* length */, bool /* copy */) { token_type_ = kKey; key_value_ = str; return true; }
112  bool EndObject(rapidjson::SizeType /* memberCount */) { token_type_ = kEndObject; return true; }
113  bool StartArray() { token_type_ = kStartArray; return true; }
114  bool EndArray(rapidjson::SizeType /* elementCount */) { token_type_ = kEndArray; return true; }
115 
116 private:
117  enum TokenType {
118  kUnknown,
119  kNull,
120  kBool,
121  kInt,
122  kUint,
123  kInt64,
124  kUint64,
125  kDouble,
126  kRawNumber,
127  kString,
128  kStartObject,
129  kKey,
130  kEndObject,
131  kStartArray,
132  kEndArray,
133  kError,
134  kEnd
135  };
136 
137  TokenType peek()
138  {
139  if (token_type_ != kUnknown) {
140  return token_type_;
141  }
142 
143  if (reader_.IterativeParseComplete()) {
144  token_type_ = kEnd;
145  return token_type_;
146  }
147 
148  if (!reader_.IterativeParseNext<rapidjson::kParseStopWhenDoneFlag>(input_stream_, *this)) {
149  token_type_ = kError;
150  }
151 
152  return token_type_;
153  }
154 
155  bool consume(TokenType expected)
156  {
157  if (token_type_ == expected) {
158  token_type_ = kUnknown;
159  return true;
160  }
161  return false;
162  }
163 
164  // consume tokens until peek() would return 'expected'
165  // skips over objects and arrays atomically
166  bool skip_to(TokenType expected)
167  {
168  int skip_level = 0;
169 
170  while (peek() != kEnd) {
171  if (skip_level == 0 && token_type_ == expected) {
172  return true;
173  }
174  switch (token_type_) {
175  case kStartArray:
176  case kStartObject:
177  ++skip_level;
178  break;
179  case kEndArray:
180  case kEndObject:
181  --skip_level;
182  break;
183  default:
184  break;
185  }
186  consume(token_type_);
187  }
188 
189  return false;
190  }
191 
192  TokenType token_type_;
193  InputStream& input_stream_;
194  rapidjson::Reader reader_;
195  bool bool_value_;
196  int int_value_;
197  unsigned int uint_value_;
198  int64_t int64_value_;
199  uint64_t uint64_value_;
200  double double_value_;
201  std::string string_value_;
202  std::string key_value_;
203 };
204 
205 template <typename InputStream>
206 bool JsonValueReader<InputStream>::begin_struct()
207 {
208  peek();
209  return consume(kStartObject);
210 }
211 
212 template <typename InputStream>
213 bool JsonValueReader<InputStream>::end_struct()
214 {
215  if (peek() == kKey) { // skip any unknown members at the end
216  if (!skip_to(kEndObject)) {
217  return false;
218  }
219  }
220  return consume(kEndObject);
221 }
222 
223 template <typename InputStream>
224 bool JsonValueReader<InputStream>::begin_struct_member(XTypes::MemberId& member_id, const MemberHelper& helper)
225 {
226  while (peek() == kKey) {
227  consume(kKey);
228  if (helper.get_value(member_id, key_value_.c_str())) {
229  return true;
230  }
231  if (!skip_to(kKey)) { // skip unknown members when expecting a known member
232  return false;
233  }
234  }
235  return false;
236 }
237 
238 template <typename InputStream>
239 bool JsonValueReader<InputStream>::end_struct_member()
240 {
241  return true;
242 }
243 
244 template <typename InputStream>
245 bool JsonValueReader<InputStream>::begin_union()
246 {
247  peek();
248  return consume(kStartObject);
249 }
250 
251 template <typename InputStream>
252 bool JsonValueReader<InputStream>::end_union()
253 {
254  peek();
255  return consume(kEndObject);
256 }
257 
258 template <typename InputStream>
259 bool JsonValueReader<InputStream>::begin_discriminator()
260 {
261  if (peek() == kKey && key_value_ == "$discriminator") {
262  return consume(kKey);
263  }
264  return false;
265 }
266 
267 template <typename InputStream>
268 bool JsonValueReader<InputStream>::end_discriminator()
269 {
270  return true;
271 }
272 
273 template <typename InputStream>
274 bool JsonValueReader<InputStream>::begin_union_member()
275 {
276  if (peek() == kKey) {
277  return consume(kKey);
278  }
279  return false;
280 }
281 
282 template <typename InputStream>
283 bool JsonValueReader<InputStream>::end_union_member()
284 {
285  return true;
286 }
287 
288 template <typename InputStream>
289 bool JsonValueReader<InputStream>::begin_array()
290 {
291  peek();
292  return consume(kStartArray);
293 }
294 
295 template <typename InputStream>
296 bool JsonValueReader<InputStream>::end_array()
297 {
298  peek();
299  return consume(kEndArray);
300 }
301 
302 template <typename InputStream>
303 bool JsonValueReader<InputStream>::begin_sequence()
304 {
305  peek();
306  return consume(kStartArray);
307 }
308 
309 template <typename InputStream>
310 bool JsonValueReader<InputStream>::elements_remaining()
311 {
312  peek();
313  return token_type_ != kEndArray;
314 }
315 
316 template <typename InputStream>
317 bool JsonValueReader<InputStream>::end_sequence()
318 {
319  peek();
320  return consume(kEndArray);
321 }
322 
323 template <typename InputStream>
324 bool JsonValueReader<InputStream>::begin_element()
325 {
326  return true;
327 }
328 
329 template <typename InputStream>
330 bool JsonValueReader<InputStream>::end_element()
331 {
332  return true;
333 }
334 
335 template <typename InputStream>
336 bool JsonValueReader<InputStream>::read_boolean(ACE_CDR::Boolean& value)
337 {
338  if (peek() == kBool) {
339  value = bool_value_;
340  return consume(kBool);
341  }
342  return false;
343 }
344 
345 template <typename InputStream>
346 bool JsonValueReader<InputStream>::read_byte(ACE_CDR::Octet& value)
347 {
348  if (peek() == kUint) {
349  value = uint_value_;
350  return consume(kUint);
351  }
352  return false;
353 }
354 
355 #if OPENDDS_HAS_EXPLICIT_INTS
356 template <typename InputStream>
357 bool JsonValueReader<InputStream>::read_int8(ACE_CDR::Int8& value)
358 {
359  switch (peek()) {
360  case kInt:
361  value = int_value_;
362  return consume(kInt);
363  case kUint:
364  value = uint_value_;
365  return consume(kUint);
366  default:
367  return false;
368  }
369 }
370 
371 template <typename InputStream>
372 bool JsonValueReader<InputStream>::read_uint8(ACE_CDR::UInt8& value)
373 {
374  if (peek() == kUint) {
375  value = uint_value_;
376  return consume(kUint);
377  }
378  return false;
379 }
380 #endif
381 
382 template <typename InputStream>
383 bool JsonValueReader<InputStream>::read_int16(ACE_CDR::Short& value)
384 {
385  peek();
386  switch (peek()) {
387  case kInt:
388  value = int_value_;
389  return consume(kInt);
390  case kUint:
391  value = uint_value_;
392  return consume(kUint);
393  default:
394  return false;
395  }
396 }
397 
398 template <typename InputStream>
399 bool JsonValueReader<InputStream>::read_uint16(ACE_CDR::UShort& value)
400 {
401  if (peek() == kUint) {
402  value = uint_value_;
403  return consume(kUint);
404  }
405  return false;
406 }
407 
408 template <typename InputStream>
409 bool JsonValueReader<InputStream>::read_int32(ACE_CDR::Long& value)
410 {
411  switch (peek()) {
412  case kInt:
413  value = int_value_;
414  return consume(kInt);
415  case kUint:
416  value = uint_value_;
417  return consume(kUint);
418  default:
419  return false;
420  }
421 }
422 
423 template <typename InputStream>
424 bool JsonValueReader<InputStream>::read_uint32(ACE_CDR::ULong& value)
425 {
426  if (peek() == kUint) {
427  value = uint_value_;
428  return consume(kUint);
429  }
430  return false;
431 }
432 
433 template <typename InputStream>
434 bool JsonValueReader<InputStream>::read_int64(ACE_CDR::LongLong& value)
435 {
436  switch (peek()) {
437  case kInt64:
438  value = int64_value_;
439  return consume(kInt64);
440  case kUint64:
441  value = uint64_value_;
442  return consume(kUint64);
443  case kInt:
444  value = int_value_;
445  return consume(kInt);
446  case kUint:
447  value = uint_value_;
448  return consume(kUint);
449  default:
450  return false;
451  }
452 }
453 
454 template <typename InputStream>
455 bool JsonValueReader<InputStream>::read_uint64(ACE_CDR::ULongLong& value)
456 {
457  switch (peek()) {
458  case kUint64:
459  value = uint64_value_;
460  return consume(kUint64);
461  case kUint:
462  value = uint_value_;
463  return consume(kUint);
464  default:
465  return false;
466  }
467 }
468 
469 template <typename InputStream>
470 bool JsonValueReader<InputStream>::read_float32(ACE_CDR::Float& value)
471 {
472  switch (peek()) {
473  case kDouble:
474  value = ACE_CDR::Float(double_value_);
475  return consume(kDouble);
476  case kUint64:
477  value = ACE_CDR::Float(uint64_value_);
478  return consume(kUint64);
479  case kUint:
480  value = ACE_CDR::Float(uint_value_);
481  return consume(kUint);
482  case kInt64:
483  value = ACE_CDR::Float(int64_value_);
484  return consume(kInt64);
485  case kInt:
486  value = ACE_CDR::Float(int_value_);
487  return consume(kUint);
488  default:
489  return false;
490  }
491 }
492 
493 template <typename InputStream>
494 bool JsonValueReader<InputStream>::read_float64(ACE_CDR::Double& value)
495 {
496  switch (peek()) {
497  case kDouble:
498  value = double_value_;
499  return consume(kDouble);
500  case kUint64:
501  value = ACE_CDR::Double(uint64_value_);
502  return consume(kUint64);
503  case kUint:
504  value = uint_value_;
505  return consume(kUint);
506  case kInt64:
507  value = ACE_CDR::Double(int64_value_);
508  return consume(kInt64);
509  case kInt:
510  value = int_value_;
511  return consume(kUint);
512  default:
513  return false;
514  }
515 }
516 
517 template <typename InputStream>
518 bool JsonValueReader<InputStream>::read_float128(ACE_CDR::LongDouble& value)
519 {
520  switch (peek()) {
521  case kDouble:
522  ACE_CDR_LONG_DOUBLE_ASSIGNMENT(value, double_value_);
523  return consume(kDouble);
524  case kUint64:
525 #ifdef ACE_WIN32
526 # pragma warning(disable:4244)
527 #endif
528  ACE_CDR_LONG_DOUBLE_ASSIGNMENT(value, uint64_value_);
529 #ifdef ACE_WIN32
530 # pragma warning(default:4244)
531 #endif
532  return consume(kUint64);
533  case kUint:
534  ACE_CDR_LONG_DOUBLE_ASSIGNMENT(value, uint_value_);
535  return consume(kUint);
536  case kInt64:
537 #ifdef ACE_WIN32
538 # pragma warning(disable:4244)
539 #endif
540  ACE_CDR_LONG_DOUBLE_ASSIGNMENT(value, int64_value_);
541 #ifdef ACE_WIN32
542 # pragma warning(default:4244)
543 #endif
544  return consume(kInt64);
545  case kInt:
546  ACE_CDR_LONG_DOUBLE_ASSIGNMENT(value, int_value_);
547  return consume(kUint);
548  default:
549  return false;
550  }
551 }
552 
553 template <typename InputStream>
554 bool JsonValueReader<InputStream>::read_fixed(OpenDDS::FaceTypes::Fixed& /*value*/)
555 {
556  // TODO
557  if (peek() == kString) {
558  return consume(kString);
559  }
560  return false;
561 }
562 
563 template <typename InputStream>
564 bool JsonValueReader<InputStream>::read_char8(ACE_CDR::Char& value)
565 {
566  if (peek() == kString) {
567  if (string_value_.length() == 1) {
568  value = string_value_[0];
569  return consume(kString);
570  }
571  }
572  return false;
573 }
574 
575 template <typename InputStream>
576 bool JsonValueReader<InputStream>::read_char16(ACE_CDR::WChar& value)
577 {
578  if (peek() == kString) {
579  rapidjson::StringStream source(string_value_.c_str());
580  rapidjson::GenericStringBuffer<rapidjson::UTF16<> > target;
581 
582  while (source.Tell() != string_value_.size()) {
583  if (!rapidjson::Transcoder<rapidjson::UTF8<>, rapidjson::UTF16<> >::Transcode(source, target)) {
584  return false;
585  }
586  }
587 
588  if (target.GetLength() == 1) {
589  value = target.GetString()[0];
590  return consume(kString);
591  }
592  }
593  return false;
594 }
595 
596 template <typename InputStream>
597 bool JsonValueReader<InputStream>::read_string(std::string& value)
598 {
599  if (peek() == kString) {
600  value = string_value_;
601  return consume(kString);
602  }
603  return false;
604 }
605 
606 template <typename InputStream>
607 bool JsonValueReader<InputStream>::read_wstring(std::wstring& value)
608 {
609  if (peek() == kString) {
610  rapidjson::StringStream source(string_value_.c_str());
611  rapidjson::GenericStringBuffer<rapidjson::UTF16<> > target;
612 
613  while (source.Tell() != string_value_.size()) {
614  if (!rapidjson::Transcoder<rapidjson::UTF8<>, rapidjson::UTF16<> >::Transcode(source, target)) {
615  return false;
616  }
617  }
618 
619  value = target.GetString();
620  return consume(kString);
621  }
622  return false;
623 }
624 
625 template <typename InputStream>
626 bool JsonValueReader<InputStream>::read_long_enum(ACE_CDR::Long& value, const EnumHelper& helper)
627 {
628  switch (peek()) {
629  case kString:
630  if (helper.get_value(value, string_value_.c_str())) {
631  return consume(kString);
632  }
633  return false;
634  break;
635  case kInt:
636  value = int_value_;
637  return consume(kInt);
638  case kUint:
639  value = uint_value_;
640  return consume(kUint);
641  default:
642  return false;
643  }
644 }
645 
646 template<typename T, typename InputStream>
647 bool from_json(T& value, InputStream& stream)
648 {
649  set_default(value);
650  JsonValueReader<InputStream> jvr(stream);
651  return vread(jvr, value);
652 }
653 
654 } // namespace DCPS
655 } // namespace OpenDDS
656 
658 
659 #endif
660 
661 #endif /* OPENDDS_DCPS_JSON_VALUE_READER_H */
ACE_Byte Octet
ACE_CDR::ULong MemberId
Definition: TypeObject.h:910
ACE_INT64 LongLong
const LogLevel::Value value
Definition: debug.cpp:61
std::string String
void set_default(Type &)
Definition: Serializer.h:944
ACE_UINT64 ULongLong
bool vread(ValueReader &, XTypes::TypeIdentifier &)
ACE_INT16 Short
char Char
ACE_UINT16 UShort
ACE_UINT32 ULong
ACE_CDR::Int64 Int64
#define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS)
ACE_INT32 Long
ACE_INT8 Int8
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
ACE_WCHAR_T WChar
bool Boolean
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
ACE_UINT8 UInt8