Document.h
1 /*
2  Copyright (C) 2015-2023 by Dr. Marc Boris Duerner
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  As a special exception, you may use this file as part of a free
10  software library without restriction. Specifically, if other files
11  instantiate templates or use macros or inline functions from this
12  file, or you compile this file and link it with other files to
13  produce an executable, this file does not by itself cause the
14  resulting executable to be covered by the GNU General Public
15  License. This exception does not however invalidate any other
16  reasons why the executable file might be covered by the GNU Library
17  General Public License.
18 
19  This library is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  Lesser General Public License for more details.
23 
24  You should have received a copy of the GNU Lesser General Public
25  License along with this library; if not, write to the Free Software
26  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27  MA 02110-1301 USA
28 */
29 
30 #ifndef PT_JSON_DOCUMENT_H
31 #define PT_JSON_DOCUMENT_H
32 
33 #include <Pt/Json/Api.h>
34 #include <Pt/SerializationInfo.h>
35 #include <Pt/String.h>
36 #include <string>
37 #include <cstddef>
38 
39 namespace Pt {
40 
41 namespace Json {
42 
45 class PT_JSON_API Document
46 {
47  friend class DocumentReader;
48 
49  public:
52  class Element
53  {
54  public:
55  explicit Element(SerializationInfo* si = 0)
56  : _si(si)
57  {}
58 
59  Element(const Element& elem)
60  : _si(elem._si)
61  {}
62 
63  Element& operator=(const Element& elem)
64  {
65  _si = elem._si;
66  return *this;
67  }
68 
71  const char* name() const
72  { return _si->name(); }
73 
76  template <typename T>
77  bool getValue(T& value) const
78  {
79  if( ! _si )
80  return false;
81 
82  *_si >>= value;
83  return true;
84  }
85 
88  template <typename T>
89  void setValue(const T& value)
90  {
91  if( _si )
92  {
93  _si->setVoid();
94  *_si <<= value;
95  }
96  }
97 
100  bool isNull() const
101  {
102  return _si ? _si->isVoid() : true;
103  }
104 
107  void setNull()
108  {
109  if( _si )
110  {
111  _si->setVoid();
112 
113  }
114  }
115 
118  Element parent() const
119  {
120  if( ! _si )
121  return Element();
122 
123  return Element( _si->parent() );
124  }
125 
128  Element begin() const
129  {
130  if( ! _si )
131  return this->end();
132 
134  if( it == _si->end() )
135  return this->end();
136 
137  SerializationInfo& si = *it;
138  return Element(&si);
139  }
140 
143  Element end() const
144  {
145  return Element();
146  }
147 
150  Element getMember(const std::string& name) const
151  {
152  if( ! _si )
153  return this->end();
154 
155  SerializationInfo* si = _si->findMember(name);
156  return Element(si);
157  }
158 
161  Element getMember(const char* name) const
162  {
163  if( ! _si )
164  return this->end();
165 
166  SerializationInfo* si = _si->findMember(name);
167  return Element(si);
168  }
169 
172  Element operator[] (const std::string& name) const
173  {
174  return this->getMember(name);
175  }
176 
179  Element operator[] (const char* name) const
180  {
181  return this->getMember(name);
182  }
183 
186  Element addMember(const char* name)
187  {
188  if( ! _si )
189  return Element();
190 
191  SerializationInfo* si = _si->findMember(name);
192  if( ! si )
193  si = &_si->addMember(name);
194 
195  return Element(si);
196  }
197 
200  Element addMember(const std::string& name)
201  {
202  if( ! _si )
203  return Element();
204 
205  SerializationInfo* si = _si->findMember(name);
206  if( ! si )
207  si = &_si->addMember(name);
208 
209  return Element(si);
210  }
211 
215  {
216  if( ! _si )
217  return Element();
218 
219  SerializationInfo& si = _si->addElement();
220  return Element(&si);
221  }
222 
225  void removeMember(const std::string& name)
226  {
227  if( _si )
228  _si->removeMember(name);
229  }
230 
233  void removeMember(const char* name)
234  {
235  if( _si )
236  _si->removeMember(name);
237  }
238 
241  void removeElement(const Element& e)
242  {
243  if( ! _si || ! e._si )
244  return;
245 
246  _si->removeMember( *e._si );
247  }
248 
252  { return *this; }
253 
257  { return this; }
258 
262  {
263  _si = _si->sibling();
264  return *this;
265  }
266 
269  bool operator!=(const Element& other) const
270  { return _si != other._si; }
271 
274  bool operator==(const Element& other) const
275  { return _si == other._si; }
276 
279  bool operator!() const
280  { return _si == 0; }
281 
282  private:
283  SerializationInfo* _si;
284  };
285 
289  {
290  public:
291  explicit ConstElement(const SerializationInfo* si = 0)
292  : _si(si)
293  {}
294 
297  const char* name() const
298  { return _si->name(); }
299 
302  template <typename T>
303  bool getValue(T& value) const
304  {
305  if( ! _si )
306  return false;
307 
308  *_si >>= value;
309  return true;
310  }
311 
314  bool isNull() const
315  {
316  return _si ? _si->isVoid() : true;
317  }
318 
322  {
323  if( ! _si )
324  return this->end();
325 
327  if(it == _si->end())
328  return this->end();
329 
330  const SerializationInfo& si = *it;
331  return ConstElement(&si);
332  }
333 
337  {
338  return ConstElement();
339  }
340 
343  ConstElement getMember(const std::string& name) const
344  {
345  if( ! _si )
346  return end();
347 
348  const SerializationInfo* si = _si->findMember(name);
349  return ConstElement(si);
350  }
351 
354  ConstElement getMember(const char* name) const
355  {
356  if( ! _si )
357  return end();
358 
359  const SerializationInfo* si = _si->findMember(name);
360  return ConstElement(si);
361  }
362 
365  ConstElement operator[] (const std::string& name) const
366  {
367  return this->getMember(name);
368  }
369 
372  ConstElement operator[] (const char* name) const
373  {
374  return this->getMember(name);
375  }
376 
379  const ConstElement& operator*() const
380  { return *this; }
381 
384  const ConstElement* operator->() const
385  { return this; }
386 
390  {
391  _si = _si->sibling();
392  return *this;
393  }
394 
397  bool operator!=(const ConstElement& other) const
398  { return _si != other._si; }
399 
402  bool operator==(const ConstElement& other) const
403  { return _si == other._si; }
404 
407  bool operator!() const
408  { return _si == 0; }
409 
410  private:
411  const SerializationInfo* _si;
412  };
413 
414  public:
417  Document();
418 
421  void clear();
422 
425  bool isEmpty() const;
426 
429  void load( std::basic_istream<Pt::Char>& is );
430 
433  void save( std::basic_ostream<Pt::Char>& os ) const;
434 
438  { return Element(&_root); }
439 
443  { return ConstElement(&_root); }
444 
448  { return root().begin(); }
449 
453  { return root().begin(); }
454 
458  { return root().end(); }
459 
463  { return root().end(); }
464 
467  Element getMember(const std::string& name)
468  {
469  return root().getMember(name);
470  }
471 
474  ConstElement getMember(const std::string& name) const
475  {
476  return root().getMember(name);
477  }
478 
481  Element getMember(const char* name)
482  {
483  return root().getMember(name);
484  }
485 
488  ConstElement getMember(const char* name) const
489  {
490  return root().getMember(name);
491  }
492 
495  Element operator[] (const std::string& name)
496  {
497  return root().getMember(name);
498  }
499 
502  ConstElement operator[] (const std::string& name) const
503  {
504  return root().getMember(name);
505  }
506 
509  Element operator[] (const char* name)
510  {
511  return root().getMember(name);
512  }
513 
516  ConstElement operator[] (const char* name) const
517  {
518  return root().getMember(name);
519  }
520 
523  Element addMember(const char* name)
524  {
525  return root().addMember(name);
526  }
527 
530  Element addMember(const std::string& name)
531  {
532  return root().addMember(name);
533  }
534 
538  {
539  return root().addElement();
540  }
541 
544  void removeMember(const char* name)
545  {
546  root().removeMember(name);
547  }
548 
551  void removeMember(const std::string& name)
552  {
553  root().removeMember(name);
554  }
555 
558  void removeElement(const Element& e)
559  {
560  root().removeElement(e);
561  }
562 
563  private:
564  SerializationInfo _root;
565 };
566 
567 } // namespace
568 
569 } // namespace
570 
571 #endif
Element addMember(const char *name)
Adds a top level element.
Definition: Document.h:523
Element addElement()
Adds a top level element.
Definition: Document.h:537
const SerializationInfo * findMember(const std::string &name) const
Find a struct member.
Definition: SerializationInfo.h:508
Const forward iterator for child elements.
Definition: SerializationInfo.h:782
JSON Document reader.
Definition: DocumentReader.h:45
Element & operator*()
Allows using the element like an iterator.
Definition: Document.h:251
ConstElement begin() const
Begin of sub elements.
Definition: Document.h:321
Element addMember(const std::string &name)
Adds a top level element.
Definition: Document.h:530
void setNull()
Sets element to null.
Definition: Document.h:107
bool operator==(const ConstElement &other) const
Allows using the element like an iterator.
Definition: Document.h:402
Element getMember(const std::string &name)
Returns a top level element.
Definition: Document.h:467
Iterator end()
Returns an iterator to the end of child elements.
Definition: SerializationInfo.h:826
SerializationInfo & addElement()
Add a sequence element.
void removeMember(const std::string &name)
Removes a top level element.
Definition: Document.h:551
SerializationInfo & addMember(const std::string &name)
Add a struct member.
Definition: SerializationInfo.h:449
Element * operator->()
Allows using the element like an iterator.
Definition: Document.h:256
Element parent() const
Returns the parent element.
Definition: Document.h:118
ConstElement end() const
End of elements.
Definition: Document.h:462
void removeMember(const char *name)
Removes a sub element.
Definition: Document.h:233
bool operator==(const Element &other) const
Allows using the element like an iterator.
Definition: Document.h:274
bool operator!=(const ConstElement &other) const
Allows using the element like an iterator.
Definition: Document.h:397
ConstElement getMember(const std::string &name) const
Returns a sub element.
Definition: Document.h:343
Constant document element.
Definition: Document.h:288
const ConstElement * operator->() const
Allows using the element like an iterator.
Definition: Document.h:384
Element end() const
End of sub elements.
Definition: Document.h:143
ConstElement & operator++()
Allows using the element like an iterator.
Definition: Document.h:389
Element & operator++()
Allows using the element like an iterator.
Definition: Document.h:261
void removeMember(const char *name)
Removes a top level element.
Definition: Document.h:544
const char * name() const
Returns the element name.
Definition: Document.h:71
ConstElement root() const
Returns the root element.
Definition: Document.h:442
bool operator!() const
Returns true if element is invalid.
Definition: Document.h:279
void removeElement(const Element &e)
Removes a sub element.
Definition: Document.h:241
ConstElement end() const
End of sub elements.
Definition: Document.h:336
ConstElement getMember(const char *name) const
Returns a sub element.
Definition: Document.h:354
ConstElement getMember(const char *name) const
Returns a top level element.
Definition: Document.h:488
const char * name() const
Returns the element name.
Definition: Document.h:297
void setValue(const T &value)
Sets the value.
Definition: Document.h:89
bool operator!() const
Returns true if element is invalid.
Definition: Document.h:407
Element getMember(const std::string &name) const
Returns a sub element.
Definition: Document.h:150
void removeElement(const Element &e)
Removes a top level element.
Definition: Document.h:558
bool isNull() const
Returns true if element is null.
Definition: Document.h:100
void removeMember(const std::string &name)
Removes a sub element.
Definition: Document.h:225
ConstElement begin() const
Begin of elements.
Definition: Document.h:452
Modifiable document element.
Definition: Document.h:52
bool getValue(T &value) const
Gets the value.
Definition: Document.h:77
Represents arbitrary types during serialization.
Definition: SerializationInfo.h:58
Iterator begin()
Returns an iterator to the begin of child elements.
Element root()
Returns the root element.
Definition: Document.h:437
bool getValue(T &value) const
Gets the value.
Definition: Document.h:303
Element addElement()
Adds a sub element.
Definition: Document.h:214
bool operator!=(const Element &other) const
Allows using the element like an iterator.
Definition: Document.h:269
JSON Document.
Definition: Document.h:45
Forward Iterator for child elements.
Definition: SerializationInfo.h:737
Element addMember(const char *name)
Adds a sub element.
Definition: Document.h:186
bool isNull() const
Returns true if element is null.
Definition: Document.h:314
Element getMember(const char *name)
Returns a top level element.
Definition: Document.h:481
const ConstElement & operator*() const
Allows using the element like an iterator.
Definition: Document.h:379
Element end()
End of elements.
Definition: Document.h:457
Element getMember(const char *name) const
Returns a sub element.
Definition: Document.h:161
ConstElement getMember(const std::string &name) const
Returns a top level element.
Definition: Document.h:474
Element addMember(const std::string &name)
Adds a sub element.
Definition: Document.h:200
Element begin()
Begin of elements.
Definition: Document.h:447
Element begin() const
Begin of sub elements.
Definition: Document.h:128