Salome HOME
sources v1.2
[modules/yacs.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     SetRowTitle(anIndex,aTable->GetRowTitle(anIndex));
236   }
237   for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++) 
238     SetColumnTitle(anIndex, 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->SetRowTitle(anIndex,GetRowTitle(anIndex));
263   }
264   for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++) 
265     aTable->SetColumnTitle(anIndex, GetColumnTitle(anIndex));
266 }
267
268
269 Handle_TColStd_HSequenceOfInteger SALOMEDS_TableOfStringAttribute::GetSetRowIndices(const Standard_Integer theRow)
270 {
271   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
272
273   Standard_Integer i, aShift = myNbColumns*(theRow-1);
274   for(i = 1; i <= myNbColumns; i++) {
275     if(myTable.IsBound(aShift + i)) aSeq->Append(i);
276   }
277   
278   return aSeq;
279 }
280
281 Handle_TColStd_HSequenceOfInteger SALOMEDS_TableOfStringAttribute::GetSetColumnIndices(const Standard_Integer theColumn)
282 {
283   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
284
285   Standard_Integer i, anIndex;
286   for(i = 1; i <= myNbRows; i++) {
287     anIndex = myNbColumns*(i-1)+theColumn;
288     if(myTable.IsBound(anIndex)) aSeq->Append(i);
289   }
290   
291   return aSeq;
292 }
293
294
295
296 void SALOMEDS_TableOfStringAttribute::ConvertToString(ostrstream& theStream)
297 {
298   int i, j, l;
299   
300   //Title
301   l = myTitle.Length();
302   theStream << l << "\n";
303   for(i=1; i<=l; i++)
304     theStream << myTitle.Value(i) << "\n";
305
306   //Nb rows
307   theStream << myNbRows << "\n";
308
309   //Rows titles
310   for(i=1; i<=myNbRows; i++) {
311     l = myRows->Value(i).Length();
312     theStream << l << "\n";
313     for(j=1; j<=l; j++)
314       theStream << myRows->Value(i).Value(j) << "\n";
315   }
316
317   //Nb columns
318   theStream << myNbColumns << "\n";
319
320   //Columns titles
321   for(i=1; i<=myNbColumns; i++) {
322     l = myCols->Value(i).Length();
323     theStream << l << "\n";
324     for(j=1; j<=l; j++)
325       theStream << myCols->Value(i).Value(j) << "\n";
326   }
327
328   //Store the table values
329   l = myTable.Extent();
330   theStream << l << "\n";
331   SALOMEDS_DataMapIteratorOfDataMapOfIntegerString anIterator(myTable);
332   for(; anIterator.More(); anIterator.Next()) {
333     if (anIterator.Value().Length()) { // check empty string in the value table
334       theStream << anIterator.Key() << "\n";
335       unsigned long aValueSize = anIterator.Value().Length();
336       theStream.write((char*)&aValueSize, sizeof(unsigned long));
337       theStream.write((TCollection_AsciiString(anIterator.Value()).ToCString()),aValueSize);
338     } else { // write index only of kind: "0key"; "05", for an example
339       theStream << "0" << anIterator.Key() << "\n";
340     }
341   }
342   return;
343 }
344
345 bool SALOMEDS_TableOfStringAttribute::RestoreFromString(istrstream& theStream)
346 {
347   Backup();
348
349   theStream.seekg(0, ios::end);
350   long aSize = theStream.tellg();
351   theStream.seekg(0, ios::beg);
352
353   int i, j, l;
354   char *aValueString = new char[aSize];
355
356   Standard_ExtCharacter anExtChar;
357   TCollection_ExtendedString aStr;
358
359   //Title
360   theStream >> l;
361
362   myTitle = TCollection_ExtendedString(l, 0);
363   for(i=1; i<=l; i++) {
364     theStream >> anExtChar;
365     myTitle.SetValue(i, anExtChar);
366   }
367
368   //Nb rows
369   theStream >> myNbRows;
370
371   //Rows titles
372   myRows->Clear();  
373   for(i=1; i<=myNbRows; i++) { 
374     theStream >> l;
375     aStr = TCollection_ExtendedString(l,0);
376     for(j=1; j<=l; j++) {
377       theStream >> anExtChar;
378       aStr.SetValue(j, anExtChar);
379     }
380     myRows->Append(aStr);
381   }
382
383   //Nb columns
384   theStream >> myNbColumns;
385
386   //Columns titles
387   myCols->Clear();
388   for(i=1; i<=myNbColumns; i++) {
389     theStream >> l;
390     aStr = TCollection_ExtendedString(l,0);
391     for(j=1; j<=l; j++) {
392       theStream >> anExtChar;
393       aStr.SetValue(j, anExtChar);
394     }
395     myCols->Append(aStr);
396   }
397
398   //Restore the table values
399   TCollection_AsciiString aValue;
400   theStream >> l;
401   myTable.Clear();
402   theStream.getline(aValueString,aSize,'\n');
403   for(i=1; i<=l; i++) {
404     Standard_Integer aKey;
405
406     theStream.getline(aValueString,aSize,'\n');
407     aValue = aValueString;
408     aKey = aValue.IntegerValue();
409     if (aValue.Value(1) == '0')
410       aValue = "";
411     else {
412       unsigned long aValueSize;
413       theStream.read((char*)&aValueSize, sizeof(unsigned long));
414       theStream.read(aValueString, aValueSize);
415       aValue = aValueString;
416     }
417     myTable.Bind(aKey, aValue);
418   }
419   delete(aValueString);
420   return true;
421 }