Salome HOME
737f1f752fde4b23930e765f300b65ef56a371a0
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_TableOfStringAttribute.cxx
1 //  SALOME SALOMEDS : data structure of SALOME and sources of Salome data server 
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : SALOMEDS_TableOfStringAttribute.cxx
8 //  Author : Sergey Ruin
9 //  Module : SALOME
10
11 using namespace std;
12 #include <SALOMEDS_TableOfStringAttribute.ixx>
13 #include <Standard_Failure.hxx>
14 #include <SALOMEDS_DataMapIteratorOfDataMapOfIntegerString.hxx>
15
16 #include <string>
17 #include <stdio.h>
18
19 const Standard_GUID& SALOMEDS_TableOfStringAttribute::GetID() 
20 {
21   static Standard_GUID SALOMEDS_TableOfStringAttributeID ("128371A2-8F52-11d6-A8A3-0001021E8C7F");
22   return SALOMEDS_TableOfStringAttributeID;
23 }
24
25 Handle(SALOMEDS_TableOfStringAttribute) SALOMEDS_TableOfStringAttribute::Set(const TDF_Label& label) 
26 {
27   Handle(SALOMEDS_TableOfStringAttribute) anAttr;
28   if (!label.FindAttribute(SALOMEDS_TableOfStringAttribute::GetID(),anAttr)) {
29     anAttr = new SALOMEDS_TableOfStringAttribute();
30     label.AddAttribute(anAttr);
31   }
32   return anAttr;
33 }
34
35 SALOMEDS_TableOfStringAttribute::SALOMEDS_TableOfStringAttribute() {
36   myRows = new TColStd_HSequenceOfExtendedString();
37   myCols = new TColStd_HSequenceOfExtendedString();
38   myNbRows = 0;
39   myNbColumns = 0;
40 }
41
42 void SALOMEDS_TableOfStringAttribute::SetNbColumns(const Standard_Integer theNbColumns)
43 {
44   Backup();
45   
46   SALOMEDS_DataMapOfIntegerString aMap;
47   aMap = myTable;
48   myTable.Clear();
49
50   SALOMEDS_DataMapIteratorOfDataMapOfIntegerString anIterator(aMap);
51   for(; anIterator.More(); anIterator.Next()) {
52     int aRow = (int)(anIterator.Key()/myNbColumns) + 1;
53     int aCol = (int)(anIterator.Key() - myNbColumns*(aRow-1));
54     if(aCol == 0) { aCol = myNbColumns; aRow--; }
55     if(aCol > theNbColumns) continue;
56     int aKey = (aRow-1)*theNbColumns+aCol;
57     myTable.Bind(aKey, anIterator.Value());
58   }
59
60   myNbColumns = theNbColumns;
61
62   while (myCols->Length() < myNbColumns) { // append empty columns titles
63     myCols->Append(TCollection_ExtendedString(""));
64   }
65 }
66
67 void SALOMEDS_TableOfStringAttribute::SetTitle(const TCollection_ExtendedString& theTitle) {
68   Backup();
69   myTitle = theTitle;
70 }
71
72 TCollection_ExtendedString SALOMEDS_TableOfStringAttribute::GetTitle() const {
73   return myTitle;
74 }
75
76 void SALOMEDS_TableOfStringAttribute::SetRowData(const Standard_Integer theRow,
77                                                   const Handle(TColStd_HSequenceOfExtendedString)& theData) 
78 {
79   if(theData->Length() > myNbColumns) SetNbColumns(theData->Length());
80
81   Backup();
82
83   while (myRows->Length() < theRow) { // append new row titles
84     myRows->Append(TCollection_ExtendedString(""));
85   }
86
87   Standard_Integer i, aShift = (theRow-1)*myNbColumns, aLength = theData->Length();
88   for(i = 1; i <= aLength; i++) {
89     myTable.Bind(aShift + i, theData->Value(i));
90   }
91
92   if(theRow > myNbRows) myNbRows = theRow;
93 }
94
95 Handle(TColStd_HSequenceOfExtendedString) SALOMEDS_TableOfStringAttribute::GetRowData(const Standard_Integer theRow)
96 {
97   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString();
98   Standard_Integer i, aShift = (theRow-1)*myNbColumns;
99   for(i = 1; i <= myNbColumns; i++) {
100      if(myTable.IsBound(aShift+i)) 
101        aSeq->Append(myTable.Find(aShift+i));
102      else
103        aSeq->Append(0.);
104   }
105   
106   return aSeq;
107 }
108
109 void SALOMEDS_TableOfStringAttribute::SetRowTitle(const Standard_Integer theRow,
110                                                    const TCollection_ExtendedString& theTitle) {
111   Backup();
112   myRows->SetValue(theRow,theTitle);
113 }
114
115 TCollection_ExtendedString SALOMEDS_TableOfStringAttribute::GetRowTitle(const Standard_Integer theRow) const {
116   return myRows->Value(theRow);
117 }
118
119
120 void SALOMEDS_TableOfStringAttribute::SetColumnData(const Standard_Integer theColumn,
121                                                      const Handle(TColStd_HSequenceOfExtendedString)& theData) 
122 {
123   if(theColumn > myNbColumns) SetNbColumns(theColumn);
124
125   Backup();
126
127   Standard_Integer i, aLength = theData->Length();
128   for(i = 1; i <= aLength; i++) {
129     myTable.Bind(myNbColumns*(i-1)+theColumn, theData->Value(i));
130   }
131
132   if(aLength > myNbRows) {
133     myNbRows = aLength;
134     while (myRows->Length() < myNbRows) { // append empty row titles
135       myRows->Append(TCollection_ExtendedString(""));
136     }
137   }
138 }
139
140
141 Handle(TColStd_HSequenceOfExtendedString) SALOMEDS_TableOfStringAttribute::GetColumnData(const Standard_Integer theColumn)
142 {
143   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
144   
145   Standard_Integer i, anIndex;
146   for(i = 1; i <= myNbRows; i++) {
147     anIndex = myNbColumns*(i-1) + theColumn;
148     if(myTable.IsBound(anIndex)) 
149       aSeq->Append(myTable.Find(anIndex));
150     else
151       aSeq->Append(0.);
152   }
153   
154   return aSeq;
155 }
156
157 void SALOMEDS_TableOfStringAttribute::SetColumnTitle(const Standard_Integer theColumn,
158                                                       const TCollection_ExtendedString& theTitle) {
159   Backup();
160   while(myCols->Length() < theColumn) myCols->Append(TCollection_ExtendedString(""));
161   myCols->SetValue(theColumn,theTitle);
162 }
163
164 TCollection_ExtendedString SALOMEDS_TableOfStringAttribute::GetColumnTitle(const Standard_Integer theColumn) const {
165   if(myCols.IsNull()) return "";
166   if(myCols->Length() < theColumn) return "";
167   return myCols->Value(theColumn);
168 }
169
170
171 Standard_Integer SALOMEDS_TableOfStringAttribute::GetNbRows() const
172 {
173   return myNbRows;
174 }
175
176 Standard_Integer SALOMEDS_TableOfStringAttribute::GetNbColumns() const
177 {
178   return myNbColumns;
179 }
180
181 void SALOMEDS_TableOfStringAttribute::PutValue(const TCollection_ExtendedString& theValue,
182                                                const Standard_Integer theRow,
183                                                const Standard_Integer theColumn) 
184 {
185   if(theColumn > myNbColumns) SetNbColumns(theColumn);
186
187   Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
188   myTable.Bind(anIndex, theValue);
189
190   if(theRow > myNbRows) {
191     while (myRows->Length() < theRow) { // append empty row titles
192       myRows->Append(TCollection_ExtendedString(""));
193     }
194     myNbRows = theRow;
195   }
196 }
197
198 Standard_Boolean SALOMEDS_TableOfStringAttribute::HasValue(const Standard_Integer theRow,
199                                                            const Standard_Integer theColumn) 
200 {
201   Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
202   return myTable.IsBound(anIndex); 
203 }
204
205 TCollection_ExtendedString SALOMEDS_TableOfStringAttribute::GetValue(const Standard_Integer theRow,
206                                                                      const Standard_Integer theColumn) 
207 {
208   Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
209   if(myTable.IsBound(anIndex)) return myTable.Find(anIndex);
210   
211   Standard_Failure::Raise("Invalid cell index");
212   return 0.;
213 }
214
215 const Standard_GUID& SALOMEDS_TableOfStringAttribute::ID() const
216 {
217   return GetID();
218 }
219
220 void SALOMEDS_TableOfStringAttribute::Restore(const Handle(TDF_Attribute)& with) 
221 {
222   Standard_Integer anIndex;
223   Handle(SALOMEDS_TableOfStringAttribute) aTable = Handle(SALOMEDS_TableOfStringAttribute)::DownCast(with);
224
225   myTable.Clear();
226   myCols->Clear();
227   myRows->Clear();
228
229   myTable = aTable->myTable;
230   myNbRows = aTable->myNbRows;
231   myNbColumns = aTable->myNbColumns;
232   myTitle = aTable->myTitle;
233   
234   for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
235     myRows->Append(aTable->GetRowTitle(anIndex));
236
237   for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++) 
238     myCols->Append(aTable->GetColumnTitle(anIndex));
239 }
240
241 Handle(TDF_Attribute) SALOMEDS_TableOfStringAttribute::NewEmpty() const
242 {
243   return new SALOMEDS_TableOfStringAttribute();
244 }
245
246 void SALOMEDS_TableOfStringAttribute::Paste(const Handle(TDF_Attribute)& into,
247                                              const Handle(TDF_RelocationTable)&) const
248 {
249   Standard_Integer anIndex;
250   Handle(SALOMEDS_TableOfStringAttribute) aTable = Handle(SALOMEDS_TableOfStringAttribute)::DownCast(into);
251
252   aTable->myTable.Clear();
253   aTable->myCols->Clear();
254   aTable->myRows->Clear();
255
256   aTable->myTable = myTable;
257   aTable->myTitle = myTitle;
258   aTable->myNbRows = myNbRows;
259   aTable->myNbColumns = myNbColumns;
260
261   for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
262     aTable->myRows->Append(GetRowTitle(anIndex));
263   for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++) 
264     aTable->myCols->Append(GetColumnTitle(anIndex));
265 }
266
267
268 Handle_TColStd_HSequenceOfInteger SALOMEDS_TableOfStringAttribute::GetSetRowIndices(const Standard_Integer theRow)
269 {
270   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
271
272   Standard_Integer i, aShift = myNbColumns*(theRow-1);
273   for(i = 1; i <= myNbColumns; i++) {
274     if(myTable.IsBound(aShift + i)) aSeq->Append(i);
275   }
276   
277   return aSeq;
278 }
279
280 Handle_TColStd_HSequenceOfInteger SALOMEDS_TableOfStringAttribute::GetSetColumnIndices(const Standard_Integer theColumn)
281 {
282   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
283
284   Standard_Integer i, anIndex;
285   for(i = 1; i <= myNbRows; i++) {
286     anIndex = myNbColumns*(i-1)+theColumn;
287     if(myTable.IsBound(anIndex)) aSeq->Append(i);
288   }
289   
290   return aSeq;
291 }
292
293
294
295 void SALOMEDS_TableOfStringAttribute::ConvertToString(ostrstream& theStream)
296 {
297   int i, j, l;
298   
299   //Title
300   l = myTitle.Length();
301   theStream << l << "\n";
302   for(i=1; i<=l; i++)
303     theStream << myTitle.Value(i) << "\n";
304
305   //Nb rows
306   theStream << myNbRows << "\n";
307
308   //Rows titles
309   for(i=1; i<=myNbRows; i++) {
310     l = myRows->Value(i).Length();
311     theStream << l << "\n";
312     for(j=1; j<=l; j++)
313       theStream << myRows->Value(i).Value(j) << "\n";
314   }
315
316   //Nb columns
317   theStream << myNbColumns << "\n";
318
319   //Columns titles
320   for(i=1; i<=myNbColumns; i++) {
321     l = myCols->Value(i).Length();
322     theStream << l << "\n";
323     for(j=1; j<=l; j++)
324       theStream << myCols->Value(i).Value(j) << "\n";
325   }
326
327   //Store the table values
328   l = myTable.Extent();
329   theStream << l << "\n";
330   SALOMEDS_DataMapIteratorOfDataMapOfIntegerString anIterator(myTable);
331   for(; anIterator.More(); anIterator.Next()) {
332     if (anIterator.Value().Length()) { // check empty string in the value table
333       theStream << anIterator.Key() << "\n";
334       unsigned long aValueSize = anIterator.Value().Length();
335       theStream.write((char*)&aValueSize, sizeof(unsigned long));
336       theStream.write((TCollection_AsciiString(anIterator.Value()).ToCString()),aValueSize);
337     } else { // write index only of kind: "0key"; "05", for an example
338       theStream << "0" << anIterator.Key() << "\n";
339     }
340   }
341   return;
342 }
343
344 bool SALOMEDS_TableOfStringAttribute::RestoreFromString(istrstream& theStream)
345 {
346   Backup();
347
348   theStream.seekg(0, ios::end);
349   long aSize = theStream.tellg();
350   theStream.seekg(0, ios::beg);
351
352   int i, j, l;
353   char *aValueString = new char[aSize];
354
355   Standard_ExtCharacter anExtChar;
356   TCollection_ExtendedString aStr;
357
358   //Title
359   theStream >> l;
360
361   myTitle = TCollection_ExtendedString(l, 0);
362   for(i=1; i<=l; i++) {
363     theStream >> anExtChar;
364     myTitle.SetValue(i, anExtChar);
365   }
366
367   //Nb rows
368   theStream >> myNbRows;
369
370   //Rows titles
371   myRows->Clear();  
372   for(i=1; i<=myNbRows; i++) { 
373     theStream >> l;
374     aStr = TCollection_ExtendedString(l,0);
375     for(j=1; j<=l; j++) {
376       theStream >> anExtChar;
377       aStr.SetValue(j, anExtChar);
378     }
379     myRows->Append(aStr);
380   }
381
382   //Nb columns
383   theStream >> myNbColumns;
384
385   //Columns titles
386   myCols->Clear();
387   for(i=1; i<=myNbColumns; i++) {
388     theStream >> l;
389     aStr = TCollection_ExtendedString(l,0);
390     for(j=1; j<=l; j++) {
391       theStream >> anExtChar;
392       aStr.SetValue(j, anExtChar);
393     }
394     myCols->Append(aStr);
395   }
396
397   //Restore the table values
398   TCollection_AsciiString aValue;
399   theStream >> l;
400   myTable.Clear();
401   theStream.getline(aValueString,aSize,'\n');
402   for(i=1; i<=l; i++) {
403     Standard_Integer aKey;
404
405     theStream.getline(aValueString,aSize,'\n');
406     aValue = aValueString;
407     aKey = aValue.IntegerValue();
408     if (aValue.Value(1) == '0')
409       aValue = "";
410     else {
411       unsigned long aValueSize;
412       theStream.read((char*)&aValueSize, sizeof(unsigned long));
413       theStream.read(aValueString, aValueSize);
414       aValue = aValueString;
415     }
416     myTable.Bind(aKey, aValue);
417   }
418   delete(aValueString);
419   return true;
420 }