casacore
JsonOut.h
Go to the documentation of this file.
1 //# JsonOut.h: Fill a file or stream in JSON format
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$
27 
28 #ifndef CASA_JSONOUT_H
29 #define CASA_JSONOUT_H
30 
31 //# Includes
32 #include <casacore/casa/aips.h>
33 #include <casacore/casa/BasicSL/String.h>
34 #include <casacore/casa/Arrays/Array.h>
35 #include <casacore/casa/BasicSL/Complex.h>
36 #include <casacore/casa/vector.h>
37 #include <iostream>
38 #include <fstream>
39 
40 namespace casacore { //# NAMESPACE CASACORE - BEGIN
41 
42  //# Forward Declarations
43  class Record;
44  class ValueHolder;
45 
46 
47  // <summary>
48  // Class to fill a file or stream in JSON format.
49  // </summary>
50 
51  // <use visibility=export>
52  // <reviewed reviewer="" date="" tests="tJsonOut">
53  // </reviewed>
54 
55  //# <prerequisite>
56  //# </prerequisite>
57 
58  // <synopsis>
59  // JsonOut is a class to create a JSON file. JsonParser.h can be used
60  // to interpret a JSON file whereafter JsonKVMap gets out the information.
61  //
62  // Besides the standard JSON types (bool, int, float, string), sequences
63  // and nested structs, JsonOut also supports Casacore data type (D)Complex,
64  // Array, Record, and ValueHolder.
65  // <br>- A complex number is written as a nested struct with fields
66  // "r" and "i".
67  // <br>- An Array is written as a (possibly nested) sequence of values.
68  // <br>- A Record is written as a nested struct; subrecords are supported.
69  // <br>- A ValueHolder is written depending on the data type it contains.
70  // <br>Note that floating point values are written with high accuracy
71  // (7 digits for single precision, 16 digits for double precision).
72  //
73  // Although standard JSON does not support comments, many parsers do support
74  // C-style and C++-style comments. JsonOut has the possibility to define
75  // arbitrary comment delimiters (e.g., / * and * / for C-style).
76  // If no start delimiter is given, possible comments are ignored.
77  //
78  // The output of JsonOut can be any iostream. If a file name is given, an
79  // ofstream will be opened in the constructor and closed in the destructor.
80  // The output is formatted pretty nicely. Nested structs are indented with
81  // 2 spaces. Arrays are written with a single axis per line; continuation
82  // lines are indented properly. String arrays have one value per line.
83  // </synopsis>
84 
85  // <example>
86  // The following example is read back by the example in class JsonParser.
87  // <srcblock>
88  // // Create the JSON file.
89  // JsonOut jout(fullName + "/imageconcat.json");
90  // // Start the JSON struct; possible comments will be ignored.
91  // jout.start();
92  // // Write some fields (one line per field).
93  // jout.write ("Version", 1);
94  // jout.write ("DataType", "float");
95  // jout.write ("Axis", latticeConcat_p.axis());
96  // jout.write ("Images", Array<String>(latticeNames));
97  // // End the JSON struct.
98  // jout.end();
99  // </srcblock>
100  // See tJsonOut.cc for more elaborate examples.
101  // </example>
102 
103  // <motivation>
104  // JSON is a commonly used interchange format.
105  // </motivation>
106  //
107  //# <todo asof="1996/03/10">
108  //# <li>
109  //# </todo>
110 
111  class JsonOut
112  {
113  public:
114  // The default constructor creates the output on stdout.
116 
117  // Create the file with the given name using an ofstream object.
118  JsonOut (const String& name);
119 
120  // Create the object using the given ostream object.
121  JsonOut (ostream& os);
122 
123  // Close the stream. It closes the ofstream object if created.
125 
126  // Start a JSON structure by writing a { and setting the indentation.
127  // It checks if not inside a JSON structure.
128  // It is possible to define the comment delimiters
129  // (e.g., / * and * / or // and empty).
130  // If commentStart is empty, possible comments are ignored.
131  void start (const String& commentStart=String(),
132  const String& commentEnd=String(),
133  const String& indent=" ");
134 
135  // End a structure by clearing the indentation and writing a }.
136  // It checks if inside a JSON structure.
137  void end();
138 
139  // Start a nested structure; i.e., a field with a structured value.
140  // It writes the name and opening brace and increments the indentation.
141  // If supported, the comment is written on a line preceeding the key line.
142  void startNested (const String& name, const String& comment=String());
143 
144  // End a nested structure.
145  // It decrements the indentation and writes the closing brace.
146  void endNested();
147 
148  // Write one or more lines defining a keyword-value pair, where value
149  // can be of any type including Array, Record, and ValueHolder.
150  // A non-finite floating point number and a null ValueHolder are
151  // written as a null value.
152  // If supported, the comment is written on a line preceeding the
153  // 'key:value' line.
154  template <typename T>
155  void write (const String& name, T value, const String& comment=String());
156 
157  // Write a comment on a separate line.
158  // If comments are not supported, an empty line is written.
159  void writeComment (const String& comment);
160 
161  // Write a null value.
162  void putNull();
163 
164  // Put a scalar value with sufficient accuracy.
165  // A Complex value is written as a nested JSON structure
166  // with fields r and i.
167  // A string is enclosed in quotes and escaped where necessary.
168  // A NaN is written as a null value.
169  // <br>These functions are meant for internal use by the 'write' function.
170  // <group>
171  template <typename T> void put (T value);
172  void put (Bool value);
173  void put (Float value);
174  void put (Double value);
175  void put (const Complex& value);
176  void put (const DComplex& value);
177  void put (const char* value);
178  void put (const String& value);
179  // </group>
180 
181  // Put a line defining an array value. Multi-dim arrays are written as
182  // nested [] lines.
183  // Normally the values of the first dimension are written on a single line,
184  // but for string values a line per value is used.
185  // <br>These functions are meant for internal use by the 'write' function.
186  template <typename T>
187  void putArray (const Array<T>& value, const String& indent,
188  Bool firstLine);
189  void putArray (const Array<String>& value, const String& indent,
190  Bool firstLine);
191  template <typename T>
192  void putArray (const Array<T>& value, const String& indent,
193  Bool firstLine, Bool valueEndl);
194 
195  // Escape special characters (including control characters) in a string.
196  static String escapeString (const String& in);
197 
198  private:
199  // Copy constructor cannot be used.
200  JsonOut (const JsonOut& other);
201 
202  // Assignment cannot be used.
203  JsonOut& operator= (const JsonOut& other);
204 
205  // Write the name.
206  void putName (const String& name);
207 
208  // General function to write a key and value.
209  // Specializations exist for particular data types.
210  template <typename T>
211  void writeKV (const String& name, T value);
212 
213  // Write a key and array value.
214  template <typename T>
215  void writeKV (const String& name, const Array<T>& value);
216 
217  // Write a key and valueholder.
218  void writeKV (const String& name, const ValueHolder& vh);
219 
220  // Put a Record which is written as a {} structure.
221  // The Record can be nested.
222  void put (const Record&);
223 
224  // Get the indentation after a name.
225  // It indents with the length of the name (including quotes and colon)
226  // with a maximum of 20 spaces.
227  String indentValue (const String& indent, const String& name) const;
228 
229  //# Data fields.
230  std::ofstream itsFile;
231  std::ostream& itsStream;
234  int itsLevel;
237  vector<Bool> itsFirstName;
238  };
239 
240 
241 } //# NAMESPACE CASACORE - END
242 
243 #ifndef CASACORE_NO_AUTO_TEMPLATES
244 #include <casacore/casa/Json/JsonOut.tcc>
245 #endif //# CASACORE_NO_AUTO_TEMPLATES
246 #endif
void put(const String &value)
JsonOut(ostream &os)
Create the object using the given ostream object.
String itsCommentEnd
Definition: JsonOut.h:236
void writeKV(const String &name, const Array< T > &value)
Write a key and array value.
JsonOut(const String &name)
Create the file with the given name using an ofstream object.
void writeKV(const String &name, T value)
General function to write a key and value.
void writeKV(const String &name, const ValueHolder &vh)
Write a key and valueholder.
JsonOut & operator=(const JsonOut &other)
Assignment cannot be used.
void writeComment(const String &comment)
Write a comment on a separate line.
std::ofstream itsFile
Definition: JsonOut.h:230
~JsonOut()
Close the stream.
void put(const char *value)
void startNested(const String &name, const String &comment=String())
Start a nested structure; i.e., a field with a structured value.
void putArray(const Array< T > &value, const String &indent, Bool firstLine, Bool valueEndl)
void start(const String &commentStart=String(), const String &commentEnd=String(), const String &indent=" ")
Start a JSON structure by writing a { and setting the indentation.
void putName(const String &name)
Write the name.
void put(const Complex &value)
void put(const Record &)
Put a Record which is written as a {} structure.
void write(const String &name, T value, const String &comment=String())
Write one or more lines defining a keyword-value pair, where value can be of any type including Array...
void put(Float value)
JsonOut()
The default constructor creates the output on stdout.
void put(const DComplex &value)
JsonOut(const JsonOut &other)
Copy constructor cannot be used.
void put(Bool value)
vector< Bool > itsFirstName
Definition: JsonOut.h:237
String itsIndent
Definition: JsonOut.h:232
void putNull()
Write a null value.
void putArray(const Array< String > &value, const String &indent, Bool firstLine)
void put(Double value)
void putArray(const Array< T > &value, const String &indent, Bool firstLine)
Put a line defining an array value.
std::ostream & itsStream
Definition: JsonOut.h:231
static String escapeString(const String &in)
Escape special characters (including control characters) in a string.
String indentValue(const String &indent, const String &name) const
Get the indentation after a name.
void put(T value)
Put a scalar value with sufficient accuracy.
String itsCommentStart
Definition: JsonOut.h:235
String itsIndentStep
Definition: JsonOut.h:233
void end()
End a structure by clearing the indentation and writing a }.
void endNested()
End a nested structure.
String: the storage and methods of handling collections of characters.
Definition: String.h:225
this file contains all the compiler specific defines
Definition: mainpage.dox:28
float Float
Definition: aipstype.h:54
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
double Double
Definition: aipstype.h:55