0023850: TDataStd_ByteArray is too slow on storage on disk
authorvro <vro@opencascade>
Thu, 23 May 2013 08:09:09 +0000 (12:09 +0400)
committervro <vro@opencascade>
Thu, 23 May 2013 08:09:09 +0000 (12:09 +0400)
Optimization of a byte-array for XML persistence (binary persistence is ok).
A possible bug is corrected (size of an array is extended a little).
Same improvement for storage of a TDataStd_TreeNode.
Improvement of speed of storage of several Ocaf attributes in XML file format.
Also, format of storage of a double value is extended to keep 17 digits after a decimal point (it was used only 15 digits before).
Several draw-commands are added to manipulate the basic Ocaf attributes:
BooleanArray
BooleanList
IntegerList
RealList
A test-script for OCAF document successfully saved and opened from disk in XML file format.
+ 1 is added to keep '\0'
Removed several spaces in source files.
PLib_LocalArray is renamed to NCollection_LocalArray and became a template. It is used as a local array for Standard_Character in XML OCAF drivers, and as a local array of Standard_Real in PLib package.
Small correction of test case for this fix

20 files changed:
src/BSplCLib/BSplCLib.cxx
src/BSplSLib/BSplSLib.cxx
src/DDataStd/DDataStd_BasicCommands.cxx
src/NCollection/FILES
src/NCollection/NCollection_LocalArray.hxx [new file with mode: 0644]
src/PLib/FILES
src/PLib/PLib.cxx
src/PLib/PLib_HermitJacobi.cxx
src/PLib/PLib_LocalArray.hxx [deleted file]
src/XmlMDataStd/XmlMDataStd_BooleanArrayDriver.cxx
src/XmlMDataStd/XmlMDataStd_BooleanListDriver.cxx
src/XmlMDataStd/XmlMDataStd_ByteArrayDriver.cxx
src/XmlMDataStd/XmlMDataStd_IntPackedMapDriver.cxx
src/XmlMDataStd/XmlMDataStd_IntegerArrayDriver.cxx
src/XmlMDataStd/XmlMDataStd_IntegerListDriver.cxx
src/XmlMDataStd/XmlMDataStd_RealArrayDriver.cxx
src/XmlMDataStd/XmlMDataStd_RealDriver.cxx
src/XmlMDataStd/XmlMDataStd_RealListDriver.cxx
src/XmlMDataStd/XmlMDataStd_TreeNodeDriver.cxx
tests/caf/bugs/D1 [new file with mode: 0755]

index 97053ae..0e951a7 100755 (executable)
@@ -34,7 +34,7 @@
 
 #include <BSplCLib.ixx>
 #include <PLib.hxx>
-#include <PLib_LocalArray.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <Precision.hxx>
 #include <Standard_NotImplemented.hxx>
 
@@ -67,8 +67,6 @@ public:
   Standard_Real myBuffer[27*27];
 };
 
-typedef PLib_LocalArray BSplCLib_LocalArray;
-
 //=======================================================================
 //function : Hunt
 //purpose  : 
@@ -3226,7 +3224,7 @@ void  BSplCLib::Eval
     if (NewRequest > Degree) {
       NewRequest = Degree ;
     }
-    BSplCLib_LocalArray LocalRealArray((LocalRequest + 1)*ArrayDimension);
+    NCollection_LocalArray<Standard_Real> LocalRealArray((LocalRequest + 1)*ArrayDimension);
     Index = 0 ;
     Inverse = 1.0e0 ;
 
@@ -3421,7 +3419,7 @@ void  BSplCLib::Eval
     if (NewRequest > Degree) {
       NewRequest = Degree ;
     }
-    BSplCLib_LocalArray LocalRealArray((LocalRequest + 1)*ArrayDimension);
+    NCollection_LocalArray<Standard_Real> LocalRealArray((LocalRequest + 1)*ArrayDimension);
 
     Index = 0 ;
     Inverse = 1.0e0 ;
index 0a39cee..36d0638 100755 (executable)
@@ -28,7 +28,7 @@
 
 #include <BSplSLib.ixx>
 #include <PLib.hxx>
-#include <PLib_LocalArray.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <BSplCLib.hxx>
 #include <TColgp_Array2OfXYZ.hxx>
 #include <TColgp_Array1OfXYZ.hxx>
@@ -64,8 +64,6 @@ struct BSplSLib_DataContainer
   Standard_Real ders[48];
 };
 
-typedef PLib_LocalArray BSplSLib_LocalArray;
-
 //**************************************************************************
 //                     Evaluation methods
 //**************************************************************************
