mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0030949: Foundation Classes - Dump improvement for OCCT classes
1. new file Standard_Dump to prepare and parse Dump in JSON format for OCCT objects 2. some presentations cover the proposed dump functionality. 3. 'bounding', 'vaspects' has '-dumpJson' field to see the DumpJson result 4. Bnd_Box constructor with min/max points is implemented to use Dump of this class in Dump BVH_Box 5. Limitation (some classes of Graphic3d, Prs3d has not full filling for DumpJson)
This commit is contained in:
@@ -24,6 +24,8 @@ Standard_DimensionError.hxx
|
||||
Standard_DimensionMismatch.hxx
|
||||
Standard_DivideByZero.hxx
|
||||
Standard_DomainError.hxx
|
||||
Standard_Dump.cxx
|
||||
Standard_Dump.hxx
|
||||
Standard_ErrorHandler.cxx
|
||||
Standard_ErrorHandler.hxx
|
||||
Standard_ExtCharacter.hxx
|
||||
|
224
src/Standard/Standard_Dump.cxx
Normal file
224
src/Standard/Standard_Dump.cxx
Normal file
@@ -0,0 +1,224 @@
|
||||
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <Standard_Dump.hxx>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
// =======================================================================
|
||||
// function : Constructor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_DumpSentry::Standard_DumpSentry (Standard_OStream& theOStream, const char* theClassName)
|
||||
: myOStream (&theOStream)
|
||||
{
|
||||
(*myOStream) << "\"" << theClassName << "\": {";
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Destructor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_DumpSentry::~Standard_DumpSentry()
|
||||
{
|
||||
(*myOStream) << "}";
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : EndsWith
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Standard_Dump::EndsWith (const Standard_OStream& theOStream,
|
||||
const TCollection_AsciiString& theEndString)
|
||||
{
|
||||
Standard_SStream aStream;
|
||||
aStream << theOStream.rdbuf();
|
||||
TCollection_AsciiString aStreamStr = Standard_Dump::Text (aStream);
|
||||
return aStreamStr.EndsWith (theEndString);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DumpKeyToClass
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Standard_Dump::DumpKeyToClass (Standard_OStream& theOStream,
|
||||
const char* theKey,
|
||||
const TCollection_AsciiString& theField)
|
||||
{
|
||||
if (!Standard_Dump::EndsWith (theOStream, "{"))
|
||||
theOStream << ", ";
|
||||
theOStream << "\"" << theKey << "\": {" << theField << "}";
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DumpCharacterValues
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Standard_Dump::DumpCharacterValues (Standard_OStream& theOStream, int theCount, ...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, theCount);
|
||||
for(int i = 0; i < theCount; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
theOStream << ", ";
|
||||
theOStream << "\"" << va_arg(vl, char*) << "\"";
|
||||
}
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DumpRealValues
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Standard_Dump::DumpRealValues (Standard_OStream& theOStream, int theCount, ...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, theCount);
|
||||
for(int i = 0; i < theCount; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
theOStream << ", ";
|
||||
theOStream << va_arg(vl, Standard_Real);
|
||||
}
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetPointerInfo
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
TCollection_AsciiString Standard_Dump::GetPointerInfo (const Handle(Standard_Transient)& thePointer,
|
||||
const bool isShortInfo)
|
||||
{
|
||||
if (thePointer.IsNull())
|
||||
return TCollection_AsciiString();
|
||||
|
||||
return GetPointerInfo (thePointer.get(), isShortInfo);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetPointerInfo
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
TCollection_AsciiString Standard_Dump::GetPointerInfo (const void* thePointer, const bool isShortInfo)
|
||||
{
|
||||
std::ostringstream aPtrStr;
|
||||
aPtrStr << thePointer;
|
||||
if (!isShortInfo)
|
||||
return aPtrStr.str().c_str();
|
||||
|
||||
TCollection_AsciiString anInfoPtr (aPtrStr.str().c_str());
|
||||
for (int aSymbolId = 1; aSymbolId < anInfoPtr.Length(); aSymbolId++)
|
||||
{
|
||||
if (anInfoPtr.Value(aSymbolId) != '0')
|
||||
{
|
||||
anInfoPtr = anInfoPtr.SubString (aSymbolId, anInfoPtr.Length());
|
||||
anInfoPtr.Prepend (GetPointerPrefix());
|
||||
return anInfoPtr;
|
||||
}
|
||||
}
|
||||
return aPtrStr.str().c_str();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// DumpFieldToName
|
||||
// =======================================================================
|
||||
void Standard_Dump::DumpFieldToName (const char* theField, const char*& theName)
|
||||
{
|
||||
theName = theField;
|
||||
|
||||
if (theName[0] == '&')
|
||||
{
|
||||
theName = theName + 1;
|
||||
}
|
||||
if (::LowerCase (theName[0]) == 'm' && theName[1] == 'y')
|
||||
{
|
||||
theName = theName + 2;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// Text
|
||||
// =======================================================================
|
||||
TCollection_AsciiString Standard_Dump::Text (const Standard_SStream& theStream)
|
||||
{
|
||||
return TCollection_AsciiString (theStream.str().c_str());
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// FormatJson
|
||||
// =======================================================================
|
||||
TCollection_AsciiString Standard_Dump::FormatJson (const Standard_SStream& theStream,
|
||||
const Standard_Integer theIndent)
|
||||
{
|
||||
TCollection_AsciiString aStreamStr = Text (theStream);
|
||||
TCollection_AsciiString anIndentStr;
|
||||
for (Standard_Integer anIndentId = 0; anIndentId < theIndent; anIndentId++)
|
||||
anIndentStr.AssignCat (' ');
|
||||
|
||||
TCollection_AsciiString aText;
|
||||
|
||||
Standard_Integer anIndentCount = 0;
|
||||
Standard_Boolean isMassiveValues = Standard_False;
|
||||
for (Standard_Integer anIndex = 1; anIndex < aStreamStr.Length(); anIndex++)
|
||||
{
|
||||
Standard_Character aSymbol = aStreamStr.Value (anIndex);
|
||||
if (aSymbol == '{')
|
||||
{
|
||||
anIndentCount++;
|
||||
|
||||
aText += aSymbol;
|
||||
aText += '\n';
|
||||
|
||||
for (int anIndent = 0; anIndent < anIndentCount; anIndent++)
|
||||
aText += anIndentStr;
|
||||
}
|
||||
else if (aSymbol == '}')
|
||||
{
|
||||
anIndentCount--;
|
||||
|
||||
aText += '\n';
|
||||
for (int anIndent = 0; anIndent < anIndentCount; anIndent++)
|
||||
aText += anIndentStr;
|
||||
aText += aSymbol;
|
||||
}
|
||||
else if (aSymbol == '[')
|
||||
{
|
||||
isMassiveValues = Standard_True;
|
||||
aText += aSymbol;
|
||||
}
|
||||
else if (aSymbol == ']')
|
||||
{
|
||||
isMassiveValues = Standard_False;
|
||||
aText += aSymbol;
|
||||
}
|
||||
else if (aSymbol == ',')
|
||||
{
|
||||
if (!isMassiveValues)
|
||||
{
|
||||
aText += aSymbol;
|
||||
aText += '\n';
|
||||
for (int anIndent = 0; anIndent < anIndentCount; anIndent++)
|
||||
aText += anIndentStr;
|
||||
if (anIndex + 1 < aStreamStr.Length() && aStreamStr.Value (anIndex + 1) == ' ')
|
||||
anIndex++; // skip empty value after comma
|
||||
}
|
||||
else
|
||||
aText += aSymbol;
|
||||
}
|
||||
else
|
||||
aText += aSymbol;
|
||||
}
|
||||
return aText;
|
||||
}
|
245
src/Standard/Standard_Dump.hxx
Normal file
245
src/Standard/Standard_Dump.hxx
Normal file
@@ -0,0 +1,245 @@
|
||||
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _Standard_Dump_HeaderFile
|
||||
#define _Standard_Dump_HeaderFile
|
||||
|
||||
#include <Standard_SStream.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
class Standard_DumpSentry;
|
||||
|
||||
//! The file contains interface to prepare dump output for OCCT objects. Format of the dump is JSON.
|
||||
//! To prepare this output, implement method Dump in the object and use macro functions from this file.
|
||||
//! Macros have one parameter for both, key and the value. It is a field of the current class. Macro has internal analyzer that
|
||||
//! uses the variable name to generate key. If the parameter has prefix symbols "&", "*" and "my", it is cut.
|
||||
//!
|
||||
//! - DUMP_FIELD_VALUE_NUMERICAL. Use it for fields of numerical C++ types, like int, float, double. It creates a pair "key", "value",
|
||||
//! - DUMP_FIELD_VALUE_STRING. Use it for char* type. It creates a pair "key", "value",
|
||||
//! - DUMP_FIELD_VALUE_POINTER. Use it for pointer fields. It creates a pair "key", "value", where the value is the pointer address,
|
||||
//! - DUMP_FIELD_VALUES_DUMPED. Use it for fields that has own Dump implementation. It expects the pointer to the class instance.
|
||||
//! It creates "key": { result of dump of the field }
|
||||
//! - DUMP_FIELD_VALUES_NUMERICAL. Use it for unlimited list of fields of C++ double type.
|
||||
//! It creates massive of values [value_1, value_2, ...]
|
||||
//! - DUMP_FIELD_VALUES_STRING. Use it for unlimited list of fields of TCollection_AsciiString types.
|
||||
//! It creates massive of values ["value_1", "value_2", ...]
|
||||
//! - DUMP_FIELD_VALUES_BY_KIND. Use if Dump implementation of the class is virtual, to perform ClassName::Dump() of the parent class,
|
||||
//! expected parameter is the parent class name.
|
||||
//! It creates "key": { result of dump of the field }
|
||||
//! - DUMP_VECTOR_CLASS. Use it as a single row in some object dump to have one row in output.
|
||||
//! It's possible to use it without necessity of DUMP_CLASS_BEGIN call.
|
||||
//! It creates massive of values [value_1, value_2, ...]
|
||||
//!
|
||||
//! The Dump result prepared by these macros is an output stream, it is not arranged with spaces and line feed.
|
||||
//! To have output in a more readable way, use ConvertToAlignedString method for obtained stream.
|
||||
|
||||
//! Converts the class type into a string value
|
||||
#define CLASS_NAME(theClass) #theClass
|
||||
|
||||
//! @def DUMP_CLASS_BEGIN
|
||||
//! Creates an instance of Sentry to cover the current Dump implementation with keys of start and end.
|
||||
//! This row should be inserted before other macros. The end key will be added by the sentry remove,
|
||||
//! (exit of the method).
|
||||
#define DUMP_CLASS_BEGIN(theOStream, theName) \
|
||||
Standard_DumpSentry aSentry (theOStream, CLASS_NAME(theName)); \
|
||||
|
||||
//! @def DUMP_FIELD_VALUE_NUMERICAL
|
||||
//! Append into output value: "Name": Field
|
||||
#define DUMP_FIELD_VALUE_NUMERICAL(theOStream, theField) \
|
||||
{ \
|
||||
const char* aName = NULL; \
|
||||
Standard_Dump::DumpFieldToName (#theField, aName); \
|
||||
if (!Standard_Dump::EndsWith (theOStream, "{")) \
|
||||
theOStream << ", "; \
|
||||
theOStream << "\"" << aName << "\": " << theField; \
|
||||
}
|
||||
|
||||
//! @def DUMP_FIELD_VALUE_STRING
|
||||
//! Append into output value: "Name": "Field"
|
||||
#define DUMP_FIELD_VALUE_STRING(theOStream, theField) \
|
||||
{ \
|
||||
const char* aName = NULL; \
|
||||
Standard_Dump::DumpFieldToName (#theField, aName); \
|
||||
if (!Standard_Dump::EndsWith (theOStream, "{")) \
|
||||
theOStream << ", "; \
|
||||
theOStream << "\"" << aName << "\": \"" << theField << "\""; \
|
||||
}
|
||||
|
||||
//! @def DUMP_FIELD_VALUE_POINTER
|
||||
//! Append into output value: "Name": "address of the pointer"
|
||||
#define DUMP_FIELD_VALUE_POINTER(theOStream, theField) \
|
||||
{ \
|
||||
const char* aName = NULL; \
|
||||
Standard_Dump::DumpFieldToName (#theField, aName); \
|
||||
if (!Standard_Dump::EndsWith (theOStream, "{")) \
|
||||
theOStream << ", "; \
|
||||
theOStream << "\"" << aName << "\": \"" << Standard_Dump::GetPointerInfo (theField) << "\""; \
|
||||
}
|
||||
|
||||
//! @def DUMP_FIELD_VALUES_DUMPED
|
||||
//! Append into output value: "Name": { field dumped values }
|
||||
//! It computes Dump of the fields. The expected field is a pointer.
|
||||
//! Use this macro for fields of the dumped class which has own Dump implementation.
|
||||
//! The macros is recursive. Recursion is stopped when the depth value becomes equal to zero.
|
||||
//! Depth = -1 is the default value, dump here is unlimited.
|
||||
#define DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, theField) \
|
||||
{ \
|
||||
if (theDepth != 0) \
|
||||
{ \
|
||||
Standard_SStream aFieldStream; \
|
||||
if ((theField) != NULL) \
|
||||
(theField)->DumpJson (aFieldStream, theDepth - 1); \
|
||||
const char* aName = NULL; \
|
||||
Standard_Dump::DumpFieldToName (#theField, aName); \
|
||||
Standard_Dump::DumpKeyToClass (theOStream, aName, Standard_Dump::Text (aFieldStream)); \
|
||||
} \
|
||||
}
|
||||
|
||||
//! @def DUMP_FIELD_VALUES_NUMERICAL
|
||||
//! Append real values into output values in an order: [value_1, value_2, ...]
|
||||
//! It computes Dump of the parent. The expected field is a parent class name to call ClassName::Dump.
|
||||
#define DUMP_FIELD_VALUES_NUMERICAL(theOStream, theName, theCount, ...) \
|
||||
{ \
|
||||
if (!Standard_Dump::EndsWith (theOStream, "{")) \
|
||||
theOStream << ", "; \
|
||||
theOStream << "\"" << theName << "\": ["; \
|
||||
Standard_Dump::DumpRealValues (theOStream, theCount, __VA_ARGS__);\
|
||||
theOStream << "]"; \
|
||||
}
|
||||
|
||||
//! @def DUMP_FIELD_VALUES_STRING
|
||||
//! Append real values into output values in an order: ["value_1", "value_2", ...]
|
||||
//! It computes Dump of the parent. The expected field is a parent class name to call ClassName::Dump.
|
||||
#define DUMP_FIELD_VALUES_STRING(theOStream, theName, theCount, ...) \
|
||||
{ \
|
||||
if (!Standard_Dump::EndsWith (theOStream, "{")) \
|
||||
theOStream << ", "; \
|
||||
theOStream << "\"" << theName << "\": ["; \
|
||||
Standard_Dump::DumpCharacterValues (theOStream, theCount, __VA_ARGS__);\
|
||||
theOStream << "]"; \
|
||||
}
|
||||
|
||||
//! @def DUMP_FIELD_VALUES_BY_KIND
|
||||
//! Append into output value: "Name": { field dumped values }
|
||||
//! It computes Dump of the parent. The expected field is a parent class name to call ClassName::Dump.
|
||||
//! Use this macro for parent of the current class.
|
||||
//! The macros is recursive. Recursive is stoped when the depth value becomes equal to zero.
|
||||
//! Depth = -1 is the default value, dump here is unlimited.
|
||||
#define DUMP_FIELD_VALUES_BY_KIND(theOStream, theDepth, theField) \
|
||||
{ \
|
||||
if (theDepth != 0) \
|
||||
{ \
|
||||
Standard_SStream aFieldStream; \
|
||||
theField::DumpJson (aFieldStream, theDepth - 1); \
|
||||
const char* aName = NULL; \
|
||||
Standard_Dump::DumpFieldToName (#theField, aName); \
|
||||
Standard_Dump::DumpKeyToClass (theOStream, aName, Standard_Dump::Text (aFieldStream)); \
|
||||
} \
|
||||
}
|
||||
|
||||
//! @def DUMP_VECTOR_CLASS
|
||||
//! Append vector values into output value: "Name": [value_1, value_2, ...]
|
||||
//! This macro is intended to have only one row for dumped object in Json.
|
||||
//! It's possible to use it without necessity of DUMP_CLASS_BEGIN call, but pay attention that it should be only one row in the object dump.
|
||||
#define DUMP_VECTOR_CLASS(theOStream, theName, theCount, ...) \
|
||||
{ \
|
||||
theOStream << "\"" << CLASS_NAME(theName) << "\": ["; \
|
||||
Standard_Dump::DumpRealValues (theOStream, theCount, __VA_ARGS__);\
|
||||
theOStream << "]"; \
|
||||
}
|
||||
|
||||
//! @brief Simple sentry class providing convenient interface to dump.
|
||||
//! Appends start and last rows in dump with class name key.
|
||||
//! An example of the using: for ClassName, the result is: "ClassName" { ... }
|
||||
//! Create instance of that class in the first row of Dump.
|
||||
class Standard_DumpSentry
|
||||
{
|
||||
public:
|
||||
//! Constructor - add parameters of start class name definition in the stream
|
||||
Standard_EXPORT Standard_DumpSentry (Standard_OStream& theOStream, const char* theClassName);
|
||||
|
||||
//! Destructor - add parameters of stop class name definition in the stream
|
||||
Standard_EXPORT ~Standard_DumpSentry();
|
||||
|
||||
private:
|
||||
Standard_OStream* myOStream; //!< modified stream
|
||||
};
|
||||
|
||||
//! This interface has some tool methods for stream (in JSON format) processing.
|
||||
class Standard_Dump
|
||||
{
|
||||
public:
|
||||
//! Converts stream value to string value. The result is original stream value.
|
||||
//! @param theStream source value
|
||||
//! @return text presentation
|
||||
Standard_EXPORT static TCollection_AsciiString Text (const Standard_SStream& theStream);
|
||||
|
||||
//! Converts stream value to string value. Improves the text presentation with the following cases:
|
||||
//! - for '{' append after '\n' and indent to the next value, increment current indent value
|
||||
//! - for '}' append '\n' and current indent before it, decrement indent value
|
||||
//! - for ',' append after '\n' and indent to the next value. If the current symbol is in massive container [], do nothing
|
||||
//! @param theStream source value
|
||||
//! @param theIndent count of ' ' symbols to apply hierarchical indent of the text values
|
||||
//! @return text presentation
|
||||
Standard_EXPORT static TCollection_AsciiString FormatJson (const Standard_SStream& theStream, const Standard_Integer theIndent = 3);
|
||||
|
||||
//! Determines whether the end of this stream matches the specified string.
|
||||
//! @param theStream source value
|
||||
//! @param theEndString text value to find
|
||||
//! @return true if matches
|
||||
static Standard_EXPORT Standard_Boolean EndsWith (const Standard_OStream& theOStream,
|
||||
const TCollection_AsciiString& theEndString);
|
||||
|
||||
//! Returns default prefix added for each pointer info string if short presentation of pointer used
|
||||
Standard_EXPORT static TCollection_AsciiString GetPointerPrefix() { return "0x"; }
|
||||
|
||||
//! Convert handle pointer to address of the pointer. If the handle is NULL, the result is an empty string.
|
||||
//! @param thePointer a pointer
|
||||
//! @param isShortInfo if true, all '0' symbols in the beginning of the pointer are skipped
|
||||
//! @return the string value
|
||||
Standard_EXPORT static TCollection_AsciiString GetPointerInfo (const Handle(Standard_Transient)& thePointer,
|
||||
const bool isShortInfo = true);
|
||||
|
||||
//! Convert pointer to address of the pointer. If the handle is NULL, the result is an empty string.
|
||||
//! @param thePointer a pointer
|
||||
//! @param isShortInfo if true, all '0' symbols in the beginning of the pointer are skipped
|
||||
//! @return the string value
|
||||
Standard_EXPORT static TCollection_AsciiString GetPointerInfo (const void* thePointer,
|
||||
const bool isShortInfo = true);
|
||||
|
||||
//! Append into output value: "Name": { Field }
|
||||
//! @param theOStream [out] stream to be fill with values
|
||||
//! @param theKey a source value
|
||||
//! @param theField stream value
|
||||
Standard_EXPORT static void DumpKeyToClass (Standard_OStream& theOStream,
|
||||
const char* theKey,
|
||||
const TCollection_AsciiString& theField);
|
||||
|
||||
//! Unite values in one value using template: "value_1", "value_2", ..., "value_n"
|
||||
//! @param theOStream [out] stream to be fill with values
|
||||
//! @param theCount numer of values
|
||||
Standard_EXPORT static void DumpCharacterValues (Standard_OStream& theOStream, int theCount, ...);
|
||||
|
||||
//! Unite values in one value using template: value_1, value_2, ..., value_n
|
||||
//! @param theOStream [out] stream to be fill with values
|
||||
//! @param theCount numer of values
|
||||
Standard_EXPORT static void DumpRealValues (Standard_OStream& theOStream, int theCount, ...);
|
||||
|
||||
//! Convert field name into dump text value, removes "&" and "my" prefixes
|
||||
//! An example, for field myValue, theName is Value, for &myCLass, the name is Class
|
||||
//! @param theField a source value
|
||||
//! @param theName [out] an updated name
|
||||
Standard_EXPORT static void DumpFieldToName (const char* theField, const char*& theName);
|
||||
};
|
||||
|
||||
#endif // _Standard_Dump_HeaderFile
|
Reference in New Issue
Block a user