From 8e1e79f052958a3d7137aeed1f3c438fa99fa08a Mon Sep 17 00:00:00 2001 From: vro Date: Thu, 16 Oct 2014 15:01:33 +0400 Subject: [PATCH] 0025317: Failure on attempt to save an Ocaf document with a long double array attribute in a Xml file A draw-command SetRealArrayValue. It is necessary to reproduce the crash. A fix + some additional draw-commands Test cases for issue CR25317 --- src/DDataStd/DDataStd_BasicCommands.cxx | 586 ++++++++++++++++-- .../XmlLDrivers_DocumentStorageDriver.cxx | 3 + .../XmlMDataStd_RealArrayDriver.cxx | 27 +- tests/bugs/caf/bug25317 | 35 ++ 4 files changed, 589 insertions(+), 62 deletions(-) create mode 100755 tests/bugs/caf/bug25317 diff --git a/src/DDataStd/DDataStd_BasicCommands.cxx b/src/DDataStd/DDataStd_BasicCommands.cxx index 01eaaa7821..ad7a79b02d 100644 --- a/src/DDataStd/DDataStd_BasicCommands.cxx +++ b/src/DDataStd/DDataStd_BasicCommands.cxx @@ -426,11 +426,9 @@ static Standard_Integer DDataStd_GetUAttribute (Draw_Interpretor& di, //function : SetIntArray (DF, entry , isDelta, From, To, elmt1, elmt2, ... //======================================================================= static Standard_Integer DDataStd_SetIntArray (Draw_Interpretor& di, - Standard_Integer, + Standard_Integer nb, const char** arg) -{ - - +{ Handle(TDF_Data) DF; if (!DDF::GetDF(arg[1],DF)) return 1; TDF_Label label; @@ -440,15 +438,49 @@ static Standard_Integer DDataStd_SetIntArray (Draw_Interpretor& di, di << "Array of Standard_Integer with bounds from = " << From << " to = " << To << "\n"; Handle(TDataStd_IntegerArray) A = TDataStd_IntegerArray::Set(label, From, To, isDelta); - j = 6; - for(Standard_Integer i = From; i<=To; i++) { - A->SetValue(i, Draw::Atoi(arg[j]) ); - j++; + if (nb > 6) { + j = 6; + for(Standard_Integer i = From; i<=To; i++) { + A->SetValue(i, Draw::Atoi(arg[j]) ); + j++; + } } return 0; } +//======================================================================= +//function : SetIntArrayValue (DF, entry, index, value) +//======================================================================= +static Standard_Integer DDataStd_SetIntArrayValue (Draw_Interpretor&, + Standard_Integer, + const char** arg) +{ + // Get document. + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1], DF)) + return 1; + + // Get label. + TDF_Label label; + if (!DDF::AddLabel(DF, arg[2], label)) + return 1; + + // Get index and value. + Standard_Integer index = Draw::Atoi(arg[3]); + Standard_Integer value = Draw::Atoi(arg[4]); + + // Set new value. + Handle(TDataStd_IntegerArray) arr; + if (label.FindAttribute(TDataStd_IntegerArray::GetID(), arr)) + { + arr->SetValue(index, value); + return 0; + } + + return 1; +} + //======================================================================= //function : GetIntArray (DF, entry ) //======================================================================= @@ -481,7 +513,41 @@ static Standard_Integer DDataStd_GetIntArray (Draw_Interpretor& di, di<<"\n"; return 0; } -// + +//======================================================================= +//function : GetIntArrayValue (DF, entry, index) +//======================================================================= +static Standard_Integer DDataStd_GetIntArrayValue (Draw_Interpretor& di, + Standard_Integer, + const char** arg) +{ + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1],DF)) + return 1; + + TDF_Label label; + if (!DDF::FindLabel(DF, arg[2], label)) { + di << "No label for entry" << "\n"; + return 1; + } + + Handle(TDataStd_IntegerArray) A; + if ( !label.FindAttribute(TDataStd_IntegerArray::GetID(), A) ) { + di << "There is no TDataStd_IntegerArray under label" << "\n"; + return 1; + } + + Standard_Integer index = Draw::Atoi(arg[3]); + if (index < A->Lower() || index > A->Upper()) { + di << "Index is out of range" << "\n"; + return 1; + } else { + di << A->Value(index) << "\n"; + } + + return 0; +} + //======================================================================= //function : ChangeIntArray (DF, entry, indx, val ) //======================================================================= @@ -572,7 +638,7 @@ static Standard_Integer DDataStd_SetIntArrayTest (Draw_Interpretor& di, //function : SetRealArray (DF, entry , isDelta, From, To, elmt1, elmt2, ... //======================================================================= static Standard_Integer DDataStd_SetRealArray (Draw_Interpretor& di, - Standard_Integer, + Standard_Integer nb, const char** arg) { @@ -587,15 +653,49 @@ static Standard_Integer DDataStd_SetRealArray (Draw_Interpretor& di, di << " Array of Standard_Real with bounds from = " << From << " to = " << To << "\n"; Handle(TDataStd_RealArray) A = TDataStd_RealArray::Set(label, From, To, isDelta); - j = 6; - for(Standard_Integer i = From; i<=To; i++) { - A->SetValue(i, Draw::Atof(arg[j]) ); - j++; + if (nb > 6) { + j = 6; + for(Standard_Integer i = From; i<=To; i++) { + A->SetValue(i, Draw::Atof(arg[j]) ); + j++; + } } return 0; } +//======================================================================= +//function : SetRealArrayValue (DF, entry, index value) +//======================================================================= +static Standard_Integer DDataStd_SetRealArrayValue (Draw_Interpretor&, + Standard_Integer, + const char** arg) +{ + // Get document. + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1], DF)) + return 1; + + // Get label. + TDF_Label label; + if (!DDF::AddLabel(DF, arg[2], label)) + return 1; + + // Get index and value. + Standard_Integer index = Draw::Atoi(arg[3]); + Standard_Real value = Draw::Atof(arg[4]); + + // Set new value. + Handle(TDataStd_RealArray) realArray; + if (label.FindAttribute(TDataStd_RealArray::GetID(), realArray)) + { + realArray->SetValue(index, value); + return 0; + } + + return 1; +} + //======================================================================= //function : GetRealArray (DF, entry ) //======================================================================= @@ -629,7 +729,40 @@ static Standard_Integer DDataStd_GetRealArray (Draw_Interpretor& di, return 0; } -// +//======================================================================= +//function : GetRealArrayValue (DF, entry, index) +//======================================================================= +static Standard_Integer DDataStd_GetRealArrayValue (Draw_Interpretor& di, + Standard_Integer, + const char** arg) +{ + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1],DF)) + return 1; + + TDF_Label label; + if (!DDF::FindLabel(DF, arg[2], label)) { + di << "No label for entry" << "\n"; + return 1; + } + + Handle(TDataStd_RealArray) A; + if ( !label.FindAttribute(TDataStd_RealArray::GetID(), A) ) { + di << "There is no TDataStd_RealArray under label" << "\n"; + return 1; + } + + Standard_Integer index = Draw::Atoi(arg[3]); + if (index < A->Lower() || index > A->Upper()) { + di << "Index is out of range" << "\n"; + return 1; + } else { + di << A->Value(index) << "\n"; + } + + return 0; +} + //======================================================================= //function : ChangeRealArray (DF, entry, indx, val ) //======================================================================= @@ -899,11 +1032,9 @@ static Standard_Integer DDataStd_GetFunction (Draw_Interpretor& di, //function : SetExtStringArray (DF, entry , isDelta, From, To, elmt1, elmt2, ... //======================================================================= static Standard_Integer DDataStd_SetExtStringArray (Draw_Interpretor& di, - Standard_Integer, - const char** arg) + Standard_Integer nb, + const char** arg) { - - Handle(TDF_Data) DF; if (!DDF::GetDF(arg[1],DF)) return 1; TDF_Label label; @@ -914,15 +1045,48 @@ static Standard_Integer DDataStd_SetExtStringArray (Draw_Interpretor& di, di << "Array of ExtString with bounds from = " << From << " to = " << To << "\n"; Handle(TDataStd_ExtStringArray) A = TDataStd_ExtStringArray::Set(label, From, To, isDelta); - j = 6; - for(Standard_Integer i = From; i<=To; i++) { - A->SetValue(i, arg[j] ); - j++; + if (nb > 6) { + j = 6; + for(Standard_Integer i = From; i<=To; i++) { + A->SetValue(i, arg[j] ); + j++; + } } return 0; } +//======================================================================= +//function : SetExtStringArrayValue (DF, entry, index, value) +//======================================================================= +static Standard_Integer DDataStd_SetExtStringArrayValue (Draw_Interpretor&, + Standard_Integer, + const char** arg) +{ + // Get document. + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1], DF)) + return 1; + + // Get label. + TDF_Label label; + if (!DDF::AddLabel(DF, arg[2], label)) + return 1; + + // Get index and value. + Standard_Integer index = Draw::Atoi(arg[3]); + + // Set new value. + Handle(TDataStd_ExtStringArray) arr; + if (label.FindAttribute(TDataStd_ExtStringArray::GetID(), arr)) + { + arr->SetValue(index, arg[4]); + return 0; + } + + return 1; +} + //======================================================================= //function : GetExtStringArray (DF, entry ) //======================================================================= @@ -956,6 +1120,41 @@ static Standard_Integer DDataStd_GetExtStringArray (Draw_Interpretor& di, return 0; } +//======================================================================= +//function : GetExtStringArrayValue (DF, entry, index) +//======================================================================= +static Standard_Integer DDataStd_GetExtStringArrayValue (Draw_Interpretor& di, + Standard_Integer, + const char** arg) +{ + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1],DF)) + return 1; + + TDF_Label label; + if (!DDF::FindLabel(DF, arg[2], label)) { + di << "No label for entry" << "\n"; + return 1; + } + + Handle(TDataStd_ExtStringArray) A; + if ( !label.FindAttribute(TDataStd_ExtStringArray::GetID(), A) ) { + di << "There is no TDataStd_ExtStringArray under label" << "\n"; + return 1; + } + + Standard_Integer index = Draw::Atoi(arg[3]); + if (index < A->Lower() || index > A->Upper()) { + di << "Index is out of range" << "\n"; + return 1; + } else { + const TCollection_ExtendedString& value = A->Value(index); + di << value << "\n"; + } + + return 0; +} + //======================================================================= //function : ChangeExtStrArray (DF, entry, indx, val ) //======================================================================= @@ -1132,26 +1331,27 @@ static Standard_Integer DDataStd_SetByteArray (Draw_Interpretor& di, Standard_Integer nb, const char** arg) { - - if (nb > 6) { + if (nb >= 6) { Handle(TDF_Data) DF; if (!DDF::GetDF(arg[1],DF)) return 1; TDF_Label label; DDF::AddLabel(DF, arg[2], label); Standard_Integer isDelta = Draw::Atoi(arg[3]); Standard_Integer From = Draw::Atoi(arg[4]), To = Draw::Atoi( arg[5] ), j; - di << "Array of Standard_Integer with bounds from = " << From << " to = " << To << "\n"; + di << "Array of Standard_Byte with bounds from = " << From << " to = " << To << "\n"; Handle(TDataStd_ByteArray) A = TDataStd_ByteArray::Set(label, From, To, isDelta); - j = 6; - for(Standard_Integer i = From; i<=To; ++i) { - Standard_Integer ival = Draw::Atoi(arg[j]); - if(ival < 0 || 255 < ival) { - cout << "Bad value = " << ival<< endl; - return 1; + if (nb > 6) { + j = 6; + for(Standard_Integer i = From; i<=To; ++i) { + Standard_Integer ival = Draw::Atoi(arg[j]); + if(ival < 0 || 255 < ival) { + cout << "Bad value = " << ival<< endl; + return 1; + } + A->SetValue(i, (Standard_Byte)ival); + j++; } - A->SetValue(i, (Standard_Byte)ival); - j++; } return 0; } @@ -1159,6 +1359,44 @@ static Standard_Integer DDataStd_SetByteArray (Draw_Interpretor& di, return 1; } +//======================================================================= +//function : SetByteArrayValue (DF, entry, index, value) +//======================================================================= +static Standard_Integer DDataStd_SetByteArrayValue (Draw_Interpretor&, + Standard_Integer, + const char** arg) +{ + // Get document. + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1], DF)) + return 1; + + // Get label. + TDF_Label label; + if (!DDF::AddLabel(DF, arg[2], label)) + return 1; + + // Get index and value. + Standard_Integer index = Draw::Atoi(arg[3]); + Standard_Integer value = Draw::Atoi(arg[4]); + + // Check the value. + if(value < 0 || 255 < value) { + cout << "Bad value = " << value << endl; + return 1; + } + + // Set new value. + Handle(TDataStd_ByteArray) arr; + if (label.FindAttribute(TDataStd_ByteArray::GetID(), arr)) + { + arr->SetValue(index, (Standard_Byte) value); + return 0; + } + + return 1; +} + //======================================================================= //function : SetBooleanArray (DF, entry, isDelta, From, To, elmt1, elmt2, ... ) //======================================================================= @@ -1166,7 +1404,7 @@ static Standard_Integer DDataStd_SetBooleanArray (Draw_Interpretor& di, Standard_Integer nb, const char** arg) { - if (nb > 6) + if (nb >= 6) { Handle(TDF_Data) DF; if (!DDF::GetDF(arg[1],DF)) @@ -1178,17 +1416,19 @@ static Standard_Integer DDataStd_SetBooleanArray (Draw_Interpretor& di, di << "Array of Standard_Boolean with bounds from = " << From << " to = " << To << "\n"; Handle(TDataStd_BooleanArray) A = TDataStd_BooleanArray::Set(label, From, To); - j = 6; - for(Standard_Integer i = From; i<=To; i++) - { - Standard_Integer ival = Draw::Atoi(arg[j]); - if(ival > 1) + if (nb > 6) { + j = 6; + for(Standard_Integer i = From; i<=To; i++) { - cout << "Bad value = " << ival<< ". 0 or 1 is expected." << endl; - return 1; + Standard_Integer ival = Draw::Atoi(arg[j]); + if(ival > 1) + { + cout << "Bad value = " << ival<< ". 0 or 1 is expected." << endl; + return 1; + } + A->SetValue(i, (Standard_Boolean)ival); + j++; } - A->SetValue(i, (Standard_Boolean)ival); - j++; } return 0; } @@ -1196,6 +1436,44 @@ static Standard_Integer DDataStd_SetBooleanArray (Draw_Interpretor& di, return 1; } +//======================================================================= +//function : SetBooleanArrayValue (DF, entry, index, value) +//======================================================================= +static Standard_Integer DDataStd_SetBooleanArrayValue (Draw_Interpretor& di, + Standard_Integer, + const char** arg) +{ + // Get document. + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1], DF)) + return 1; + + // Get label. + TDF_Label label; + if (!DDF::AddLabel(DF, arg[2], label)) + return 1; + + // Get index and value. + Standard_Integer index = Draw::Atoi(arg[3]); + Standard_Integer value = Draw::Atoi(arg[4]); + + // Check the value. + if (value != 0 && value != 1) { + di << "DDataStd_SetBooleanArrayValue: Error! The value should be either 0 or 1." << "\n"; + return 1; + } + + // Set new value. + Handle(TDataStd_BooleanArray) arr; + if (label.FindAttribute(TDataStd_BooleanArray::GetID(), arr)) + { + arr->SetValue(index, (Standard_Boolean) value); + return 0; + } + + return 1; +} + //======================================================================= //function : SetBooleanList (DF, entry, elmt1, elmt2, ... ) //======================================================================= @@ -1315,6 +1593,40 @@ static Standard_Integer DDataStd_GetByteArray (Draw_Interpretor& di, return 0; } +//======================================================================= +//function : GetByteArrayValue (DF, entry, index) +//======================================================================= +static Standard_Integer DDataStd_GetByteArrayValue (Draw_Interpretor& di, + Standard_Integer, + const char** arg) +{ + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1],DF)) + return 1; + + TDF_Label label; + if (!DDF::FindLabel(DF, arg[2], label)) { + di << "No label for entry" << "\n"; + return 1; + } + + Handle(TDataStd_ByteArray) A; + if ( !label.FindAttribute(TDataStd_ByteArray::GetID(), A) ) { + di << "There is no TDataStd_ByteArray under label" << "\n"; + return 1; + } + + Standard_Integer index = Draw::Atoi(arg[3]); + if (index < A->Lower() || index > A->Upper()) { + di << "Index is out of range" << "\n"; + return 1; + } else { + di << A->Value(index) << "\n"; + } + + return 0; +} + //======================================================================= //function : GetBooleanArray (DF, entry ) //======================================================================= @@ -1350,6 +1662,40 @@ static Standard_Integer DDataStd_GetBooleanArray (Draw_Interpretor& di, return 0; } +//======================================================================= +//function : GetBooleanArrayValue (DF, entry, index) +//======================================================================= +static Standard_Integer DDataStd_GetBooleanArrayValue (Draw_Interpretor& di, + Standard_Integer, + const char** arg) +{ + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1],DF)) + return 1; + + TDF_Label label; + if (!DDF::FindLabel(DF, arg[2], label)) { + di << "No label for entry" << "\n"; + return 1; + } + + Handle(TDataStd_BooleanArray) A; + if ( !label.FindAttribute(TDataStd_BooleanArray::GetID(), A) ) { + di << "There is no TDataStd_BooleanArray under label" << "\n"; + return 1; + } + + Standard_Integer index = Draw::Atoi(arg[3]); + if (index < A->Lower() || index > A->Upper()) { + di << "Index is out of range" << "\n"; + return 1; + } else { + di << ((A->Value(index) == Standard_True) ? "True" : "False") << "\n"; + } + + return 0; +} + //======================================================================= //function : ChangeByteArray (DF, entry, indx, val ) //======================================================================= @@ -2593,10 +2939,9 @@ static Standard_Integer DDataStd_GetNDRealArray (Draw_Interpretor& di, //function : SetRefArray (DF, entry , From, To, elmt1, elmt2, ... //======================================================================= static Standard_Integer DDataStd_SetRefArray (Draw_Interpretor& di, - Standard_Integer, - const char** arg) -{ - + Standard_Integer nb, + const char** arg) +{ Handle(TDF_Data) DF; if (!DDF::GetDF(arg[1],DF)) return 1; TDF_Label label; @@ -2607,15 +2952,51 @@ static Standard_Integer DDataStd_SetRefArray (Draw_Interpretor& di, Handle(TDataStd_ReferenceArray) A = TDataStd_ReferenceArray::Set(label, From, To); - j = 5; - for(Standard_Integer i = From; i<=To; i++) { - TDF_Label aRefLabel; - DDF::AddLabel(DF, arg[j], aRefLabel); - A->SetValue(i, aRefLabel); - j++; + if (nb > 6) { + j = 5; + for(Standard_Integer i = From; i<=To; i++) { + TDF_Label aRefLabel; + DDF::AddLabel(DF, arg[j], aRefLabel); + A->SetValue(i, aRefLabel); + j++; + } } return 0; } + +//======================================================================= +//function : SetRefArrayValue (DF, entry, index, value) +//======================================================================= +static Standard_Integer DDataStd_SetRefArrayValue (Draw_Interpretor&, + Standard_Integer, + const char** arg) +{ + // Get document. + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1], DF)) + return 1; + + // Get label. + TDF_Label label; + if (!DDF::AddLabel(DF, arg[2], label)) + return 1; + + // Get index and value. + Standard_Integer index = Draw::Atoi(arg[3]); + + // Set new value. + Handle(TDataStd_ReferenceArray) arr; + if (label.FindAttribute(TDataStd_ReferenceArray::GetID(), arr)) + { + TDF_Label aRefLabel; + DDF::AddLabel(DF, arg[4], aRefLabel); + arr->SetValue(index, aRefLabel); + return 0; + } + + return 1; +} + //======================================================================= //function : GetRefArray (DF, entry ) //======================================================================= @@ -2650,6 +3031,43 @@ static Standard_Integer DDataStd_GetRefArray (Draw_Interpretor& di, return 0; } +//======================================================================= +//function : GetRefArrayValue (DF, entry, index) +//======================================================================= +static Standard_Integer DDataStd_GetRefArrayValue (Draw_Interpretor& di, + Standard_Integer, + const char** arg) +{ + Handle(TDF_Data) DF; + if (!DDF::GetDF(arg[1],DF)) + return 1; + + TDF_Label label; + if (!DDF::FindLabel(DF, arg[2], label)) { + di << "No label for entry" << "\n"; + return 1; + } + + Handle(TDataStd_ReferenceArray) A; + if ( !label.FindAttribute(TDataStd_ReferenceArray::GetID(), A) ) { + di << "There is no TDataStd_ReferenceArray under label" << "\n"; + return 1; + } + + Standard_Integer index = Draw::Atoi(arg[3]); + if (index < A->Lower() || index > A->Upper()) { + di << "Index is out of range" << "\n"; + return 1; + } else { + const TDF_Label& value = A->Value(index); + TCollection_AsciiString entry; + TDF_Tool::Entry(value, entry); + di << entry.ToCString() << "\n"; + } + + return 0; +} + //======================================================================= //function : BasicCommands //purpose : @@ -2672,29 +3090,49 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands) __FILE__, DDataStd_SetInteger, g); theCommands.Add ("SetIntArray", - "SetIntArray (DF, entry, isDelta, From, To, elmt1, elmt2, ... )", + "SetIntArray (DF, entry, isDelta, From, To, [elmt1, elmt2, ...])", __FILE__, DDataStd_SetIntArray, g); + + theCommands.Add ("SetIntArrayValue", + "SetIntArrayValue (DF, entry, index, value)", + __FILE__, DDataStd_SetIntArrayValue, g); theCommands.Add ("SetReal", "SetReal (DF, entry, value)", __FILE__, DDataStd_SetReal, g); theCommands.Add ("SetRealArray", - "SetRealArray (DF, entry, isDelta, From, To, elmt1, elmt2, ... )", + "SetRealArray (DF, entry, isDelta, From, To, [elmt1, elmt2, ...])", __FILE__, DDataStd_SetRealArray, g); + theCommands.Add ("SetRealArrayValue", + "SetRealArrayValue (DF, entry, index, value)", + __FILE__, DDataStd_SetRealArrayValue, g); + theCommands.Add ("SetByteArray", - "SetByteArray (DF, entry, isDelta, From, To, elmt1, elmt2, ... )", + "SetByteArray (DF, entry, isDelta, From, To, [elmt1, elmt2, ...])", __FILE__, DDataStd_SetByteArray, g); + theCommands.Add ("SetByteArrayValue", + "SetByteArrayValue (DF, entry, index, value)", + __FILE__, DDataStd_SetByteArrayValue, g); + theCommands.Add ("SetExtStringArray", - "SetExtStringArray (DF, entry, isDelta, From, To, elmt1, elmt2, ... )", + "SetExtStringArray (DF, entry, isDelta, From, To, [elmt1, elmt2, ...])", __FILE__, DDataStd_SetExtStringArray, g); + theCommands.Add ("SetExtStringArrayValue", + "SetExtStringArrayValue (DF, entry, index, value)", + __FILE__, DDataStd_SetExtStringArrayValue, g); + theCommands.Add ("SetRefArray", - "SetRefArray (DF, entry, From, To, lab1, lab2,.. )", + "SetRefArray (DF, entry, From, To, [lab1, lab2, ...])", __FILE__, DDataStd_SetRefArray, g); + theCommands.Add ("SetRefArrayValue", + "SetRefArrayValue (DF, entry, index, value)", + __FILE__, DDataStd_SetRefArrayValue, g); + theCommands.Add ("SetIntPackedMap", "SetIntPackedMap (DF, entry, isDelta, key1, key2, ... )", __FILE__, DDataStd_SetIntPackedMap, g); @@ -2720,9 +3158,13 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands) __FILE__, DDataStd_SetAsciiString, g); theCommands.Add ("SetBooleanArray", - "SetBooleanArray (DF, entry, isDelta, From, To, elmt1, elmt2, ... )", + "SetBooleanArray (DF, entry, isDelta, From, To, [elmt1, elmt2, ...])", __FILE__, DDataStd_SetBooleanArray, g); + theCommands.Add ("SetBooleanArrayValue", + "SetBooleanArrayValue (DF, entry, index, value)", + __FILE__, DDataStd_SetBooleanArrayValue, g); + theCommands.Add ("SetBooleanList", "SetBooleanList (DF, entry, elmt1, elmt2, ... )", __FILE__, DDataStd_SetBooleanList, g); @@ -2750,22 +3192,42 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands) "GetIntArray (DF, entry )", __FILE__, DDataStd_GetIntArray, g); + theCommands.Add ("GetIntArrayValue", + "GetIntArrayValue (DF, entry, index)", + __FILE__, DDataStd_GetIntArrayValue, g); + theCommands.Add ("GetRealArray", "GetRealArray (DF, entry )", __FILE__, DDataStd_GetRealArray, g); + theCommands.Add ("GetRealArrayValue", + "GetRealArrayValue (DF, entry, index)", + __FILE__, DDataStd_GetRealArrayValue, g); + theCommands.Add ("GetByteArray", "GetByteArray (DF, entry )", __FILE__, DDataStd_GetByteArray, g); + theCommands.Add ("GetByteArrayValue", + "GetByteArrayValue (DF, entry, index)", + __FILE__, DDataStd_GetByteArrayValue, g); + theCommands.Add ("GetExtStringArray", "GetExtStringArray (DF, entry )", __FILE__, DDataStd_GetExtStringArray, g); + theCommands.Add ("GetExtStringArrayValue", + "GetExtStringArrayValue (DF, entry, index)", + __FILE__, DDataStd_GetExtStringArrayValue, g); + theCommands.Add ("GetRefArray", "GetRefArray (DF, entry )", __FILE__, DDataStd_GetRefArray, g); + theCommands.Add ("GetRefArrayValue", + "GetRefArrayValue (DF, entry, index)", + __FILE__, DDataStd_GetRefArrayValue, g); + theCommands.Add ("GetIntPackedMap", "GetIntPackedMap (DF, entry )", __FILE__, DDataStd_GetIntPackedMap, g); @@ -2807,6 +3269,10 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands) "GetBooleanArray (DF, entry )", __FILE__, DDataStd_GetBooleanArray, g); + theCommands.Add ("GetBooleanArrayValue", + "GetBooleanArrayValue (DF, entry, index)", + __FILE__, DDataStd_GetBooleanArrayValue, g); + theCommands.Add ("GetBooleanList", "GetBooleanList (DF, entry )", __FILE__, DDataStd_GetBooleanList, g); diff --git a/src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx b/src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx index 6af87ac159..dba87c7045 100644 --- a/src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx +++ b/src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx @@ -127,6 +127,7 @@ void XmlLDrivers_DocumentStorageDriver::Write }else{ SetIsError (Standard_True); + SetStoreStatus(PCDM_SS_WriteFailure); TCollection_ExtendedString aMsg = TCollection_ExtendedString("Error: the file ") + aFileName + " cannot be opened for writing"; @@ -295,12 +296,14 @@ Standard_Boolean XmlLDrivers_DocumentStorageDriver::WriteToDomDocument catch (Standard_Failure) { SetIsError (Standard_True); + SetStoreStatus(PCDM_SS_Failure); TCollection_ExtendedString anErrorString (Standard_Failure::Caught()->GetMessageString()); aMessageDriver -> Write (anErrorString.ToExtString()); } } if (anObjNb <= 0 && IsError() == Standard_False) { SetIsError (Standard_True); + SetStoreStatus(PCDM_SS_No_Obj); TCollection_ExtendedString anErrorString ("error occurred"); aMessageDriver -> Write (anErrorString.ToExtString()); } diff --git a/src/XmlMDataStd/XmlMDataStd_RealArrayDriver.cxx b/src/XmlMDataStd/XmlMDataStd_RealArrayDriver.cxx index 782d7ba2f3..7465afa297 100644 --- a/src/XmlMDataStd/XmlMDataStd_RealArrayDriver.cxx +++ b/src/XmlMDataStd/XmlMDataStd_RealArrayDriver.cxx @@ -22,6 +22,8 @@ #include #include #include +#include +#include IMPLEMENT_DOMSTRING (FirstIndexString, "first") IMPLEMENT_DOMSTRING (LastIndexString, "last") @@ -167,8 +169,29 @@ void XmlMDataStd_RealArrayDriver::Paste (const Handle(TDF_Attribute)& theSource, Standard_Integer iChar = 0; NCollection_LocalArray str; if (realArray.Length()) - str.Allocate(25 * realArray.Length() + 1); - + { + try + { + OCC_CATCH_SIGNALS + str.Allocate(25 * realArray.Length() + 1); + } + catch (Standard_OutOfMemory) + { + // If allocation of big space for the string of double array values failed, + // try to calculate the necessary space more accurate and allocate it. + // It may take some time... therefore it was not done initially and + // an attempt to use a simple 25 chars for a double value was used. + Standard_Character buf[25]; + Standard_Integer i(aL), nbChars(0); + while (i <= anU) + { + nbChars += Sprintf(buf, "%.17g ", realArray.Value(i++)) + 1/*a space*/; + } + if (nbChars) + str.Allocate(nbChars); + } + } + Standard_Integer i = aL; for (;;) { diff --git a/tests/bugs/caf/bug25317 b/tests/bugs/caf/bug25317 new file mode 100755 index 0000000000..9d65c44bb9 --- /dev/null +++ b/tests/bugs/caf/bug25317 @@ -0,0 +1,35 @@ +puts "================" +puts "OCC25317" +puts "================" +puts "" +################################################################################################### +# Failure on attempt to save an Ocaf document with a long double array attribute in a Xml file +################################################################################################### + +set i 1 +set nb 50000 + +set FileName $imagedir/${test_image}.xml +file delete ${FileName} +if [file exists ${FileName}] { + puts "Error: There is temporary ${FileName} file" +} + +#Allocate a large array. +NewDocument D XmlOcaf +SetRealArray D 0:1 0 1 $nb + +#Fill-in the large array. +repeat $nb { + SetRealArrayValue D 0:1 $i 1.234 + incr i 1 +} + +#Save the document in XML format. +SaveAs D ${FileName} + +if [file exists ${FileName}] { + puts "OK: There is ${FileName} file" +} else { + puts "Error: There is not ${FileName} file" +} -- 2.20.1