@@ -141,9 +139,9 @@ void  BSplSLib::RationalDerivative(const Standard_Integer UDeg,
   M3 = (M1 << 1) + M1;
   M4 = (VDeg + 1) << 2;
   
-  BSplSLib_LocalArray StoreDerivatives (All ? 0 : ii * 3);
+  NCollection_LocalArray<Standard_Real> StoreDerivatives (All ? 0 : ii * 3);
   Standard_Real *RArray = (All ? &RDerivatives : (Standard_Real*)StoreDerivatives);
-  BSplSLib_LocalArray StoreW (ii);  
+  NCollection_LocalArray<Standard_Real> StoreW (ii);  
   Standard_Real *HomogeneousArray = &HDerivatives; 
   Standard_Real denominator,Pii,Pip,Pjq;
   
@@ -1314,7 +1312,7 @@ void  BSplSLib::Iso(const Standard_Real            Param,
   
   // compute local knots
   
-  BSplSLib_LocalArray locknots1 (2*Degree);  
+  NCollection_LocalArray<Standard_Real> locknots1 (2*Degree);  
   BSplCLib::LocateParameter(Degree,Knots,Mults,u,Periodic,index,u);
   BSplCLib::BuildKnots(Degree,index,Periodic,Knots,Mults,*locknots1);
   if (&Mults == NULL)
@@ -1341,7 +1339,7 @@ void  BSplSLib::Iso(const Standard_Real            Param,
     l2 = Poles.UpperRow();
   }
   
-  BSplSLib_LocalArray locpoles ((Degree+1) * (l2-f2+1) * dim);
+  NCollection_LocalArray<Standard_Real> locpoles ((Degree+1) * (l2-f2+1) * dim);
   
   Standard_Real w, *pole = locpoles;
   index += f1;
@@ -2105,7 +2103,7 @@ void  BSplSLib::CacheD0(const Standard_Real                  UParameter,
     new_parameter[1] = (VParameter - VCacheParameter) / VSpanLenght ; 
     dimension = 3 * (VDegree + 1) ;
   }
-  BSplSLib_LocalArray locpoles(dimension);
+  NCollection_LocalArray<Standard_Real> locpoles(dimension);
   
   PLib::NoDerivativeEvalPolynomial(new_parameter[0],
                       max_degree,
@@ -2263,7 +2261,7 @@ void  BSplSLib::CacheD1(const Standard_Real                  UParameter,
     my_vec_max = (Standard_Real *) &aVecU ;
   }
 
-  BSplSLib_LocalArray locpoles (2 * dimension);
+  NCollection_LocalArray<Standard_Real> locpoles (2 * dimension);
   
   PLib::EvalPolynomial(new_parameter[0],
                       1,
@@ -2527,7 +2525,7 @@ void  BSplSLib::CacheD2(const Standard_Real                  UParameter,
     my_vec_max_max = (Standard_Real *) &aVecUU ;
   }
 
-  BSplSLib_LocalArray locpoles (3 * dimension);
+  NCollection_LocalArray<Standard_Real> locpoles (3 * dimension);
   
   //
   // initialize in case min or max degree are less than 2
index 2be18b8..b2a763c 100755 (executable)
 #include <TDF_Reference.hxx>
 #include <TDataStd_UAttribute.hxx>
 #include <TDataStd_IntegerArray.hxx>
+#include <TDataStd_BooleanArray.hxx>
 #include <TDataStd_RealArray.hxx>
+#include <TDataStd_BooleanList.hxx>
+#include <TDataStd_IntegerList.hxx>
+#include <TDataStd_RealList.hxx>
 #include <TDataStd_Variable.hxx>
 #include <TDataStd_ExtStringArray.hxx>
 #include <TDF_ChildIterator.hxx>
@@ -91,6 +95,9 @@
 #include <TColStd_PackedMapOfInteger.hxx>
 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
 #include <TDataStd_ByteArray.hxx>
+#include <TDataStd_ListIteratorOfListOfByte.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TColStd_ListIteratorOfListOfReal.hxx>
 
 #include <Standard_Macro.hxx>
 #ifdef OptJr
@@ -1166,6 +1173,130 @@ static Standard_Integer DDataStd_SetByteArray (Draw_Interpretor& di,
   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) 
+  {  
+    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_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) 
+      {
+        cout << "Bad value = " << ival<< ". 0 or 1 is expected." << endl;
+        return 1;
+      }
+      A->SetValue(i, (Standard_Boolean)ival); 
+      j++;
+    }
+    return 0; 
+  }
+  di << "DDataStd_SetBooleanArray: Error" << "\n";
+  return 1; 
+} 
+
+//=======================================================================
+//function : SetBooleanList (DF, entry, elmt1, elmt2, ...  )
+//=======================================================================
+static Standard_Integer DDataStd_SetBooleanList (Draw_Interpretor& di,
+                                                 Standard_Integer nb, 
+                                                 const char** arg) 
+{
+  if (nb > 2) 
+  {  
+    Handle(TDF_Data) DF;
+    if (!DDF::GetDF(arg[1],DF))
+        return 1; 
+
+    TDF_Label label;
+    DDF::AddLabel(DF, arg[2], label);
+    Handle(TDataStd_BooleanList) A = TDataStd_BooleanList::Set(label);
+    for(Standard_Integer i = 3; i <= nb - 1; i++) 
+    {
+      Standard_Integer ival = Draw::Atoi(arg[i]);
+      if(ival > 1) 
+      {
+        cout << "Bad value = " << ival<< ". 0 or 1 is expected." << endl;
+        return 1;
+      }
+      A->Append((Standard_Boolean)ival); 
+    }
+    return 0; 
+  }
+  di << "DDataStd_SetBooleanList: Error" << "\n";
+  return 1; 
+} 
+
+//=======================================================================
+//function : SetIntegerList (DF, entry, elmt1, elmt2, ...  )
+//=======================================================================
+static Standard_Integer DDataStd_SetIntegerList (Draw_Interpretor& di,
+                                                 Standard_Integer nb, 
+                                                 const char** arg) 
+{
+  if (nb > 2) 
+  {  
+    Handle(TDF_Data) DF;
+    if (!DDF::GetDF(arg[1],DF))
+        return 1; 
+
+    TDF_Label label;
+    DDF::AddLabel(DF, arg[2], label);
+    Handle(TDataStd_IntegerList) A = TDataStd_IntegerList::Set(label);
+    for(Standard_Integer i = 3; i <= nb - 1; i++) 
+    {
+      Standard_Integer ival = Draw::Atoi(arg[i]);
+      A->Append(ival); 
+    }
+    return 0; 
+  }
+  di << "DDataStd_SetIntegerList: Error" << "\n";
+  return 1; 
+} 
+
+//=======================================================================
+//function : SetRealList (DF, entry, elmt1, elmt2, ...  )
+//=======================================================================
+static Standard_Integer DDataStd_SetRealList (Draw_Interpretor& di,
+                                              Standard_Integer nb, 
+                                              const char** arg) 
+{
+  if (nb > 2) 
+  {  
+    Handle(TDF_Data) DF;
+    if (!DDF::GetDF(arg[1],DF))
+        return 1; 
+
+    TDF_Label label;
+    DDF::AddLabel(DF, arg[2], label);
+    Handle(TDataStd_RealList) A = TDataStd_RealList::Set(label);
+    for(Standard_Integer i = 3; i <= nb - 1; i++) 
+    {
+      Standard_Real fval = Draw::Atof(arg[i]);
+      A->Append(fval); 
+    }
+    return 0; 
+  }
+  di << "DDataStd_SetRealList: Error" << "\n";
+  return 1; 
+} 
+
 //=======================================================================
 //function : GetByteArray (DF, entry )
 //=======================================================================
@@ -1199,6 +1330,41 @@ static Standard_Integer DDataStd_GetByteArray (Draw_Interpretor& di,
   return 0; 
 } 
 
+//=======================================================================
+//function : GetBooleanArray (DF, entry )
+//=======================================================================
+static Standard_Integer DDataStd_GetBooleanArray (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 at label"  << "\n";
+    return 1;
+  }
+  
+  for (Standard_Integer i = A->Lower(); i<=A->Upper(); i++)
+  {
+    di << (Standard_Integer) A->Value(i);
+    if (i < A->Upper())  
+     di << " ";
+  }
+  di << "\n";
+  return 0; 
+}
+
 //=======================================================================
 //function : ChangeByteArray (DF, entry, indx, val )
 //=======================================================================
@@ -1259,6 +1425,112 @@ static Standard_Integer DDataStd_ChangeByteArray (Draw_Interpretor& di,
   di << "DDataStd_ChangeByteArray: Error" << "\n";
   return 1; 
 }
+
+//=======================================================================
+//function : GetBooleanList (DF, entry )
+//=======================================================================
+static Standard_Integer DDataStd_GetBooleanList (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_BooleanList) A;
+  if ( !label.FindAttribute(TDataStd_BooleanList::GetID(), A) ) 
+  {
+    di << "There is no TDataStd_BooleanList at label"  << "\n";
+    return 1;
+  }
+  
+  const TDataStd_ListOfByte& bList = A->List();
+  TDataStd_ListIteratorOfListOfByte itr(bList);
+  for (; itr.More(); itr.Next())
+  {
+    di << (Standard_Integer) itr.Value() << " ";
+  }
+  di << "\n";
+  return 0; 
+}
+
+//=======================================================================
+//function : GetIntegerList (DF, entry )
+//=======================================================================
+static Standard_Integer DDataStd_GetIntegerList (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_IntegerList) A;
+  if ( !label.FindAttribute(TDataStd_IntegerList::GetID(), A) ) 
+  {
+    di << "There is no TDataStd_IntegerList at label"  << "\n";
+    return 1;
+  }
+  
+  const TColStd_ListOfInteger& iList = A->List();
+  TColStd_ListIteratorOfListOfInteger itr(iList);
+  for (; itr.More(); itr.Next())
+  {
+    di << itr.Value() << " ";
+  }
+  di << "\n";
+  return 0; 
+}
+
+//=======================================================================
+//function : GetRealList (DF, entry )
+//=======================================================================
+static Standard_Integer DDataStd_GetRealList (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_RealList) A;
+  if ( !label.FindAttribute(TDataStd_RealList::GetID(), A) ) 
+  {
+    di << "There is no TDataStd_RealList at label"  << "\n";
+    return 1;
+  }
+  
+  const TColStd_ListOfReal& iList = A->List();
+  TColStd_ListIteratorOfListOfReal itr(iList);
+  for (; itr.More(); itr.Next())
+  {
+    di << itr.Value() << " ";
+  }
+  di << "\n";
+  return 0; 
+}
+
 //=======================================================================
 //function : SetIntPackedMap (DF, entry, isDelta, key1, key2, ...
 //=======================================================================
