0025317: Failure on attempt to save an Ocaf document with a long double array attribu...
authorvro <vro@opencascade.com>
Thu, 16 Oct 2014 11:01:33 +0000 (15:01 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 16 Oct 2014 11:02:30 +0000 (15:02 +0400)
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
src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx
src/XmlMDataStd/XmlMDataStd_RealArrayDriver.cxx
tests/bugs/caf/bug25317 [new file with mode: 0755]

index 01eaaa7..ad7a79b 100644 (file)
@@ -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,16 +438,50 @@ 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 )
 //=======================================================================
 static Standard_Integer DDataStd_GetIntArray (Draw_Interpretor& di,
@@ -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,16 +653,50 @@ 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 )
 //=======================================================================
 static Standard_Integer DDataStd_GetRealArray (Draw_Interpretor& di,
@@ -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,16 +1045,49 @@ 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 )
 //=======================================================================
 static Standard_Integer DDataStd_GetExtStringArray (Draw_Interpretor& di,
@@ -957,6 +1121,41 @@ static Standard_Integer DDataStd_GetExtStringArray (Draw_Interpretor& di,
 } 
 
 //=======================================================================
+//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 )
 //=======================================================================
 static Standard_Integer DDataStd_ChangeExtStrArray (Draw_Interpretor& di,
@@ -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; 
   }
@@ -1160,13 +1360,51 @@ static Standard_Integer DDataStd_SetByteArray (Draw_Interpretor& di,
 } 
 
 //=======================================================================
+//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, ...  )
 //=======================================================================
 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; 
   }
@@ -1197,6 +1437,44 @@ static Standard_Integer DDataStd_SetBooleanArray (Draw_Interpretor& di,
 } 
 
 //=======================================================================
+//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, ...  )
 //=======================================================================
 static Standard_Integer DDataStd_SetBooleanList (Draw_Interpretor& di,
@@ -1316,6 +1594,40 @@ static Standard_Integer DDataStd_GetByteArray (Draw_Interpretor& di,
 } 
 
 //=======================================================================
+//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 )
 //=======================================================================
 static Standard_Integer DDataStd_GetBooleanArray (Draw_Interpretor& di,
@@ -1351,6 +1663,40 @@ static Standard_Integer DDataStd_GetBooleanArray (Draw_Interpretor& di,
 }
 
 //=======================================================================
+//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 )
 //=======================================================================
 static Standard_Integer DDataStd_ChangeByteArray (Draw_Interpretor& di,
@@ -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 )
 //=======================================================================
@@ -2651,6 +3032,43 @@ static Standard_Integer DDataStd_GetRefArray (Draw_Interpretor& di,
 } 
 
 //=======================================================================
+//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);
index 6af87ac..dba87c7 100644 (file)
@@ -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());
   }
index 782d7ba..7465afa 100644 (file)
@@ -22,6 +22,8 @@
 #include <XmlMDataStd.hxx>
 #include <TColStd_HArray1OfReal.hxx>
 #include <NCollection_LocalArray.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_OutOfMemory.hxx>
 
 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<Standard_Character> 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 (executable)
index 0000000..9d65c44
--- /dev/null
@@ -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"
+}