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