@@ -1320,7 +1592,7 @@ static Standard_Integer DDataStd_GetIntPackedMap (Draw_Interpretor& di,
     TColStd_MapIteratorOfPackedMapOfInteger itr(aMap);
     for (Standard_Integer j = 1; itr.More(); itr.Next(),j++){
       Standard_Integer aKey(itr.Key());
-      cout << "Key ("<< j <<")"<<" = " << aKey << endl;;
+      di << aKey << " ";
       }
     return 0; 
   }
@@ -2397,6 +2669,22 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands)
                    "SetAsciiString (DF, entry, String  )",
                    __FILE__, DDataStd_SetAsciiString, g);
 
+  theCommands.Add ("SetBooleanArray", 
+                   "SetBooleanArray (DF, entry, isDelta, From, To, elmt1, elmt2, ...  )",
+                   __FILE__, DDataStd_SetBooleanArray, g);
+
+  theCommands.Add ("SetBooleanList", 
+                   "SetBooleanList (DF, entry, elmt1, elmt2, ...  )",
+                   __FILE__, DDataStd_SetBooleanList, g);
+
+  theCommands.Add ("SetIntegerList", 
+                   "SetIntegerList (DF, entry, elmt1, elmt2, ...  )",
+                   __FILE__, DDataStd_SetIntegerList, g);
+
+  theCommands.Add ("SetRealList", 
+                   "SetRealList (DF, entry, elmt1, elmt2, ...  )",
+                   __FILE__, DDataStd_SetRealList, g);
+
 
   // GET
 
@@ -2416,7 +2704,6 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands)
                    "GetRealArray (DF, entry )",
                    __FILE__, DDataStd_GetRealArray, g);
 
-
   theCommands.Add ("GetByteArray", 
                    "GetByteArray (DF, entry )",
                    __FILE__, DDataStd_GetByteArray, g);
@@ -2458,11 +2745,26 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands)
                    "SetRelation (DF, entry, expression, var1[, var2, ...])",
                    __FILE__, DDataStd_SetRelation, g);
 
-
   theCommands.Add ("DumpRelation", 
                    "DumpRelation (DF, entry)",
                    __FILE__, DDataStd_DumpRelation, g);
 
+  theCommands.Add ("GetBooleanArray", 
+                   "GetBooleanArray (DF, entry )",
+                   __FILE__, DDataStd_GetBooleanArray, g);
+
+  theCommands.Add ("GetBooleanList", 
+                   "GetBooleanList (DF, entry )",
+                   __FILE__, DDataStd_GetBooleanList, g);
+
+  theCommands.Add ("GetIntegerList", 
+                   "GetIntegerList (DF, entry )",
+                   __FILE__, DDataStd_GetIntegerList, g);
+
+  theCommands.Add ("GetRealList", 
+                   "GetRealList (DF, entry )",
+                   __FILE__, DDataStd_GetRealList, g);
+
 
 
 // ========================= UTF =====================================
index d7e9af7..8011e6e 100755 (executable)
@@ -74,6 +74,7 @@ NCollection_UtfString.hxx
 NCollection_UtfString.lxx
 NCollection_String.hxx
 
+NCollection_LocalArray.hxx
 NCollection_SparseArray.hxx
 NCollection_SparseArrayBase.hxx
 NCollection_SparseArrayBase.cxx
diff --git a/src/NCollection/NCollection_LocalArray.hxx b/src/NCollection/NCollection_LocalArray.hxx
new file mode 100644 (file)
index 0000000..f322488
--- /dev/null
@@ -0,0 +1,83 @@
+// Created on: 2009-09-23
+// Copyright (c) 2009-2012 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+
+#ifndef _NCollection_LocalArray_HeaderFile
+#define _NCollection_LocalArray_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_TypeDef.hxx>
+
+//! Auxiliary class optimizing creation of array buffer 
+//! (using stack allocation for small arrays).
+template<class theItem> class NCollection_LocalArray
+{
+public:
+
+  // 1K * sizeof (theItem)
+  static const size_t MAX_ARRAY_SIZE = 1024;
+
+  NCollection_LocalArray (const size_t theSize)
+  : myPtr (myBuffer)
+  {
+    Allocate(theSize);
+  }
+
+  NCollection_LocalArray ()
+  : myPtr (myBuffer) {}
+
+  virtual ~NCollection_LocalArray()
+  {
+    Deallocate();
+  }
+
+  void Allocate (const size_t theSize)
+  {
+    Deallocate();
+    if (theSize > MAX_ARRAY_SIZE)
+      myPtr = (theItem*)Standard::Allocate (theSize * sizeof(theItem));
+    else
+      myPtr = myBuffer;
+  }
+
+  operator theItem*() const
+  {
+    return myPtr;
+  }
+
+private:
+
+  NCollection_LocalArray (const NCollection_LocalArray& );
+  NCollection_LocalArray& operator= (const NCollection_LocalArray& );
+
+protected:
+
+  void Deallocate()
+  {
+    if (myPtr != myBuffer)
+      Standard::Free (*(Standard_Address*)&myPtr);
+  }
+
+protected:
+
+  theItem  myBuffer[MAX_ARRAY_SIZE];
+  theItem* myPtr;
+
+};
+
+#endif // _NCollection_LocalArray_HeaderFile
index 27447e4..286b5de 100755 (executable)
@@ -1,4 +1,3 @@
 PLib_ChangeDim.gxx
 PLib_JacobiPolynomial_0.hxx
-PLib_LocalArray.hxx
 PLib_CMPLRS.edl
index c462878..1eacaf7 100755 (executable)
@@ -23,7 +23,7 @@
 // Modified: 19/02/1997 by JCT :  EvalPoly2Var added
 
 #include <PLib.ixx>
-#include <PLib_LocalArray.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <math_Matrix.hxx> 
 #include <math_Gauss.hxx> 
 #include <Standard_ConstructionError.hxx>
