1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0031326: Foundation Classes - Init from Json for base OCCT classes

InitFromJson method implementation for some simple classes.
OCCT_INIT_* defines introduction to do automatic parsing of the stream into values.
Inspector is extended to visualize objects created on the dump stream if it might be created.
This commit is contained in:
nds
2020-09-08 00:16:32 +03:00
committed by bugmaster
parent b19cde437e
commit 6b63dc83c3
33 changed files with 793 additions and 63 deletions

View File

@@ -74,6 +74,135 @@ void Standard_Dump::DumpRealValues (Standard_OStream& theOStream, int theCount,
va_end(vl);
}
//=======================================================================
//function : ProcessStreamName
//purpose :
//=======================================================================
Standard_Boolean Standard_Dump::ProcessStreamName (const TCollection_AsciiString& theStreamStr,
const TCollection_AsciiString& theName,
Standard_Integer& theStreamPos)
{
if (theStreamStr.IsEmpty())
return Standard_False;
if (theStreamStr.Length () < theStreamPos)
return Standard_False;
TCollection_AsciiString aSubText = theStreamStr.SubString (theStreamPos, theStreamStr.Length());
if (aSubText.StartsWith (JsonKeyToString (Standard_JsonKey_SeparatorValueToValue)))
{
theStreamPos += JsonKeyLength (Standard_JsonKey_SeparatorValueToValue);
aSubText = theStreamStr.SubString (theStreamPos, theStreamStr.Length());
}
TCollection_AsciiString aKeyName = TCollection_AsciiString (JsonKeyToString (Standard_JsonKey_Quote))
+ theName
+ TCollection_AsciiString (JsonKeyToString (Standard_JsonKey_Quote))
+ JsonKeyToString (Standard_JsonKey_SeparatorKeyToValue);
Standard_Boolean aResult = aSubText.StartsWith (aKeyName);
if (aResult)
theStreamPos += aKeyName.Length();
return aResult;
}
//=======================================================================
//function : ProcessFieldName
//purpose :
//=======================================================================
Standard_Boolean Standard_Dump::ProcessFieldName (const TCollection_AsciiString& theStreamStr,
const TCollection_AsciiString& theName,
Standard_Integer& theStreamPos)
{
if (theStreamStr.IsEmpty())
return Standard_False;
TCollection_AsciiString aSubText = theStreamStr.SubString (theStreamPos, theStreamStr.Length());
if (aSubText.StartsWith (JsonKeyToString (Standard_JsonKey_SeparatorValueToValue)))
{
theStreamPos += JsonKeyLength (Standard_JsonKey_SeparatorValueToValue);
aSubText = theStreamStr.SubString (theStreamPos, theStreamStr.Length());
}
TCollection_AsciiString aName = Standard_Dump::DumpFieldToName (theName.ToCString());
TCollection_AsciiString aKeyName = TCollection_AsciiString (JsonKeyToString (Standard_JsonKey_Quote))
+ aName
+ TCollection_AsciiString (JsonKeyToString (Standard_JsonKey_Quote))
+ JsonKeyToString (Standard_JsonKey_SeparatorKeyToValue);
Standard_Boolean aResult = aSubText.StartsWith (aKeyName);
if (aResult)
theStreamPos += aKeyName.Length();
return aResult;
}
//=======================================================================
//function : InitRealValues
//purpose :
//=======================================================================
Standard_Boolean Standard_Dump::InitRealValues (const TCollection_AsciiString& theStreamStr,
Standard_Integer& theStreamPos,
int theCount, ...)
{
Standard_Integer aStreamPos = theStreamPos + JsonKeyLength (Standard_JsonKey_OpenContainer);
TCollection_AsciiString aSubText = theStreamStr.SubString (aStreamPos, theStreamStr.Length());
va_list vl;
va_start(vl, theCount);
aStreamPos = 1;
Standard_Integer aClosePos = aSubText.Location (JsonKeyToString (Standard_JsonKey_CloseContainer), aStreamPos, aSubText.Length());
for(int i = 0; i < theCount; ++i)
{
Standard_Integer aNextPos = (i < theCount-1) ? aSubText.Location (JsonKeyToString (Standard_JsonKey_SeparatorValueToValue), aStreamPos, aSubText.Length())
: aClosePos;
TCollection_AsciiString aValueText = aSubText.SubString (aStreamPos, aNextPos - 1);
if (!aValueText.IsRealValue())
return Standard_False;
Standard_Real aValue = aValueText.RealValue();
*(va_arg(vl, Standard_Real*)) = aValue;
aStreamPos = aNextPos + JsonKeyLength (Standard_JsonKey_SeparatorValueToValue);
}
va_end(vl);
aClosePos = theStreamStr.Location (JsonKeyToString (Standard_JsonKey_CloseContainer), theStreamPos, theStreamStr.Length());
theStreamPos = aClosePos + JsonKeyLength (Standard_JsonKey_CloseContainer);
return Standard_True;
}
//=======================================================================
//function : InitValue
//purpose :
//=======================================================================
Standard_Boolean Standard_Dump::InitValue (const TCollection_AsciiString& theStreamStr,
Standard_Integer& theStreamPos,
TCollection_AsciiString& theValue)
{
Standard_Integer aStreamPos = theStreamPos;
TCollection_AsciiString aSubText = theStreamStr.SubString (aStreamPos, theStreamStr.Length());
aStreamPos = 1;
Standard_Integer aNextPos = aSubText.Location (JsonKeyToString (Standard_JsonKey_SeparatorValueToValue), aStreamPos, aSubText.Length());
Standard_JsonKey aNextKey = Standard_JsonKey_SeparatorValueToValue;
Standard_Integer aCloseChildPos = aSubText.Location (JsonKeyToString (Standard_JsonKey_CloseChild), aStreamPos, aSubText.Length());
Standard_Boolean isUseClosePos = (aNextPos > 0 && aCloseChildPos > 0 && aCloseChildPos < aNextPos) || !aNextPos;
if (isUseClosePos)
{
aNextPos = aCloseChildPos;
aNextKey = Standard_JsonKey_CloseChild;
}
theValue = aNextPos ? aSubText.SubString (aStreamPos, aNextPos - 1) : aSubText;
theStreamPos = aNextPos ? (theStreamPos + (aNextPos - aStreamPos) + JsonKeyLength (aNextKey)) : theStreamStr.Length();
return Standard_True;
}
// =======================================================================
// function : GetPointerInfo
// purpose :

