0031363: Documentation - broken Doxygen documentation of header files in Standard...
[occt.git] / src / Standard / Standard_Dump.hxx
CommitLineData
0904aa63 1// Copyright (c) 2019 OPEN CASCADE SAS
2//
3// This file is part of Open CASCADE Technology software library.
4//
5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
10//
11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
13
14#ifndef _Standard_Dump_HeaderFile
15#define _Standard_Dump_HeaderFile
16
bc73b006 17#include <NCollection_IndexedDataMap.hxx>
18#include <NCollection_List.hxx>
0904aa63 19#include <Standard_SStream.hxx>
20#include <TCollection_AsciiString.hxx>
21
64e68ea6 22//!@file
0904aa63 23//! The file contains interface to prepare dump output for OCCT objects. Format of the dump is JSON.
64e68ea6 24//!
3de0f784 25//! To prepare this output, implement method DumpJson in the object and use macro functions from this file.
0904aa63 26//! Macros have one parameter for both, key and the value. It is a field of the current class. Macro has internal analyzer that
27//! uses the variable name to generate key. If the parameter has prefix symbols "&", "*" and "my", it is cut.
28//!
3de0f784 29//! - OCCT_DUMP_FIELD_VALUE_NUMERICAL. Use it for fields of numerical C++ types, like int, float, double. It creates a pair "key", "value",
30//! - OCCT_DUMP_FIELD_VALUE_STRING. Use it for char* type. It creates a pair "key", "value",
31//! - OCCT_DUMP_FIELD_VALUE_POINTER. Use it for pointer fields. It creates a pair "key", "value", where the value is the pointer address,
32//! - OCCT_DUMP_FIELD_VALUES_DUMPED. Use it for fields that has own Dump implementation. It expects the pointer to the class instance.
0904aa63 33//! It creates "key": { result of dump of the field }
3de0f784 34//! - OCCT_DUMP_FIELD_VALUES_NUMERICAL. Use it for unlimited list of fields of C++ double type.
0904aa63 35//! It creates massive of values [value_1, value_2, ...]
3de0f784 36//! - OCCT_DUMP_FIELD_VALUES_STRING. Use it for unlimited list of fields of TCollection_AsciiString types.
0904aa63 37//! It creates massive of values ["value_1", "value_2", ...]
3de0f784 38//! - OCCT_DUMP_BASE_CLASS. Use if Dump implementation of the class is virtual, to perform ClassName::Dump() of the parent class,
0904aa63 39//! expected parameter is the parent class name.
40//! It creates "key": { result of dump of the field }
3de0f784 41//! - OCCT_DUMP_VECTOR_CLASS. Use it as a single row in some object dump to have one row in output.
42//! It's possible to use it without necessity of OCCT_DUMP_CLASS_BEGIN call.
0904aa63 43//! It creates massive of values [value_1, value_2, ...]
44//!
45//! The Dump result prepared by these macros is an output stream, it is not arranged with spaces and line feed.
46//! To have output in a more readable way, use ConvertToAlignedString method for obtained stream.
47
48//! Converts the class type into a string value
3de0f784 49#define OCCT_CLASS_NAME(theClass) #theClass
0904aa63 50
3de0f784 51//! @def OCCT_DUMP_CLASS_BEGIN
0904aa63 52//! Creates an instance of Sentry to cover the current Dump implementation with keys of start and end.
53//! This row should be inserted before other macros. The end key will be added by the sentry remove,
54//! (exit of the method).
bc73b006 55#define OCCT_DUMP_CLASS_BEGIN(theOStream, theField) \
56{ \
57 const char* className = OCCT_CLASS_NAME(theField); \
58 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, className) \
59}
60
61//! @def OCCT_DUMP_TRANSIENT_CLASS_BEGIN
62//! Creates an instance of Sentry to cover the current Dump implementation with keys of start and end.
63//! This row should be inserted before other macros. The end key will be added by the sentry remove,
64//! (exit of the method).
65#define OCCT_DUMP_TRANSIENT_CLASS_BEGIN(theOStream) \
66{ \
67 const char* className = get_type_name(); \
68 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, className) \
69}
0904aa63 70
3de0f784 71//! @def OCCT_DUMP_FIELD_VALUE_NUMERICAL
0904aa63 72//! Append into output value: "Name": Field
3de0f784 73#define OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, theField) \
0904aa63 74{ \
bc73b006 75 TCollection_AsciiString aName = Standard_Dump::DumpFieldToName (#theField); \
3de0f784 76 Standard_Dump::AddValuesSeparator (theOStream); \
0904aa63 77 theOStream << "\"" << aName << "\": " << theField; \
78}
79
3de0f784 80//! @def OCCT_DUMP_FIELD_VALUE_STRING
0904aa63 81//! Append into output value: "Name": "Field"
3de0f784 82#define OCCT_DUMP_FIELD_VALUE_STRING(theOStream, theField) \
0904aa63 83{ \
bc73b006 84 TCollection_AsciiString aName = Standard_Dump::DumpFieldToName (#theField); \
3de0f784 85 Standard_Dump::AddValuesSeparator (theOStream); \
0904aa63 86 theOStream << "\"" << aName << "\": \"" << theField << "\""; \
87}
88
3de0f784 89//! @def OCCT_DUMP_FIELD_VALUE_POINTER
0904aa63 90//! Append into output value: "Name": "address of the pointer"
3de0f784 91#define OCCT_DUMP_FIELD_VALUE_POINTER(theOStream, theField) \
0904aa63 92{ \
bc73b006 93 TCollection_AsciiString aName = Standard_Dump::DumpFieldToName (#theField); \
3de0f784 94 Standard_Dump::AddValuesSeparator (theOStream); \
0904aa63 95 theOStream << "\"" << aName << "\": \"" << Standard_Dump::GetPointerInfo (theField) << "\""; \
96}
97
bc73b006 98//! @def OCCT_DUMP_FIELD_VALUE_STRING
99//! Append into output value: "Name": "Field"
100#define OCCT_DUMP_FIELD_VALUE_GUID(theOStream, theField) \
101{ \
102 TCollection_AsciiString aName = Standard_Dump::DumpFieldToName (#theField); \
103 Standard_Dump::AddValuesSeparator (theOStream); \
104 char aStr[Standard_GUID_SIZE_ALLOC]; \
105 theField.ToCString (aStr); \
106 theOStream << "\"" << aName << "\": \"" << aStr << "\""; \
107}
108
3de0f784 109//! @def OCCT_DUMP_FIELD_VALUES_DUMPED
0904aa63 110//! Append into output value: "Name": { field dumped values }
111//! It computes Dump of the fields. The expected field is a pointer.
112//! Use this macro for fields of the dumped class which has own Dump implementation.
113//! The macros is recursive. Recursion is stopped when the depth value becomes equal to zero.
114//! Depth = -1 is the default value, dump here is unlimited.
3de0f784 115#define OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, theField) \
0904aa63 116{ \
bc73b006 117 if (theDepth != 0 && (void*)(theField) != NULL) \
0904aa63 118 { \
119 Standard_SStream aFieldStream; \
bc73b006 120 (theField)->DumpJson (aFieldStream, theDepth - 1); \
121 TCollection_AsciiString aName = Standard_Dump::DumpFieldToName (#theField); \
0904aa63 122 Standard_Dump::DumpKeyToClass (theOStream, aName, Standard_Dump::Text (aFieldStream)); \
123 } \
124}
125
3de0f784 126//! @def OCCT_DUMP_FIELD_VALUES_NUMERICAL
0904aa63 127//! Append real values into output values in an order: [value_1, value_2, ...]
128//! It computes Dump of the parent. The expected field is a parent class name to call ClassName::Dump.
3de0f784 129#define OCCT_DUMP_FIELD_VALUES_NUMERICAL(theOStream, theName, theCount, ...) \
0904aa63 130{ \
3de0f784 131 Standard_Dump::AddValuesSeparator (theOStream); \
0904aa63 132 theOStream << "\"" << theName << "\": ["; \
133 Standard_Dump::DumpRealValues (theOStream, theCount, __VA_ARGS__);\
134 theOStream << "]"; \
135}
136
3de0f784 137//! @def OCCT_DUMP_FIELD_VALUES_STRING
0904aa63 138//! Append real values into output values in an order: ["value_1", "value_2", ...]
139//! It computes Dump of the parent. The expected field is a parent class name to call ClassName::Dump.
3de0f784 140#define OCCT_DUMP_FIELD_VALUES_STRING(theOStream, theName, theCount, ...) \
0904aa63 141{ \
3de0f784 142 Standard_Dump::AddValuesSeparator (theOStream); \
0904aa63 143 theOStream << "\"" << theName << "\": ["; \
144 Standard_Dump::DumpCharacterValues (theOStream, theCount, __VA_ARGS__);\
145 theOStream << "]"; \
146}
147
3de0f784 148//! @def OCCT_DUMP_BASE_CLASS
0904aa63 149//! Append into output value: "Name": { field dumped values }
150//! It computes Dump of the parent. The expected field is a parent class name to call ClassName::Dump.
151//! Use this macro for parent of the current class.
152//! The macros is recursive. Recursive is stoped when the depth value becomes equal to zero.
153//! Depth = -1 is the default value, dump here is unlimited.
3de0f784 154#define OCCT_DUMP_BASE_CLASS(theOStream, theDepth, theField) \
0904aa63 155{ \
156 if (theDepth != 0) \
157 { \
bc73b006 158 Standard_Dump::AddValuesSeparator (theOStream); \
159 theField::DumpJson (theOStream, theDepth - 1); \
0904aa63 160 } \
161}
162
3de0f784 163//! @def OCCT_DUMP_VECTOR_CLASS
0904aa63 164//! Append vector values into output value: "Name": [value_1, value_2, ...]
165//! This macro is intended to have only one row for dumped object in Json.
3de0f784 166//! It's possible to use it without necessity of OCCT_DUMP_CLASS_BEGIN call, but pay attention that it should be only one row in the object dump.
167#define OCCT_DUMP_VECTOR_CLASS(theOStream, theName, theCount, ...) \
0904aa63 168{ \
bc73b006 169 Standard_Dump::AddValuesSeparator (theOStream); \
170 theOStream << "\"" << theName << "\": ["; \
0904aa63 171 Standard_Dump::DumpRealValues (theOStream, theCount, __VA_ARGS__);\
172 theOStream << "]"; \
173}
174
bc73b006 175//! Kind of key in Json string
176enum Standard_JsonKey
0904aa63 177{
bc73b006 178 Standard_JsonKey_None, //!< no key
179 Standard_JsonKey_OpenChild, //!< "{"
180 Standard_JsonKey_CloseChild, //!< "}"
181 Standard_JsonKey_OpenContainer, //!< "["
182 Standard_JsonKey_CloseContainer, //!< "]"
183 Standard_JsonKey_Quote, //!< "\""
184 Standard_JsonKey_SeparatorKeyToValue, //!< ": "
185 Standard_JsonKey_SeparatorValueToValue //!< ", "
186};
0904aa63 187
bc73b006 188//! Type for storing a dump value with the stream position
189struct Standard_DumpValue
190{
191 Standard_DumpValue() : myStartPosition (0) {}
192 Standard_DumpValue (const TCollection_AsciiString& theValue, const Standard_Integer theStartPos)
193 : myValue (theValue), myStartPosition (theStartPos) {}
0904aa63 194
bc73b006 195 TCollection_AsciiString myValue; //!< current string value
196 Standard_Integer myStartPosition; //!< position of the value first char in the whole stream
0904aa63 197};
198
199//! This interface has some tool methods for stream (in JSON format) processing.
200class Standard_Dump
201{
202public:
203 //! Converts stream value to string value. The result is original stream value.
204 //! @param theStream source value
205 //! @return text presentation
206 Standard_EXPORT static TCollection_AsciiString Text (const Standard_SStream& theStream);
207
208 //! Converts stream value to string value. Improves the text presentation with the following cases:
209 //! - for '{' append after '\n' and indent to the next value, increment current indent value
210 //! - for '}' append '\n' and current indent before it, decrement indent value
211 //! - for ',' append after '\n' and indent to the next value. If the current symbol is in massive container [], do nothing
212 //! @param theStream source value
213 //! @param theIndent count of ' ' symbols to apply hierarchical indent of the text values
214 //! @return text presentation
215 Standard_EXPORT static TCollection_AsciiString FormatJson (const Standard_SStream& theStream, const Standard_Integer theIndent = 3);
216
bc73b006 217 //! Converts stream into map of values. Values are not empty if the stream contains at least two values.
218 //!
219 //! The one level stream example: <class_name>key_1\value_1\key_2\value_2</class_name>
220 //! In output: theStreamKey equals class_name, theValues contains key_1, value_1, key_2, and value_2.
221 //!
222 //! Two level stream example: <class_name>key_1\value_1\key_2\value_2\key_3<subclass_name>subclass_key_1\subclass_value1</subclass_name></class_name>
223 //! In output: theStreamKey equals class_name, theValues contains key_1, value_1, key_2, and value_2, key_3 and
224 //! <subclass_name>subclass_key_1\subclass_value1</subclass_name>.
225 //! The last value might be processed later using the same method.
226 //!
227 //! @param theStream stream value
228 //! @param theKeyToValues [out] container of split values
229 Standard_EXPORT static Standard_Boolean SplitJson (const TCollection_AsciiString& theStreamStr,
230 NCollection_IndexedDataMap<TCollection_AsciiString, Standard_DumpValue>& theKeyToValues);
231
232 //! Returns container of indices in values, that has hierarchical value
233 Standard_EXPORT static NCollection_List<Standard_Integer> HierarchicalValueIndices (
234 const NCollection_IndexedDataMap<TCollection_AsciiString, TCollection_AsciiString>& theValues);
235
236 //! Returns true if the value has bracket key
237 Standard_EXPORT static Standard_Boolean HasChildKey (const TCollection_AsciiString& theSourceValue);
238
239 //! Returns key value for enum type
240 Standard_EXPORT static Standard_CString JsonKeyToString (const Standard_JsonKey theKey);
241
242 //! Returns length value for enum type
243 Standard_EXPORT static Standard_Integer JsonKeyLength (const Standard_JsonKey theKey);
244
64e68ea6 245 //! @param theOStream source value
3de0f784 246 static Standard_EXPORT void AddValuesSeparator (Standard_OStream& theOStream);
0904aa63 247
248 //! Returns default prefix added for each pointer info string if short presentation of pointer used
bc73b006 249 static TCollection_AsciiString GetPointerPrefix() { return "0x"; }
0904aa63 250
251 //! Convert handle pointer to address of the pointer. If the handle is NULL, the result is an empty string.
252 //! @param thePointer a pointer
253 //! @param isShortInfo if true, all '0' symbols in the beginning of the pointer are skipped
254 //! @return the string value
255 Standard_EXPORT static TCollection_AsciiString GetPointerInfo (const Handle(Standard_Transient)& thePointer,
256 const bool isShortInfo = true);
257
258 //! Convert pointer to address of the pointer. If the handle is NULL, the result is an empty string.
259 //! @param thePointer a pointer
260 //! @param isShortInfo if true, all '0' symbols in the beginning of the pointer are skipped
261 //! @return the string value
262 Standard_EXPORT static TCollection_AsciiString GetPointerInfo (const void* thePointer,
263 const bool isShortInfo = true);
264
265 //! Append into output value: "Name": { Field }
266 //! @param theOStream [out] stream to be fill with values
267 //! @param theKey a source value
268 //! @param theField stream value
269 Standard_EXPORT static void DumpKeyToClass (Standard_OStream& theOStream,
bc73b006 270 const TCollection_AsciiString& theKey,
0904aa63 271 const TCollection_AsciiString& theField);
272
273 //! Unite values in one value using template: "value_1", "value_2", ..., "value_n"
274 //! @param theOStream [out] stream to be fill with values
275 //! @param theCount numer of values
276 Standard_EXPORT static void DumpCharacterValues (Standard_OStream& theOStream, int theCount, ...);
277
278 //! Unite values in one value using template: value_1, value_2, ..., value_n
279 //! @param theOStream [out] stream to be fill with values
280 //! @param theCount numer of values
281 Standard_EXPORT static void DumpRealValues (Standard_OStream& theOStream, int theCount, ...);
282
283 //! Convert field name into dump text value, removes "&" and "my" prefixes
284 //! An example, for field myValue, theName is Value, for &myCLass, the name is Class
285 //! @param theField a source value
bc73b006 286 Standard_EXPORT static TCollection_AsciiString DumpFieldToName (const TCollection_AsciiString& theField);
287
288private:
289 //! Extracts from the string value a pair (key, value), add it into output container, update index value
290 //! Example:
291 //! stream string starting the index position contains: ..."key": <value>...
292 //! a pair key, value will be added into theValues
293 //! at beginning theIndex is the position of the quota before <key>, after the index is the next position after the value
294 //! splitDumped(aString) gives theSplitValue = "abc", theTailValue = "defg", theKey = "key"
295 Standard_EXPORT static Standard_Boolean splitKeyToValue (const TCollection_AsciiString& theStreamStr,
296 Standard_Integer theStartIndex,
297 Standard_Integer& theNextIndex,
298 NCollection_IndexedDataMap<TCollection_AsciiString, Standard_DumpValue>& theValues);
299
300
301 //! Returns key of json in the index position. Incement the index position to the next symbol in the row
302 Standard_EXPORT static Standard_Boolean jsonKey (const TCollection_AsciiString& theStreamStr,
303 Standard_Integer theStartIndex,
304 Standard_Integer& theNextIndex,
305 Standard_JsonKey& theKey);
306
307 //! Find position in the source string of the symbol close after the start position.
308 //! Ignore combination <symbol open> ... <symbol close> between the close symbol.
309 //! Example, for case ... { ... { ... } ...} ... } it returns the position of the forth brace
310 Standard_EXPORT static Standard_Integer nextClosePosition (const TCollection_AsciiString& theSourceValue,
311 const Standard_Integer theStartPosition,
312 const Standard_JsonKey theCloseKey,
313 const Standard_JsonKey theOpenKey);
314
0904aa63 315};
316
317#endif // _Standard_Dump_HeaderFile