@@ -192,8 +192,8 @@ void  PLib::RationalDerivative(const Standard_Integer Degree,
   Standard_Real *RationalArray = &RDers;
   Standard_Real Factor ;
   Standard_Integer ii, Index, OtherIndex, Index1, Index2, jj;
-  PLib_LocalArray binomial_array;
-  PLib_LocalArray derivative_storage;
+  NCollection_LocalArray<Standard_Real> binomial_array;
+  NCollection_LocalArray<Standard_Real> derivative_storage;
   if (Dimension == 3) {
     Standard_Integer DeRequest1 = DerivativeRequest + 1;
     Standard_Integer MinDegRequ = DerivativeRequest;
@@ -412,8 +412,8 @@ void  PLib::RationalDerivatives(const Standard_Integer DerivativeRequest,
   Standard_Integer ii, Index, Index1, Index2, jj;
   Standard_Integer DeRequest1 = DerivativeRequest + 1;
   
-  PLib_LocalArray binomial_array (DeRequest1);
-  PLib_LocalArray derivative_storage;
+  NCollection_LocalArray<Standard_Real> binomial_array (DeRequest1);
+  NCollection_LocalArray<Standard_Real> derivative_storage;
 
   for (ii = 0 ; ii < DeRequest1 ; ii++) {
     binomial_array[ii] = 1.0e0 ;
@@ -1945,7 +1945,7 @@ PLib::EvalLagrange(const Standard_Real                   Parameter,
   if (local_request >= Degree) {
     local_request = Degree ;
   }
-  PLib_LocalArray divided_differences_array ((Degree + 1) * Dimension);
+  NCollection_LocalArray<Standard_Real> divided_differences_array ((Degree + 1) * Dimension);
   //
   //  Build the divided differences array
   //
@@ -2075,7 +2075,7 @@ Standard_Integer PLib::EvalCubicHermite
   if (local_request >= Degree) {
     local_request = Degree ;
   }   
-  PLib_LocalArray divided_differences_array ((Degree + 1) * Dimension);
+  NCollection_LocalArray<Standard_Real> divided_differences_array ((Degree + 1) * Dimension);
 
   for (ii = 0, jj = 0  ; ii < 2 ; ii++, jj+= 2) {
     ParametersArray[jj] =
index 96152f7..4e7b7bc 100755 (executable)
@@ -21,7 +21,7 @@
 
 #include <PLib_HermitJacobi.ixx>
 #include <PLib.hxx>
-#include <PLib_LocalArray.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <TColStd_HArray1OfReal.hxx>
 
 //=======================================================================
@@ -149,11 +149,11 @@ void PLib_HermitJacobi::D0123(const Standard_Integer NDeriv,
                              TColStd_Array1OfReal& BasisD2,
                              TColStd_Array1OfReal& BasisD3)
 {
-  PLib_LocalArray jac0 (4 * 20);
-  PLib_LocalArray jac1 (4 * 20);
-  PLib_LocalArray jac2 (4 * 20);
-  PLib_LocalArray jac3 (4 * 20);
-  PLib_LocalArray wvalues (4);
+  NCollection_LocalArray<Standard_Real> jac0 (4 * 20);
+  NCollection_LocalArray<Standard_Real> jac1 (4 * 20);
+  NCollection_LocalArray<Standard_Real> jac2 (4 * 20);
+  NCollection_LocalArray<Standard_Real> jac3 (4 * 20);
+  NCollection_LocalArray<Standard_Real> wvalues (4);
 
   Standard_Integer i, j;
   Standard_Integer NivConstr  = this->NivConstr(),
diff --git a/src/PLib/PLib_LocalArray.hxx b/src/PLib/PLib_LocalArray.hxx
deleted file mode 100644 (file)
index e616233..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-// Created on: 2009-09-23
-// Copyright (c) 2009-2012 OPEN CASCADE SAS
-//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
-//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
-//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-
-#ifndef _PLib_LocalArray_HeaderFile
-#define _PLib_LocalArray_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_TypeDef.hxx>
-
-//! Auxiliary class optimizing creation of array buffer for
-//! evaluation of bspline (using stack allocation for small arrays)
-class PLib_LocalArray
-{
-public:
-
-  // 1K * sizeof (double) = 8K
-  static const size_t MAX_ARRAY_SIZE = 1024;
-
-  PLib_LocalArray (const size_t theSize)
-  : myPtr (myBuffer)
-  {
-    Allocate(theSize);
-  }
-
-  PLib_LocalArray()
-  : myPtr (myBuffer) {}
-
-  virtual ~PLib_LocalArray()
-  {
-    Deallocate();
-  }
-
-  void Allocate (const size_t theSize)
-  {
-    Deallocate();
-    if (theSize > MAX_ARRAY_SIZE)
-      myPtr = (Standard_Real*)Standard::Allocate (theSize * sizeof(Standard_Real));
-    else
-      myPtr = myBuffer;
-  }
-
-  operator Standard_Real*() const
-  {
-    return myPtr;
-  }
-
-private:
-
-  PLib_LocalArray (const PLib_LocalArray& );
-  PLib_LocalArray& operator= (const PLib_LocalArray& );
-
-protected:
-
-  void Deallocate()
-  {
-    if (myPtr != myBuffer)
-      Standard::Free (*(Standard_Address*)&myPtr);
-  }
-
-protected:
-
-  Standard_Real  myBuffer[MAX_ARRAY_SIZE];
-  Standard_Real* myPtr;
-
-};
-
-#endif
index 8aca3a8..b5e6bf3 100755 (executable)
@@ -21,6 +21,7 @@
 #include <XmlMDataStd_BooleanArrayDriver.ixx>
 #include <TDataStd_BooleanArray.hxx>
 #include <TColStd_HArray1OfByte.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <XmlObjMgt.hxx>
 
 IMPLEMENT_DOMSTRING (FirstIndexString, "first")
@@ -93,9 +94,10 @@ Standard_Boolean XmlMDataStd_BooleanArrayDriver::Paste(const XmlObjMgt_Persisten
   Handle(TDataStd_BooleanArray) aBooleanArray = Handle(TDataStd_BooleanArray)::DownCast(theTarget);
   aBooleanArray->Init(aFirstInd, aLastInd);
   Standard_Integer length = aLastInd - aFirstInd + 1;
-  Handle(TColStd_HArray1OfByte) array = new TColStd_HArray1OfByte(0, length >> 3);
+  Handle(TColStd_HArray1OfByte) hArr = new TColStd_HArray1OfByte(0, length >> 3);
+  TColStd_Array1OfByte& arr = hArr->ChangeArray1();
 
-  Standard_Integer i = 0, upper = array->Upper();
+  Standard_Integer i = 0, upper = arr.Upper();
   Standard_CString aValueStr = Standard_CString(XmlObjMgt::GetStringValue(anElement).GetString());
   for (; i <= upper; i++)
   {
@@ -108,9 +110,9 @@ Standard_Boolean XmlMDataStd_BooleanArrayDriver::Paste(const XmlObjMgt_Persisten
       WriteMessage (aMessageString);
       return Standard_False;
     }
-    array->SetValue(i, (Standard_Byte) aValue);
+    arr.SetValue(i, (Standard_Byte) aValue);
   }
-  aBooleanArray->SetInternalArray(array);
+  aBooleanArray->SetInternalArray(hArr);
   
   return Standard_True;
 }
@@ -127,17 +129,27 @@ void XmlMDataStd_BooleanArrayDriver::Paste(const Handle(TDF_Attribute)& theSourc
 
   Standard_Integer aL = aBooleanArray->Lower();
   Standard_Integer anU = aBooleanArray->Upper();
-  TCollection_AsciiString aValueStr;
 
   theTarget.Element().setAttribute(::FirstIndexString(), aL);
   theTarget.Element().setAttribute(::LastIndexString(), anU);
 
-  const Handle(TColStd_HArray1OfByte)& array = aBooleanArray->InternalArray();
-  Standard_Integer lower = array->Lower(), i = lower, upper = array->Upper();
+  const Handle(TColStd_HArray1OfByte)& hArr = aBooleanArray->InternalArray();
+  const TColStd_Array1OfByte& arr = hArr->Array1();
+
+  // Allocation of 4 chars for each byte.
+  Standard_Integer iChar = 0;
+  NCollection_LocalArray<Standard_Character> str;
+  if (arr.Length())
+    str.Allocate(4 * arr.Length() + 1);
+
+  // Convert integers - compressed boolean values, to a string.
+  Standard_Integer lower = arr.Lower(), i = lower, upper = arr.Upper();
   for (; i <= upper; i++)
   {
-    aValueStr += TCollection_AsciiString((Standard_Integer) array->Value(i));
-    aValueStr += ' ';
+    const Standard_Byte& byte = arr.Value(i);
+    iChar += Sprintf(&(str[iChar]), "%d ", byte);
   }
-  XmlObjMgt::SetStringValue (theTarget, aValueStr.ToCString(), Standard_True);
+
+  if (arr.Length())
+    XmlObjMgt::SetStringValue (theTarget, (Standard_Character*)str, Standard_True);
 }
index 0fd9b0e..7a9dc9e 100755 (executable)
@@ -21,6 +21,7 @@
 #include <XmlMDataStd_BooleanListDriver.ixx>
 #include <TDataStd_BooleanList.hxx>
 #include <TDataStd_ListIteratorOfListOfByte.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <XmlObjMgt.hxx>
 
 IMPLEMENT_DOMSTRING (FirstIndexString, "first")
@@ -127,18 +128,18 @@ void XmlMDataStd_BooleanListDriver::Paste(const Handle(TDF_Attribute)& theSource
   Handle(TDataStd_BooleanList) aBooleanList = Handle(TDataStd_BooleanList)::DownCast(theSource);
 
   Standard_Integer anU = aBooleanList->Extent();
-  TCollection_AsciiString aValueStr;
-
   theTarget.Element().setAttribute(::LastIndexString(), anU);
   if (anU >= 1)
   {
+    // Allocation of 1 char for each boolean value + a space.
+    Standard_Integer iChar = 0;
+    NCollection_LocalArray<Standard_Character> str(2 * anU + 1);
     TDataStd_ListIteratorOfListOfByte itr(aBooleanList->List());
     for (; itr.More(); itr.Next())
     {
-      aValueStr += TCollection_AsciiString(itr.Value());
-      aValueStr += ' ';
+      const Standard_Byte& byte = itr.Value();
+      iChar += Sprintf(&(str[iChar]), "%d ", byte);
     }
+    XmlObjMgt::SetStringValue (theTarget, (Standard_Character*)str, Standard_True);
   }
-  // No occurrence of '&', '<' and other irregular XML characters
-  XmlObjMgt::SetStringValue (theTarget, aValueStr.ToCString(), Standard_True);
 }
index f0a359b..81ee509 100755 (executable)
@@ -21,6 +21,7 @@
 #include <XmlMDataStd_ByteArrayDriver.ixx>
 #include <TDataStd_ByteArray.hxx>
 #include <TColStd_HArray1OfByte.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <XmlObjMgt.hxx>
 #include <XmlMDataStd.hxx>
 
@@ -93,10 +94,11 @@ Standard_Boolean XmlMDataStd_ByteArrayDriver::Paste(const XmlObjMgt_Persistent&
 
 
   Handle(TDataStd_ByteArray) aByteArray = Handle(TDataStd_ByteArray)::DownCast(theTarget);
-  Handle(TColStd_HArray1OfByte) array = new TColStd_HArray1OfByte(aFirstInd, aLastInd);
+  Handle(TColStd_HArray1OfByte) hArr = new TColStd_HArray1OfByte(aFirstInd, aLastInd);
+  TColStd_Array1OfByte& arr = hArr->ChangeArray1();
 
   Standard_CString aValueStr = Standard_CString(XmlObjMgt::GetStringValue(anElement).GetString());
-  Standard_Integer i = array->Lower(), upper = array->Upper();
+  Standard_Integer i = arr.Lower(), upper = arr.Upper();
   for (; i <= upper; i++)
   {
     if (!XmlObjMgt::GetInteger(aValueStr, aValue)) 
@@ -108,9 +110,9 @@ Standard_Boolean XmlMDataStd_ByteArrayDriver::Paste(const XmlObjMgt_Persistent&
       WriteMessage (aMessageString);
       return Standard_False;
     }
-    array->SetValue(i, (Standard_Byte) aValue);
+    arr.SetValue(i, (Standard_Byte) aValue);
   }
-  aByteArray->ChangeArray(array);
+  aByteArray->ChangeArray(hArr);
   
 #ifdef DEB
   //cout << "CurDocVersion = " << XmlMDataStd::DocumentVersion() <<endl;
@@ -152,19 +154,32 @@ void XmlMDataStd_ByteArrayDriver::Paste(const Handle(TDF_Attribute)& theSource,
 
   Standard_Integer aL = aByteArray->Lower();
   Standard_Integer anU = aByteArray->Upper();
-  TCollection_AsciiString aValueStr;
 
   theTarget.Element().setAttribute(::FirstIndexString(), aL);
   theTarget.Element().setAttribute(::LastIndexString(), anU);
   theTarget.Element().setAttribute(::IsDeltaOn(),aByteArray->GetDelta());
 
-  const Handle(TColStd_HArray1OfByte)& array = aByteArray->InternalArray();
-  Standard_Integer lower = array->Lower(), i = lower, upper = array->Upper();
-  for (; i <= upper; i++)
+  const Handle(TColStd_HArray1OfByte)& hArr = aByteArray->InternalArray();
+  if (!hArr.IsNull() && hArr->Length())
   {
-    aValueStr += TCollection_AsciiString((Standard_Integer) array->Value(i));
-    aValueStr += ' ';
-  }
-  XmlObjMgt::SetStringValue (theTarget, aValueStr.ToCString(), Standard_True);
+    // Access to data through an internal reprsentation of the array is faster.
+    const TColStd_Array1OfByte& arr = hArr->Array1();
+
+    // Allocate 4 characters (including a space ' ') for each byte (unsigned char) from the array.
+    NCollection_LocalArray<Standard_Character> str(4 * arr.Length() + 1);
+
+    // Char counter in the array of chars.
+    Standard_Integer iChar = 0;
 
+    // Iterate on the array of bytes and fill-in the array of chars inserting spacing between the chars.
+    Standard_Integer iByte = arr.Lower(); // position inside the byte array
+    for (; iByte <= arr.Upper(); ++iByte)
+    {
+      const Standard_Byte& byte = arr.Value(iByte);
+      iChar += Sprintf(&(str[iChar]), "%d ", byte);
+    }
+
+    // Transfer the string (array of chars) to XML.
+    XmlObjMgt::SetStringValue (theTarget, (Standard_Character*)str, Standard_True);
+  }
 }
index 9aa07de..26e2f92 100755 (executable)
@@ -29,6 +29,7 @@
 #include <XmlMDF_ADriver.hxx>
 #include <TDF_Attribute.hxx>
 #include <TDataStd_IntPackedMap.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <XmlMDataStd.hxx>
 
 IMPLEMENT_DOMSTRING (IntPackedMapSize, "mapsize")
@@ -154,14 +155,21 @@ void XmlMDataStd_IntPackedMapDriver::Paste (const Handle(TDF_Attribute)& theSour
   theTarget.Element().setAttribute(::IntPackedMapSize(), aSize);
   theTarget.Element().setAttribute(::IsDeltaOn(),aS->GetDelta());
 
-  TCollection_AsciiString aValueString;
-  if(aSize) {
+  if(aSize)
+  {
+    // Allocation of 12 chars for each integer including the space.
+    // An example: -2 147 483 648
+    Standard_Integer iChar = 0;
+    NCollection_LocalArray<Standard_Character> str(12 * aSize + 1);
+
     TColStd_MapIteratorOfPackedMapOfInteger anIt(aS->GetMap());
-    for(;anIt.More();anIt.Next()) {
-      aValueString += TCollection_AsciiString(anIt.Key());
-      aValueString += ' ';
+    for(;anIt.More();anIt.Next()) 
+    {
+      const Standard_Integer intValue = anIt.Key();
+      iChar += Sprintf(&(str[iChar]), "%d ", intValue);
     }
+
     // No occurrence of '&', '<' and other irregular XML characters
-    XmlObjMgt::SetStringValue (theTarget, aValueString.ToCString(), Standard_True);
+    XmlObjMgt::SetStringValue (theTarget, (Standard_Character*)str, Standard_True);
   }
 }
index a1f4596..4222d88 100755 (executable)
@@ -21,6 +21,7 @@
 
 #include <XmlMDataStd_IntegerArrayDriver.ixx>
 #include <TDataStd_IntegerArray.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <XmlObjMgt.hxx>
 #include <XmlMDataStd.hxx>
 
@@ -154,21 +155,36 @@ void XmlMDataStd_IntegerArrayDriver::Paste
 {
   Handle(TDataStd_IntegerArray) anIntArray =
     Handle(TDataStd_IntegerArray)::DownCast(theSource);
+  const Handle(TColStd_HArray1OfInteger)& hIntArray = anIntArray->Array();
+  const TColStd_Array1OfInteger& intArray = hIntArray->Array1();
+  Standard_Integer aL = intArray.Lower(), anU = intArray.Upper();
 
-  Standard_Integer aL = anIntArray->Lower(), anU = anIntArray->Upper();
-  TCollection_AsciiString aValueStr;
-
-  if (aL != 1) theTarget.Element().setAttribute (::FirstIndexString(), aL);
+  if (aL != 1) 
+    theTarget.Element().setAttribute(::FirstIndexString(), aL);
   theTarget.Element().setAttribute(::LastIndexString(), anU);
   theTarget.Element().setAttribute(::IsDeltaOn(), anIntArray->GetDelta());
 
+  // Allocation of 12 chars for each integer including the space.
+  // An example: -2 147 483 648
+  Standard_Integer iChar = 0;
+  NCollection_LocalArray<Standard_Character> str;
+  if (intArray.Length())
+    str.Allocate(12 * intArray.Length() + 1);
+
   Standard_Integer i = aL;
-  while (1) {
-    aValueStr += TCollection_AsciiString(anIntArray->Value(i));
-    if (i >= anU) break;
-    aValueStr += ' ';
+  while (1) 
+  {
+    const Standard_Integer& intValue = intArray.Value(i);
+    iChar += Sprintf(&(str[iChar]), "%d ", intValue);
+    if (i >= anU)
+      break;
     ++i;
   }
-  // No occurrence of '&', '<' and other irregular XML characters
-  XmlObjMgt::SetStringValue (theTarget, aValueStr.ToCString(), Standard_True);
+
+  if (intArray.Length())
+  {
+    // No occurrence of '&', '<' and other irregular XML characters
+    str[iChar - 1] = '\0';
+    XmlObjMgt::SetStringValue (theTarget, (Standard_Character*)str, Standard_True);
+  }
 }
index e2bc4f6..f370d4e 100755 (executable)
@@ -21,6 +21,7 @@
 #include <XmlMDataStd_IntegerListDriver.ixx>
 #include <TDataStd_IntegerList.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <XmlObjMgt.hxx>
 
 IMPLEMENT_DOMSTRING (FirstIndexString, "first")
@@ -127,18 +128,21 @@ void XmlMDataStd_IntegerListDriver::Paste(const Handle(TDF_Attribute)& theSource
   Handle(TDataStd_IntegerList) anIntList = Handle(TDataStd_IntegerList)::DownCast(theSource);
 
   Standard_Integer anU = anIntList->Extent();
-  TCollection_AsciiString aValueStr;
-
   theTarget.Element().setAttribute(::LastIndexString(), anU);
   if (anU >= 1)
   {
+    // Allocation of 12 chars for each integer including the space.
+    // An example: -2 147 483 648
+    Standard_Integer iChar = 0;
+    NCollection_LocalArray<Standard_Character> str(12 * anU + 1);
     TColStd_ListIteratorOfListOfInteger itr(anIntList->List());
     for (; itr.More(); itr.Next())
     {
-      aValueStr += TCollection_AsciiString(itr.Value());
-      aValueStr += ' ';
+      const Standard_Integer& intValue = itr.Value();
+      iChar += Sprintf(&(str[iChar]), "%d ", intValue);
     }
+
+    // No occurrence of '&', '<' and other irregular XML characters
+    XmlObjMgt::SetStringValue (theTarget, (Standard_Character*)str, Standard_True);
   }
-  // No occurrence of '&', '<' and other irregular XML characters
-  XmlObjMgt::SetStringValue (theTarget, aValueStr.ToCString(), Standard_True);
 }
index d0edf72..926b161 100755 (executable)
 
 //AGV 150202: Changed prototype XmlObjMgt::SetStringValue()
 
-#define OCC6010 // vro 01.06.2004
-
 # include <stdio.h>
 #include <XmlMDataStd_RealArrayDriver.ixx>
 #include <TDataStd_RealArray.hxx>
 #include <XmlObjMgt.hxx>
 #include <XmlMDataStd.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+#include <NCollection_LocalArray.hxx>
 
 IMPLEMENT_DOMSTRING (FirstIndexString, "first")
 IMPLEMENT_DOMSTRING (LastIndexString, "last")
@@ -158,27 +158,35 @@ void XmlMDataStd_RealArrayDriver::Paste (const Handle(TDF_Attribute)& theSource,
 {
   Handle(TDataStd_RealArray) aRealArray =
     Handle(TDataStd_RealArray)::DownCast(theSource);
-
-  Standard_Integer aL = aRealArray->Lower(), anU = aRealArray->Upper();
-  TCollection_AsciiString aValueStr;
+  const Handle(TColStd_HArray1OfReal)& hRealArray = aRealArray->Array();
+  const TColStd_Array1OfReal& realArray = hRealArray->Array1();
+  Standard_Integer aL = realArray.Lower(), anU = realArray.Upper();
 
   if (aL != 1) theTarget.Element().setAttribute(::FirstIndexString(), aL);
   theTarget.Element().setAttribute(::LastIndexString(), anU);
   theTarget.Element().setAttribute(::IsDeltaOn(), aRealArray->GetDelta());
 
+  // Allocation of 25 chars for each double value including the space:
+  // An example: -3.1512678732195273e+020
+  Standard_Integer iChar = 0;
+  NCollection_LocalArray<Standard_Character> str;
+  if (realArray.Length())
+    str.Allocate(25 * realArray.Length() + 1);
+
   Standard_Integer i = aL;
-  while (1) {
-#ifndef OCC6010
-    aValueStr += TCollection_AsciiString(aRealArray->Value(i));
-#else
-    char aValueChar[32];
-    Sprintf(aValueChar, "%.15g", aRealArray->Value(i));
-    aValueStr += aValueChar;
-#endif
-    if (i >= anU) break;
-    aValueStr += ' ';
+  while (1) 
+  {
+    const Standard_Real& dblValue = realArray.Value(i);
+    iChar += Sprintf(&(str[iChar]), "%.17g ", dblValue);
+    if (i >= anU)
+      break;
     ++i;
   }
+
   // No occurrence of '&', '<' and other irregular XML characters
-  XmlObjMgt::SetStringValue (theTarget, aValueStr.ToCString(), Standard_True);
+  if (realArray.Length())
+  {
+    str[iChar - 1] = '\0';
+    XmlObjMgt::SetStringValue (theTarget, (Standard_Character*)str, Standard_True);
+  }
 }
index 582f2d4..84d383a 100755 (executable)
@@ -84,7 +84,7 @@ void XmlMDataStd_RealDriver::Paste (const Handle(TDF_Attribute)& theSource,
   TCollection_AsciiString aValueStr (anInt->Get());
 #else
   char aValueChar[32];
-  Sprintf(aValueChar, "%.15g", anInt->Get());
+  Sprintf(aValueChar, "%.17g", anInt->Get());
   TCollection_AsciiString aValueStr(aValueChar);
 #endif
   // No occurrence of '&', '<' and other irregular XML characters
index 572cd1d..bbea79c 100755 (executable)
@@ -21,6 +21,7 @@
 #include <XmlMDataStd_RealListDriver.ixx>
 #include <TDataStd_RealList.hxx>
 #include <TColStd_ListIteratorOfListOfReal.hxx>
+#include <NCollection_LocalArray.hxx>
 #include <XmlObjMgt.hxx>
 
 IMPLEMENT_DOMSTRING (FirstIndexString, "first")
@@ -135,18 +136,19 @@ void XmlMDataStd_RealListDriver::Paste(const Handle(TDF_Attribute)& theSource,
   Handle(TDataStd_RealList) aRealList = Handle(TDataStd_RealList)::DownCast(theSource);
 
   Standard_Integer anU = aRealList->Extent();
-  TCollection_AsciiString aValueStr;
-
   theTarget.Element().setAttribute(::LastIndexString(), anU);
   if (anU >= 1)
   {
+    // Allocation of 25 chars for each double value including the space:
+    // An example: -3.1512678732195273e+020
+    Standard_Integer iChar = 0;
+    NCollection_LocalArray<Standard_Character> str(25 * anU + 1);
     TColStd_ListIteratorOfListOfReal itr(aRealList->List());
     for (; itr.More(); itr.Next())
     {
-      aValueStr += TCollection_AsciiString(itr.Value());
-      aValueStr += ' ';
+      const Standard_Real& realValue = itr.Value();
+      iChar += Sprintf(&(str[iChar]), "%.17g ", realValue);
     }
+    XmlObjMgt::SetStringValue (theTarget, (Standard_Character*)str, Standard_True);
   }
-  // No occurrence of '&', '<' and other irregular XML characters
-  XmlObjMgt::SetStringValue (theTarget, aValueStr.ToCString(), Standard_True);
 }
index 45309de..8c0b6af 100755 (executable)
@@ -19,6 +19,7 @@
 
 
 #include <XmlMDataStd_TreeNodeDriver.ixx>
+#include <NCollection_LocalArray.hxx>
 #include <TDataStd_TreeNode.hxx>
 #include <XmlObjMgt.hxx>
 
@@ -108,20 +109,24 @@ void XmlMDataStd_TreeNodeDriver::Paste
 {
   Handle(TDataStd_TreeNode) aS = Handle(TDataStd_TreeNode)::DownCast(theSource);
 
-  Standard_Integer aNb;
-
-  TCollection_AsciiString aChildrenStr;
-
   // tree id
+  Standard_Integer aNb;
   Standard_Character aGuidStr [40];
   Standard_PCharacter pGuidStr=aGuidStr;
   aS->ID().ToCString (pGuidStr);
   theTarget.Element().setAttribute(::TreeIdString(), aGuidStr);
 
-  // first child
-  Handle(TDataStd_TreeNode) aF = aS->First();
+  // Find number of children.
+  int nbChildren = aS->NbChildren();
+  
+  // Allocate 11 digits for each ID (an integer) of the child + a space.
+  Standard_Integer iChar = 0;
+  NCollection_LocalArray<Standard_Character> str;
+  if (nbChildren)
+    str.Allocate(11 * nbChildren + 1);
 
   // form the string of numbers for the list of children
+  Handle(TDataStd_TreeNode) aF = aS->First();
   while (!aF.IsNull())
   {
     aNb = theRelocTable.FindIndex(aF);
@@ -129,14 +134,16 @@ void XmlMDataStd_TreeNodeDriver::Paste
     {
       aNb = theRelocTable.Add(aF);
     }
-    TCollection_AsciiString aNbStr (aNb);
-    aChildrenStr += aNbStr + " ";
+
+    // Add number to the long string.
+    iChar += Sprintf(&(str[iChar]), "%d ", aNb);
 
     // next child
     aF = aF->Next();
   }
 
-  if (aChildrenStr.Length() > 0)
-    theTarget.Element().setAttribute(::ChildrenString(),
-                                      aChildrenStr.ToCString());
+  if (nbChildren)
+  {
+    theTarget.Element().setAttribute(::ChildrenString(), (Standard_Character*)str);
+  }
 }
diff --git a/tests/caf/bugs/D1 b/tests/caf/bugs/D1
new file mode 100755 (executable)
index 0000000..495d8e8
--- /dev/null
@@ -0,0 +1,236 @@
+#INTERFACE CAF
+puts "================"
+puts "bug0023850: Speed-up storage of OCAF document in XML file format"
+puts "================"
+puts ""
+######################################################
+# Speed-up storage of OCAF document in XML file format
+######################################################
+
+# Create an OCAF document. Use XML as a test storage schema.
+NewDocument DOC XmlOcaf
+
+# Set a long byte array of many-many values. Here it is an array of 10 values.
+SetByteArray DOC 0:1 0 1 10 1 2 3 4 5 6 7 8 9 10
+
+# Set a list of tree nodes.
+SetNode DOC 0:1
+SetNode DOC 0:1:1
+SetNode DOC 0:1:2
+SetNode DOC 0:1:3
+SetNode DOC 0:1:4
+SetNode DOC 0:1:5
+SetNode DOC 0:1:6
+SetNode DOC 0:1:7
+SetNode DOC 0:1:8
+AppendNode DOC 0:1 0:1:1
+AppendNode DOC 0:1 0:1:2
+AppendNode DOC 0:1 0:1:3
+AppendNode DOC 0:1 0:1:4
+AppendNode DOC 0:1 0:1:5
+AppendNode DOC 0:1 0:1:6
+AppendNode DOC 0:1 0:1:7
+AppendNode DOC 0:1 0:1:8
+
+# Set an array of integer values.
+SetIntArray DOC 0:1 0 1 5 111 222 333 444 555
+
+# Set an array of double values (one of them contains 17 digits!)
+SetRealArray DOC 0:1 0 1 5 1.12345678987654321 2.2 3.3 4.4 5.5
+
+# Set a packed map of integer values.
+SetIntPackedMap DOC 0:1 0 1 10 100 1000 10000
+
+# Set an array of boolean values.
+SetBooleanArray DOC 0:1 0 1 5 0 0 0 1 1
+
+# Set a list of integer values.
+SetIntegerList DOC 0:1 1971 1972 1973 1974 1975
+
+# Set a list of boolean values.
+SetBooleanList DOC 0:1 1 0 0 0 1
+
+# Set a list of double values.
+SetRealList DOC 0:1 0.98765432123456789e+21 0.98765432123456789e+22 0.98765432123456789e+23
+                          
+set aFile ${imagedir}/bug23850_test.xml
+# Save the document on disk.
+SaveAs DOC ${aFile}
+Close DOC
+
+# Open the document.
+Open ${aFile} DOC
+
+# Get byte array and check its values.
+set bytearray [GetByteArray DOC 0:1]
+set bytearray1  [lindex ${bytearray} 0]
+set bytearray2  [lindex ${bytearray} 1]
+set bytearray3  [lindex ${bytearray} 2]
+set bytearray4  [lindex ${bytearray} 3]
+set bytearray5  [lindex ${bytearray} 4]
+set bytearray6  [lindex ${bytearray} 5]
+set bytearray7  [lindex ${bytearray} 6]
+set bytearray8  [lindex ${bytearray} 7]
+set bytearray9  [lindex ${bytearray} 8]
+set bytearray10 [lindex ${bytearray} 9]
+if { ${bytearray1} != 1 ||  
+     ${bytearray2} != 2 ||
+     ${bytearray3} != 3 ||
+     ${bytearray4} != 4 ||
+     ${bytearray5} != 5 ||
+     ${bytearray6} != 6 ||
+     ${bytearray7} != 7 ||
+     ${bytearray8} != 8 ||
+     ${bytearray9} != 9 ||
+     ${bytearray10} != 10 } {
+    puts "ByteArray failed..."
+} else {
+    puts "ByteArray      is OK"
+}
+
+# Check tree nodes.
+set nodes [ChildNodeIterate DOC 0:1 1]
+set node1  [lindex ${nodes} 0]
+set node2  [lindex ${nodes} 1]
+set node3  [lindex ${nodes} 2]
+set node4  [lindex ${nodes} 3]
+set node5  [lindex ${nodes} 4]
+set node6  [lindex ${nodes} 5]
+set node7  [lindex ${nodes} 6]
+set node8  [lindex ${nodes} 7]
+if { ${node1} != "0:1:1" ||  
+     ${node2} != "0:1:2" ||
+     ${node3} != "0:1:3" ||
+     ${node4} != "0:1:4" ||
+     ${node5} != "0:1:5" ||
+     ${node6} != "0:1:6" ||
+     ${node7} != "0:1:7" ||
+     ${node8} != "0:1:8" } {
+    puts "TreeNode failed..."
+} else {
+    puts "TreeNode       is OK"
+}
+                            
+# Check array of integer values.
+set intarray [GetIntArray DOC 0:1]
+set intarray1  [lindex ${intarray} 0]
+set intarray2  [lindex ${intarray} 1]
+set intarray3  [lindex ${intarray} 2]
+set intarray4  [lindex ${intarray} 3]
+set intarray5  [lindex ${intarray} 4]
+if { ${intarray1} != 111 ||  
+     ${intarray2} != 222 ||
+     ${intarray3} != 333 ||
+     ${intarray4} != 444 ||
+     ${intarray5} != 555 } {
+    puts "IntegerArray failed..."
+} else {
+    puts "IntegerArray   is OK"
+}
+                         
+# Check array of double values.
+# Warning!: It seems TCL uses 16 digits for manipulation with a double values...
+set realarray [GetRealArray DOC 0:1]
+set realarray1  [lindex ${realarray} 0]
+set realarray2  [lindex ${realarray} 1]
+set realarray3  [lindex ${realarray} 2]
+set realarray4  [lindex ${realarray} 3]
+set realarray5  [lindex ${realarray} 4]
+if { ${realarray1} != 1.12345678987654321 ||  
+     ${realarray2} != 2.2 ||
+     ${realarray3} != 3.3 ||
+     ${realarray4} != 4.4 ||
+     ${realarray5} != 5.5 } {
+    puts "RealArray failed..."
+} else {
+    puts "RealArray      is OK"
+}
+
+# Check packed map of integer values.
+set packedintmap [GetIntPackedMap DOC 0:1]
+set nb [llength ${packedintmap}]
+if { ${nb} != 5 } {
+    puts "IntPackedMap failed..."
+}
+set contains1 [lsearch ${packedintmap} 1]
+set contains2 [lsearch ${packedintmap} 10]
+set contains3 [lsearch ${packedintmap} 100]
+set contains4 [lsearch ${packedintmap} 1000]
+set contains5 [lsearch ${packedintmap} 10000]
+if { ${contains1} == -1 ||
+     ${contains2} == -1 ||
+     ${contains3} == -1 ||
+     ${contains4} == -1 ||
+     ${contains5} == -1 } {
+    puts "Failed..."
+} else {
+    puts "IntPackedMap   is OK"
+}
+
+# Get boolean array and check its values.
+set boolarray [GetBooleanArray DOC 0:1]
+set boolarray1  [lindex ${boolarray} 0]
+set boolarray2  [lindex ${boolarray} 1]
+set boolarray3  [lindex ${boolarray} 2]
+set boolarray4  [lindex ${boolarray} 3]
+set boolarray5  [lindex ${boolarray} 4]
+if { ${boolarray1} != 0 ||  
+     ${boolarray2} != 0 ||
+     ${boolarray3} != 0 ||
+     ${boolarray4} != 1 ||
+     ${boolarray5} != 1 } {
+    puts "BoolArray failed..."
+} else {
+    puts "BoolArray      is OK"
+}
+
+# Get boolean list and check its values.
+set boollist [GetBooleanList DOC 0:1]
+set boollist1  [lindex ${boollist} 0]
+set boollist2  [lindex ${boollist} 1]
+set boollist3  [lindex ${boollist} 2]
+set boollist4  [lindex ${boollist} 3]
+set boollist5  [lindex ${boollist} 4]
+if { ${boollist1} != 1 ||  
+     ${boollist2} != 0 ||
+     ${boollist3} != 0 ||
+     ${boollist4} != 0 ||
+     ${boollist5} != 1 } {
+    puts "BoolList failed..."
+} else {
+    puts "BoolList       is OK"
+}
+
+# Get integer list and check its values.
+set intlist [GetIntegerList DOC 0:1]
+set intlist1  [lindex ${intlist} 0]
+set intlist2  [lindex ${intlist} 1]
+set intlist3  [lindex ${intlist} 2]
+set intlist4  [lindex ${intlist} 3]
+set intlist5  [lindex ${intlist} 4]
+if { ${intlist1} != 1971 ||  
+     ${intlist2} != 1972 ||
+     ${intlist3} != 1973 ||
+     ${intlist4} != 1974 ||
+     ${intlist5} != 1975 } {
+    puts "IntList failed..."
+} else {
+    puts "IntList        is OK"
+}
+
+# Get double list and check its values.
+set reallist [GetRealList DOC 0:1]
+set reallist1  [lindex ${reallist} 0]
+set reallist2  [lindex ${reallist} 1]
+set reallist3  [lindex ${reallist} 2]
+if { ${reallist1} != 0.98765432123456789e+21 ||  
+     ${reallist2} != 0.98765432123456789e+22 ||
+     ${reallist3} != 0.98765432123456789e+23 } {
+    puts "RealList failed..."
+} else {
+    puts "RealList       is OK"
+}
+
+Close DOC
+file delete test.xml
+puts "bug0023850: OK"