casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JsonValue.h
Go to the documentation of this file.
1 //# JsonValue.h: Class to hold any JSON value
2 //# Copyright (C) 2016
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id: JsonValue.h 14057 2009-09-18 12:26:29Z diepen $
27 
28 #ifndef CASA_JSONVALUE_H
29 #define CASA_JSONVALUE_H
30 
31 //# Includes
38 #include <vector>
39 #include <iosfwd>
40 
41 namespace casacore {
42 
43  //# Forward Declarations
44  class JsonKVMap;
45  class ValueHolder;
46  class IPosition;
47 
48 
49  // <summary>
50  // Class to hold any JSON value
51  // </summary>
52 
53  // <use visibility=export>
54  // <reviewed reviewer="" date="" tests="tJsonValue">
55  // </reviewed>
56 
57  //# <prerequisite>
58  //# </prerequisite>
59 
60  // <synopsis>
61  // Class JsonValue can hold an arbitrary JSON value which can be a scalar,
62  // a JsonKVMap object, or a vector of JsonValue objects. In this way
63  // JSON values can be nested in any way.
64  //
65  // Internally scalar values are kept as Bool, Int64, Double, DComplex or
66  // String values. The functions to obtain the value convert if possible.
67  // Note that conversion from Int64 to Bool is supported.
68  // The value can also be obtained as a ValueHolder object making it easier
69  // to use in other Casacore code.
70  // Null is also a valid JsonValue. A null value can be obtained as a
71  // floating point value resulting in a NaN. It can also be obtained as a
72  // null ValueHolder. Getting it for other types results in an exception.
73  //
74  // It is possible to obtain the value as a multi-dimensional Array object
75  // if the values are regular, thus if nested vectors have the same sizes.
76  // The data type of an Array is the 'highest' data type of a value in it.
77  //
78  // Normally a JsonValue object is created by JsonParser and is the
79  // interface to obtain a value of a field in a parsed JSON file.
80  // However, users can create JsonValue objects as well.
81  // </synopsis>
82 
83  // <motivation>
84  // JSON is a commonly used interchange format.
85  // </motivation>
86 
87  //# <todo asof="1996/03/10">
88  //# <li>
89  //# </todo>
90 
91  class JsonValue
92  {
93  public:
94  // The default constructor results in a null value.
95  JsonValue();
96 
97  // Construct value with given type.
98  // <group>
99  JsonValue (Bool);
100  JsonValue (int);
101  JsonValue (Int64);
102  JsonValue (double);
103  JsonValue (const DComplex&);
104  JsonValue (const char*);
105  JsonValue (const String&);
106  JsonValue (const std::vector<JsonValue>&);
107  JsonValue (const JsonKVMap&);
108  // </group>
109 
110  // Copy constructor (copy semantics).
111  JsonValue (const JsonValue&);
112 
113  // Assignment (copy semantics).
114  JsonValue& operator= (const JsonValue&);
115 
116  ~JsonValue();
117 
118  // Is the value a null value?
119  Bool isNull() const
120  { return itsValuePtr == 0; }
121 
122  // Is the value a vector?
123  Bool isVector() const
124  { return itsDataType == TpOther; }
125 
126  // Is the value a value map?
127  Bool isValueMap() const
128  { return itsDataType == TpRecord; }
129 
130  // Return the size of a value vector or map (1 is returned for a scalar).
131  size_t size() const;
132 
133  // Get the data type of the value.
134  // A ValueMap is returned as TpRecord, a vector as TpOther.
135  DataType dataType() const
136  { return itsDataType; }
137 
138  // Get the most common data type of the value inside a possibly
139  // nested vector.
140  // <br>- If the value is a single value, that type is returned.
141  // <br>- If any vector value is a ValueMap, TpRecord is returned.
142  // <br>- If any vector contains non-matching data types, TpOther is
143  // returned.
144  // <br>- Otherwise the 'highest' data type is returned.
145  // <group>
146  DataType arrayDataType() const;
147  DataType vectorDataType (const std::vector<JsonValue>& vec) const;
148  // </group>
149 
150  // Get the shape of an array (possibly nested vector).
151  // An exception is thrown if a vector contains a ValueMap or if
152  // the array shape is irregular (nested vectors have different sizes).
153  IPosition shape() const;
154  IPosition vectorShape (const std::vector<JsonValue>& vec) const;
155 
156  // Get the value as a ValueHolder.
157  // A null value results in a null (empty) ValueHolder.
158  // An exception is thrown if the value cannot be represented as such,
159  // because it is a vector of differently typed values or nested vectors.
160  ValueHolder getValueHolder() const;
161 
162  // Get the value in the given data type.
163  // Numeric data type promotion can be done as well as conversion of
164  // integer to bool (0=False, other=True). An exception is thrown if
165  // a mismatching data type is used.
166  // Note that a null value can only be obtained as double (giving NaN).
167  // <group>
168  Bool getBool() const;
169  Int64 getInt() const;
170  double getDouble() const;
171  DComplex getDComplex() const;
172  const String& getString() const;
173  // </group>
174 
175  // As above, but get the value as a vector.
176  // If the value is a scalar, a vector with length 1 is returned.
177  // <group>
178  std::vector<Bool> getVecBool() const;
179  std::vector<Int64> getVecInt() const;
180  std::vector<double> getVecDouble() const;
181  std::vector<DComplex> getVecDComplex() const;
182  std::vector<String> getVecString() const;
183  const std::vector<JsonValue>& getVector() const;
184  // </group>
185 
186  // Get the value as a JsonKVMap (no conversion is possible).
187  const JsonKVMap& getValueMap() const;
188 
189  // Get the value as an Array. The value must be a scalar or a
190  // regularly nested vector.
191  // <group>
192  Array<Bool> getArrayBool() const;
193  Array<Int64> getArrayInt() const;
197  // </group>
198 
199  // Get functions for templated purposes
200  // <group>
201  void get (Bool& value) const
202  { value = getBool(); }
203  void get (Int64& value) const
204  { value = getInt(); }
205  void get (double& value) const
206  { value = getDouble(); }
207  void get (DComplex& value) const
208  { value = getDComplex(); }
209  void get (String& value) const
210  { value = getString(); }
211  void get (std::vector<Bool>& value) const
212  { value = getVecBool(); }
213  void get (std::vector<Int64>& value) const
214  { value = getVecInt(); }
215  void get (std::vector<double>& value) const
216  { value = getVecDouble(); }
217  void get (std::vector<DComplex>& value) const
218  { value = getVecDComplex(); }
219  void get (std::vector<String>& value) const
220  { value = getVecString(); }
221  void get (std::vector<JsonValue>& value) const
222  { value = getVector(); }
223  void get (JsonKVMap& value) const;
224  // </group>
225 
226  // Show value on given ostream.
227  friend ostream& operator<< (ostream&, const JsonValue&);
228 
229  private:
230  // Remove the value.
231  void clear();
232 
233  // Copy the value from another one.
234  void copyValue (const JsonValue& that);
235 
236  // Fill an array from nested vector in a recursive way.
237  template<typename T>
238  T* fillArray (T* data, const T* dataEnd,
239  const std::vector<JsonValue>& vec) const
240  {
241  for (std::vector<JsonValue>::const_iterator iter=vec.begin();
242  iter!=vec.end(); ++iter) {
243  if (iter->dataType() == TpOther) {
244  data = fillArray (data, dataEnd, iter->getVector());
245  } else {
246  AlwaysAssert (data<dataEnd, AipsError);
247  iter->get (*data);
248  data++;
249  }
250  }
251  return data;
252  }
253 
254  DataType itsDataType;
255  void* itsValuePtr;
256  };
257 
258 
259 } // end namespace
260 
261 #endif
A Vector of integers, for indexing into Array&lt;T&gt; objects.
Definition: IPosition.h:118
Array< double > getArrayDouble() const
long long Int64
Define the extra non-standard types used by Casacore (like proposed uSize, Size)
Definition: aipsxtype.h:38
DataType arrayDataType() const
Get the most common data type of the value inside a possibly nested vector.
double getDouble() const
IPosition shape() const
Get the shape of an array (possibly nested vector).
DataType dataType() const
Get the data type of the value.
Definition: JsonValue.h:135
std::vector< double > getVecDouble() const
Int64 getInt() const
void clear()
Remove the value.
T * fillArray(T *data, const T *dataEnd, const std::vector< JsonValue > &vec) const
Fill an array from nested vector in a recursive way.
Definition: JsonValue.h:238
DComplex getDComplex() const
DataType vectorDataType(const std::vector< JsonValue > &vec) const
IPosition vectorShape(const std::vector< JsonValue > &vec) const
Bool isVector() const
Is the value a vector?
Definition: JsonValue.h:123
Array< Int64 > getArrayInt() const
JsonValue & operator=(const JsonValue &)
Assignment (copy semantics).
const JsonKVMap & getValueMap() const
Get the value as a JsonKVMap (no conversion is possible).
const std::vector< JsonValue > & getVector() const
Class to hold a collection of JSON key:value pairs.
Definition: JsonKVMap.h:72
A holder for a value of any basic Casacore data type.
Definition: ValueHolder.h:68
void copyValue(const JsonValue &that)
Copy the value from another one.
Bool isNull() const
Is the value a null value?
Definition: JsonValue.h:119
Array< String > getArrayString() const
DataType itsDataType
Definition: JsonValue.h:254
Bool getBool() const
Get the value in the given data type.
std::vector< Int64 > getVecInt() const
#define AlwaysAssert(expr, exception)
These marcos are provided for use instead of simply using the constructors of assert_ to allow additi...
Definition: Assert.h:157
std::vector< DComplex > getVecDComplex() const
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
Class to hold any JSON value.
Definition: JsonValue.h:91
size_t size() const
Return the size of a value vector or map (1 is returned for a scalar).
std::vector< String > getVecString() const
const String & getString() const
Bool isValueMap() const
Is the value a value map?
Definition: JsonValue.h:127
Array< DComplex > getArrayDComplex() const
Base class for all Casacore library errors.
Definition: Error.h:134
String: the storage and methods of handling collections of characters.
Definition: String.h:225
std::vector< Bool > getVecBool() const
As above, but get the value as a vector.
Array< Bool > getArrayBool() const
Get the value as an Array.
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
friend ostream & operator<<(ostream &, const JsonValue &)
Show value on given ostream.
ValueHolder getValueHolder() const
Get the value as a ValueHolder.
JsonValue()
The default constructor results in a null value.