0030997: Foundation Classes - name correction of dump macros
[occt.git] / src / Standard / Standard_Dump.hxx
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
17 #include <Standard_SStream.hxx>
18 #include <TCollection_AsciiString.hxx>
19
20 class Standard_DumpSentry;
21
22 //! The file contains interface to prepare dump output for OCCT objects. Format of the dump is JSON.
23 //! To prepare this output, implement method DumpJson in the object and use macro functions from this file.
24 //! Macros have one parameter for both, key and the value. It is a field of the current class. Macro has internal analyzer that
25 //! uses the variable name to generate key. If the parameter has prefix symbols "&", "*" and "my", it is cut.
26 //!
27 //! - OCCT_DUMP_FIELD_VALUE_NUMERICAL. Use it for fields of numerical C++ types, like int, float, double. It creates a pair "key", "value",
28 //! - OCCT_DUMP_FIELD_VALUE_STRING. Use it for char* type. It creates a pair "key", "value",
29 //! - OCCT_DUMP_FIELD_VALUE_POINTER. Use it for pointer fields. It creates a pair "key", "value", where the value is the pointer address,
30 //! - OCCT_DUMP_FIELD_VALUES_DUMPED. Use it for fields that has own Dump implementation. It expects the pointer to the class instance.
31 //!     It creates "key": { result of dump of the field }
32 //! - OCCT_DUMP_FIELD_VALUES_NUMERICAL. Use it for unlimited list of fields of C++ double type.
33 //!     It creates massive of values [value_1, value_2, ...]
34 //! - OCCT_DUMP_FIELD_VALUES_STRING. Use it for unlimited list of fields of TCollection_AsciiString types.
35 //!     It creates massive of values ["value_1", "value_2", ...]
36 //! - OCCT_DUMP_BASE_CLASS. Use if Dump implementation of the class is virtual, to perform ClassName::Dump() of the parent class,
37 //!     expected parameter is the parent class name.
38 //!     It creates "key": { result of dump of the field }
39 //! - OCCT_DUMP_VECTOR_CLASS. Use it as a single row in some object dump to have one row in output.
40 //!     It's possible to use it without necessity of OCCT_DUMP_CLASS_BEGIN call.
41 //!     It creates massive of values [value_1, value_2, ...]
42 //!
43 //! The Dump result prepared by these macros is an output stream, it is not arranged with spaces and line feed.
44 //! To have output in a more readable way, use ConvertToAlignedString method for obtained stream.
45
46 //! Converts the class type into a string value
47 #define OCCT_CLASS_NAME(theClass) #theClass
48
49 //! @def OCCT_DUMP_CLASS_BEGIN
50 //! Creates an instance of Sentry to cover the current Dump implementation with keys of start and end.
51 //! This row should be inserted before other macros. The end key will be added by the sentry remove,
52 //! (exit of the method).
53 #define OCCT_DUMP_CLASS_BEGIN(theOStream, theName) \
54   Standard_DumpSentry aSentry (theOStream, OCCT_CLASS_NAME(theName));
55
56 //! @def OCCT_DUMP_FIELD_VALUE_NUMERICAL
57 //! Append into output value: "Name": Field
58 #define OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, theField) \
59 { \
60   const char* aName = Standard_Dump::DumpFieldToName (#theField); \
61   Standard_Dump::AddValuesSeparator (theOStream); \
62   theOStream << "\"" << aName << "\": " << theField; \
63 }
64
65 //! @def OCCT_DUMP_FIELD_VALUE_STRING
66 //! Append into output value: "Name": "Field"
67 #define OCCT_DUMP_FIELD_VALUE_STRING(theOStream, theField) \
68 { \
69   const char* aName = Standard_Dump::DumpFieldToName (#theField); \
70   Standard_Dump::AddValuesSeparator (theOStream); \
71   theOStream << "\"" << aName << "\": \"" << theField << "\""; \
72 }
73
74 //! @def OCCT_DUMP_FIELD_VALUE_POINTER
75 //! Append into output value: "Name": "address of the pointer"
76 #define OCCT_DUMP_FIELD_VALUE_POINTER(theOStream, theField) \
77 { \
78   const char* aName = Standard_Dump::DumpFieldToName (#theField); \
79   Standard_Dump::AddValuesSeparator (theOStream); \
80   theOStream << "\"" << aName << "\": \"" << Standard_Dump::GetPointerInfo (theField) << "\""; \
81 }
82
83 //! @def OCCT_DUMP_FIELD_VALUES_DUMPED
84 //! Append into output value: "Name": { field dumped values }
85 //! It computes Dump of the fields. The expected field is a pointer.
86 //! Use this macro for fields of the dumped class which has own Dump implementation.
87 //! The macros is recursive. Recursion is stopped when the depth value becomes equal to zero.
88 //! Depth = -1 is the default value, dump here is unlimited.
89 #define OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, theField) \
90 { \
91   if (theDepth != 0) \
92   { \
93     Standard_SStream aFieldStream; \
94     if ((theField) != NULL) \
95       (theField)->DumpJson (aFieldStream, theDepth - 1); \
96     const char* aName = Standard_Dump::DumpFieldToName (#theField); \
97     Standard_Dump::DumpKeyToClass (theOStream, aName, Standard_Dump::Text (aFieldStream)); \
98   } \
99 }
100
101 //! @def OCCT_DUMP_FIELD_VALUES_NUMERICAL
102 //! Append real values into output values in an order: [value_1, value_2, ...]
103 //! It computes Dump of the parent. The expected field is a parent class name to call ClassName::Dump.
104 #define OCCT_DUMP_FIELD_VALUES_NUMERICAL(theOStream, theName, theCount, ...) \
105 { \
106   Standard_Dump::AddValuesSeparator (theOStream); \
107   theOStream << "\"" << theName << "\": ["; \
108   Standard_Dump::DumpRealValues (theOStream, theCount, __VA_ARGS__);\
109   theOStream << "]"; \
110 }
111
112 //! @def OCCT_DUMP_FIELD_VALUES_STRING
113 //! Append real values into output values in an order: ["value_1", "value_2", ...]
114 //! It computes Dump of the parent. The expected field is a parent class name to call ClassName::Dump.
115 #define OCCT_DUMP_FIELD_VALUES_STRING(theOStream, theName, theCount, ...) \
116 { \
117   Standard_Dump::AddValuesSeparator (theOStream); \
118   theOStream << "\"" << theName << "\": ["; \
119   Standard_Dump::DumpCharacterValues (theOStream, theCount, __VA_ARGS__);\
120   theOStream << "]"; \
121 }
122
123 //! @def OCCT_DUMP_BASE_CLASS
124 //! Append into output value: "Name": { field dumped values }
125 //! It computes Dump of the parent. The expected field is a parent class name to call ClassName::Dump.
126 //! Use this macro for parent of the current class.
127 //! The macros is recursive. Recursive is stoped when the depth value becomes equal to zero.
128 //! Depth = -1 is the default value, dump here is unlimited.
129 #define OCCT_DUMP_BASE_CLASS(theOStream, theDepth, theField) \
130 { \
131   if (theDepth != 0) \
132   { \
133     Standard_SStream aFieldStream; \
134     theField::DumpJson (aFieldStream, theDepth - 1); \
135     const char* aName = Standard_Dump::DumpFieldToName (#theField); \
136     Standard_Dump::DumpKeyToClass (theOStream, aName, Standard_Dump::Text (aFieldStream)); \
137   } \
138 }
139
140 //! @def OCCT_DUMP_VECTOR_CLASS
141 //! Append vector values into output value: "Name": [value_1, value_2, ...]
142 //! This macro is intended to have only one row for dumped object in Json.
143 //! 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.
144 #define OCCT_DUMP_VECTOR_CLASS(theOStream, theName, theCount, ...) \
145 { \
146   theOStream << "\"" << OCCT_CLASS_NAME(theName) << "\": ["; \
147   Standard_Dump::DumpRealValues (theOStream, theCount, __VA_ARGS__);\
148   theOStream << "]"; \
149 }
150
151 //! @brief Simple sentry class providing convenient interface to dump.
152 //! Appends start and last rows in dump with class name key.
153 //! An example of the using: for ClassName, the result is: "ClassName" { ... }
154 //! Create instance of that class in the first row of Dump.
155 class Standard_DumpSentry
156 {
157 public:
158   //! Constructor - add parameters of start class name definition in the stream
159   Standard_EXPORT Standard_DumpSentry (Standard_OStream& theOStream, const char* theClassName);
160
161   //! Destructor - add parameters of stop class name definition in the stream
162   Standard_EXPORT ~Standard_DumpSentry();
163
164 private:
165   Standard_OStream* myOStream; //!< modified stream
166 };
167
168 //! This interface has some tool methods for stream (in JSON format) processing.
169 class Standard_Dump
170 {
171 public:
172   //! Converts stream value to string value. The result is original stream value.
173   //! @param theStream source value
174   //! @return text presentation
175   Standard_EXPORT static TCollection_AsciiString Text (const Standard_SStream& theStream);
176
177   //! Converts stream value to string value. Improves the text presentation with the following cases:
178   //! - for '{' append after '\n' and indent to the next value, increment current indent value
179   //! - for '}' append '\n' and current indent before it, decrement indent value
180   //! - for ',' append after '\n' and indent to the next value. If the current symbol is in massive container [], do nothing
181   //! @param theStream source value
182   //! @param theIndent count of ' ' symbols to apply hierarchical indent of the text values
183   //! @return text presentation
184   Standard_EXPORT static TCollection_AsciiString FormatJson (const Standard_SStream& theStream, const Standard_Integer theIndent = 3);
185
186   //! Add Json values separator if the stream last symbol is not an open brace.
187   //! @param theStream source value
188   static Standard_EXPORT void AddValuesSeparator (Standard_OStream& theOStream);
189
190   //! Returns default prefix added for each pointer info string if short presentation of pointer used
191   Standard_EXPORT static TCollection_AsciiString GetPointerPrefix() { return "0x"; }
192
193   //! Convert handle pointer to address of the pointer. If the handle is NULL, the result is an empty string.
194   //! @param thePointer a pointer
195   //! @param isShortInfo if true, all '0' symbols in the beginning of the pointer are skipped
196   //! @return the string value
197   Standard_EXPORT static TCollection_AsciiString GetPointerInfo (const Handle(Standard_Transient)& thePointer,
198                                                                  const bool isShortInfo = true);
199
200   //! Convert pointer to address of the pointer. If the handle is NULL, the result is an empty string.
201   //! @param thePointer a pointer
202   //! @param isShortInfo if true, all '0' symbols in the beginning of the pointer are skipped
203   //! @return the string value
204   Standard_EXPORT static TCollection_AsciiString GetPointerInfo (const void* thePointer,
205                                                                  const bool isShortInfo = true);
206
207   //! Append into output value: "Name": { Field }
208   //! @param theOStream [out] stream to be fill with values
209   //! @param theKey a source value
210   //! @param theField stream value
211   Standard_EXPORT static void DumpKeyToClass (Standard_OStream& theOStream,
212                                               const char* theKey,
213                                               const TCollection_AsciiString& theField);
214
215   //! Unite values in one value using template: "value_1", "value_2", ..., "value_n"
216   //! @param theOStream [out] stream to be fill with values
217   //! @param theCount numer of values
218   Standard_EXPORT static void DumpCharacterValues (Standard_OStream& theOStream, int theCount, ...);
219
220   //! Unite values in one value using template: value_1, value_2, ..., value_n
221   //! @param theOStream [out] stream to be fill with values
222   //! @param theCount numer of values
223   Standard_EXPORT static void DumpRealValues (Standard_OStream& theOStream, int theCount, ...);
224
225   //! Convert field name into dump text value, removes "&" and "my" prefixes
226   //! An example, for field myValue, theName is Value, for &myCLass, the name is Class
227   //! @param theField a source value 
228   //! @param theName [out] an updated name 
229   Standard_EXPORT static const char* DumpFieldToName (const char* theField);
230 };
231
232 #endif // _Standard_Dump_HeaderFile