View File

@@ -77,6 +77,38 @@
theOStream << "\"" << aName << "\": " << theField; \
}
//! @def OCCT_INIT_FIELD_VALUE_REAL
//! 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 OCCT_DUMP_CLASS_BEGIN call, but pay attention that it should be only one row in the object dump.
#define OCCT_INIT_FIELD_VALUE_REAL(theOStream, theStreamPos, theField) \
{ \
Standard_Integer aStreamPos = theStreamPos; \
if (!Standard_Dump::ProcessFieldName (theOStream, #theField, aStreamPos)) \
return Standard_False; \
TCollection_AsciiString aValueText; \
if (!Standard_Dump::InitValue (theOStream, aStreamPos, aValueText) || !aValueText.IsRealValue()) \
return Standard_False; \
theField = aValueText.RealValue(); \
theStreamPos = aStreamPos; \
}
//! @def OCCT_INIT_FIELD_VALUE_NUMERICAL
//! 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 OCCT_DUMP_CLASS_BEGIN call, but pay attention that it should be only one row in the object dump.
#define OCCT_INIT_FIELD_VALUE_INTEGER(theOStream, theStreamPos, theField) \
{ \
Standard_Integer aStreamPos = theStreamPos; \
if (!Standard_Dump::ProcessFieldName (theOStream, #theField, aStreamPos)) \
return Standard_False; \
TCollection_AsciiString aValueText; \
if (!Standard_Dump::InitValue (theOStream, aStreamPos, aValueText) || !aValueText.IsIntegerValue()) \
return Standard_False; \
theField = aValueText.IntegerValue(); \
theStreamPos = aStreamPos; \
}
//! @def OCCT_DUMP_FIELD_VALUE_STRING
//! Append into output value: "Name": "Field"
#define OCCT_DUMP_FIELD_VALUE_STRING(theOStream, theField) \
@@ -123,6 +155,18 @@
} \
}
//! @def OCCT_INIT_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 OCCT_INIT_FIELD_VALUES_DUMPED(theSStream, theStreamPos, theField) \
{ \
if ((theField) == NULL || !(theField)->InitFromJson (theSStream, theStreamPos)) \
return Standard_False; \
}
//! @def OCCT_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.
@@ -172,6 +216,20 @@
theOStream << "]"; \
}
//! @def OCCT_INIT_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 OCCT_DUMP_CLASS_BEGIN call, but pay attention that it should be only one row in the object dump.
#define OCCT_INIT_VECTOR_CLASS(theOStream, theName, theStreamPos, theCount, ...) \
{ \
Standard_Integer aStreamPos = theStreamPos; \
if (!Standard_Dump::ProcessStreamName (theOStream, theName, aStreamPos)) \
return Standard_False; \
if (!Standard_Dump::InitRealValues (theOStream, aStreamPos, theCount, __VA_ARGS__)) \
return Standard_False; \
theStreamPos = aStreamPos; \
}
//! Kind of key in Json string
enum Standard_JsonKey
{
@@ -271,14 +329,46 @@ public:
//! 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
//! @param theCount [in] number 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
//! @param theCount [in] number of values
Standard_EXPORT static void DumpRealValues (Standard_OStream& theOStream, int theCount, ...);
//! Check whether the parameter name is equal to the name in the stream at position
//! @param theSStream [in] stream with values
//! @param theName [in] stream key value
//! @param theStreamPos [out] current position in the stream
Standard_EXPORT static Standard_Boolean ProcessStreamName (const TCollection_AsciiString& theStreamStr,
const TCollection_AsciiString& theName,
Standard_Integer& theStreamPos);
//! Check whether the field name is equal to the name in the stream at position
//! @param theSStream [in] stream with values
//! @param theName [in] stream key field value
//! @param theStreamPos [out] current position in the stream
Standard_EXPORT static Standard_Boolean ProcessFieldName (const TCollection_AsciiString& theStreamStr,
const TCollection_AsciiString& theName,
Standard_Integer& theStreamPos);
//! Unite values in one value using template: value_1, value_2, ..., value_n
//! @param theSStream [in] stream with values
//! @param theStreamPos [out] current position in the stream
//! @param theCount [in] number of values
Standard_EXPORT static Standard_Boolean InitRealValues (const TCollection_AsciiString& theStreamStr,
Standard_Integer& theStreamPos,
int theCount, ...);
//! Returns real value
//! @param theSStream [in] stream with values
//! @param theStreamPos [out] current position in the stream
//! @param theValue [out] stream value
Standard_EXPORT static Standard_Boolean InitValue (const TCollection_AsciiString& theStreamStr,
Standard_Integer& theStreamPos,
TCollection_AsciiString& theValue);
//! 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