Salome HOME
Copyrights update
[modules/yacs.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeTableOfString.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/
19 //
20 //  File   : SALOMEDSImpl_AttributeTableOfString.cxx
21 //  Author : Sergey Ruin
22 //  Module : SALOME
23
24 #include <SALOMEDSImpl_AttributeTableOfString.hxx>
25 #include <Standard_Failure.hxx>
26 #include <Standard_GUID.hxx>
27 #include <stdio.h>
28 #include <TColStd_HSequenceOfExtendedString.hxx>  
29
30 using namespace std;
31
32 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_AttributeTableOfString, SALOMEDSImpl_GenericAttribute )
33 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_AttributeTableOfString, SALOMEDSImpl_GenericAttribute )
34
35 typedef NCollection_DataMap<Standard_Integer, TCollection_ExtendedString>::Iterator DataMapIterator;
36
37 #define SEPARATOR '\1'
38
39 static TCollection_ExtendedString getUnit(TCollection_ExtendedString theString)
40 {
41   TCollection_ExtendedString aString(theString);
42   int aPos = aString.Search(SEPARATOR);
43   if(aPos <= 0 || aPos == aString.Length() ) return TCollection_ExtendedString();
44   return aString.Split(aPos);
45 }
46
47 static TCollection_ExtendedString getTitle(TCollection_ExtendedString theString)
48 {
49   TCollection_ExtendedString aString(theString);
50   int aPos = aString.Search(SEPARATOR);
51   if(aPos < 1) return aString;
52   if(aPos == 1) return TCollection_ExtendedString();
53   aString.Split(aPos-1);
54   return aString;
55 }
56
57 const Standard_GUID& SALOMEDSImpl_AttributeTableOfString::GetID() 
58 {
59   static Standard_GUID SALOMEDSImpl_AttributeTableOfStringID ("128371A4-8F52-11d6-A8A3-0001021E8C7F");
60   return SALOMEDSImpl_AttributeTableOfStringID;
61 }
62
63 Handle(SALOMEDSImpl_AttributeTableOfString) SALOMEDSImpl_AttributeTableOfString::Set(const TDF_Label& label) 
64 {
65   Handle(SALOMEDSImpl_AttributeTableOfString) anAttr;
66   if (!label.FindAttribute(SALOMEDSImpl_AttributeTableOfString::GetID(),anAttr)) {
67     anAttr = new SALOMEDSImpl_AttributeTableOfString();
68     label.AddAttribute(anAttr);
69   }
70   return anAttr;
71 }
72
73 SALOMEDSImpl_AttributeTableOfString::SALOMEDSImpl_AttributeTableOfString() 
74 :SALOMEDSImpl_GenericAttribute("AttributeTableOfString")
75 {
76   myRows = new TColStd_HSequenceOfExtendedString();
77   myCols = new TColStd_HSequenceOfExtendedString();
78   myNbRows = 0;
79   myNbColumns = 0;
80 }
81
82 void SALOMEDSImpl_AttributeTableOfString::SetNbColumns(const Standard_Integer theNbColumns)
83 {
84   CheckLocked();  
85   Backup();
86   
87   DataMapOfIntegerString aMap;
88   aMap = myTable;
89   myTable.Clear();
90
91   DataMapIterator anIterator(aMap);
92   for(; anIterator.More(); anIterator.Next()) {
93     int aRow = (int)(anIterator.Key()/myNbColumns) + 1;
94     int aCol = (int)(anIterator.Key() - myNbColumns*(aRow-1));
95     if(aCol == 0) { aCol = myNbColumns; aRow--; }
96     if(aCol > theNbColumns) continue;
97     int aKey = (aRow-1)*theNbColumns+aCol;
98     myTable.Bind(aKey, anIterator.Value());
99   }
100
101   myNbColumns = theNbColumns;
102
103   while (myCols->Length() < myNbColumns) { // append empty columns titles
104     myCols->Append(TCollection_ExtendedString(""));
105   }
106
107   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
108 }
109
110 void SALOMEDSImpl_AttributeTableOfString::SetRowTitle(const Standard_Integer theRow,
111                                                       const TCollection_ExtendedString& theTitle) 
112 {
113   CheckLocked();  
114   Backup();
115   TCollection_ExtendedString aTitle(theTitle), aUnit = GetRowUnit(theRow);
116   if(aUnit.Length()>0) {
117     aTitle += SEPARATOR;
118     aTitle += aUnit;
119   }
120   myRows->SetValue(theRow, aTitle);
121   
122   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
123 }
124
125 void SALOMEDSImpl_AttributeTableOfString::SetRowUnit(const Standard_Integer theRow,
126                                                       const TCollection_ExtendedString& theUnit) 
127 {
128   CheckLocked();  
129   Backup();
130   TCollection_ExtendedString aTitle = GetRowTitle(theRow);
131   aTitle += SEPARATOR;
132   aTitle += theUnit;
133
134   myRows->SetValue(theRow, aTitle);
135   
136   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
137 }
138
139 void SALOMEDSImpl_AttributeTableOfString::SetRowUnits(const Handle(TColStd_HSequenceOfExtendedString)& theUnits)
140 {
141   if (theUnits->Length() != GetNbRows()) Standard_Failure::Raise("Invalid number of rows");
142   int aLength = theUnits->Length(), i;
143   for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits->Value(i));
144 }
145
146 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetRowUnits()
147 {
148   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
149   int aLength = myRows->Length(), i;
150   for(i=1; i<=aLength; i++) aSeq->Append(getUnit(myRows->Value(i)));
151   return aSeq;
152 }
153
154 void SALOMEDSImpl_AttributeTableOfString::SetRowTitles(const Handle(TColStd_HSequenceOfExtendedString)& theTitles)
155 {
156   if (theTitles->Length() != GetNbRows()) Standard_Failure::Raise("Invalid number of rows");
157   int aLength = theTitles->Length(), i;
158   for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles->Value(i));
159   
160   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
161 }
162
163 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetRowTitles()
164 {
165   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
166   int aLength = myRows->Length(), i;
167   for(i=1; i<=aLength; i++) aSeq->Append(getTitle(myRows->Value(i)));
168   return aSeq;
169 }
170
171
172 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetRowTitle(const Standard_Integer theRow) const 
173 {
174   return getTitle(myRows->Value(theRow));
175 }
176
177
178 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetRowUnit(const Standard_Integer theRow) const 
179 {
180   return getUnit(myRows->Value(theRow));
181 }
182
183 void SALOMEDSImpl_AttributeTableOfString::SetRowData(const Standard_Integer theRow,
184                                                      const Handle(TColStd_HSequenceOfExtendedString)& theData) 
185 {
186   CheckLocked();  
187   if(theData->Length() > myNbColumns) SetNbColumns(theData->Length());
188
189   Backup();
190
191   while (myRows->Length() < theRow) { // append new row titles
192     myRows->Append(TCollection_ExtendedString(""));
193   }
194
195   Standard_Integer i, aShift = (theRow-1)*myNbColumns, aLength = theData->Length();
196   for(i = 1; i <= aLength; i++) {
197     myTable.Bind(aShift + i, theData->Value(i));
198   }
199
200   if(theRow > myNbRows) myNbRows = theRow;
201   
202   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
203 }
204
205 void SALOMEDSImpl_AttributeTableOfString::SetTitle(const TCollection_ExtendedString& theTitle) 
206 {
207   CheckLocked();  
208   Backup();
209   myTitle = theTitle;
210   
211   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
212 }
213
214 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetTitle() const 
215 {
216   return myTitle;
217 }
218
219 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetRowData(const Standard_Integer theRow)
220 {
221   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString();
222   Standard_Integer i, aShift = (theRow-1)*myNbColumns;
223   for(i = 1; i <= myNbColumns; i++) {
224      if(myTable.IsBound(aShift+i)) 
225        aSeq->Append(myTable.Find(aShift+i));
226      else
227        aSeq->Append(0.);
228   }
229   
230   return aSeq;
231 }
232
233 void SALOMEDSImpl_AttributeTableOfString::SetColumnData(const Standard_Integer theColumn,
234                                                         const Handle(TColStd_HSequenceOfExtendedString)& theData) 
235 {
236   CheckLocked();  
237   if(theColumn > myNbColumns) SetNbColumns(theColumn);
238
239   Backup();
240
241   Standard_Integer i, aLength = theData->Length();
242   for(i = 1; i <= aLength; i++) {
243     myTable.Bind(myNbColumns*(i-1)+theColumn, theData->Value(i));
244   }
245
246   if(aLength > myNbRows) {
247     myNbRows = aLength;
248     while (myRows->Length() < myNbRows) { // append empty row titles
249       myRows->Append(TCollection_ExtendedString(""));
250     }
251   }
252   
253   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
254 }
255
256
257 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetColumnData(const Standard_Integer theColumn)
258 {
259   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
260   
261   Standard_Integer i, anIndex;
262   for(i = 1; i <= myNbRows; i++) {
263     anIndex = myNbColumns*(i-1) + theColumn;
264     if(myTable.IsBound(anIndex)) 
265       aSeq->Append(myTable.Find(anIndex));
266     else
267       aSeq->Append(0.);
268   }
269   
270   return aSeq;
271 }
272
273 void SALOMEDSImpl_AttributeTableOfString::SetColumnTitle(const Standard_Integer theColumn,
274                                                          const TCollection_ExtendedString& theTitle) 
275 {
276   CheckLocked();  
277   Backup();
278   while(myCols->Length() < theColumn) myCols->Append(TCollection_ExtendedString(""));
279   myCols->SetValue(theColumn,theTitle);
280   
281   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
282 }
283
284 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetColumnTitle(const Standard_Integer theColumn) const 
285 {
286   if(myCols.IsNull()) return "";
287   if(myCols->Length() < theColumn) return "";
288   return myCols->Value(theColumn);
289 }
290
291
292 void SALOMEDSImpl_AttributeTableOfString::SetColumnTitles(const Handle(TColStd_HSequenceOfExtendedString)& theTitles)
293 {
294   if (theTitles->Length() != myNbColumns) Standard_Failure::Raise("Invalid number of columns");
295   int aLength = theTitles->Length(), i;
296   for(i = 1; i <= aLength; i++)  myCols->SetValue(i, theTitles->Value(i));
297   
298   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
299 }
300
301 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetColumnTitles()
302 {
303   Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
304   int aLength = myCols->Length(), i;
305   for(i=1; i<=aLength; i++) aSeq->Append(myCols->Value(i));
306   return aSeq;
307 }
308
309
310 Standard_Integer SALOMEDSImpl_AttributeTableOfString::GetNbRows() const
311 {
312   return myNbRows;
313 }
314
315 Standard_Integer SALOMEDSImpl_AttributeTableOfString::GetNbColumns() const
316 {
317   return myNbColumns;
318 }
319
320 void SALOMEDSImpl_AttributeTableOfString::PutValue(const TCollection_ExtendedString& theValue,
321                                                    const Standard_Integer theRow,
322                                                    const Standard_Integer theColumn) 
323 {
324   CheckLocked();  
325   if(theColumn > myNbColumns) SetNbColumns(theColumn);
326
327   Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
328   myTable.Bind(anIndex, theValue);
329
330   if(theRow > myNbRows) {
331     while (myRows->Length() < theRow) { // append empty row titles
332       myRows->Append(TCollection_ExtendedString(""));
333     }
334     myNbRows = theRow;
335   }
336   
337   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
338 }
339
340 Standard_Boolean SALOMEDSImpl_AttributeTableOfString::HasValue(const Standard_Integer theRow,
341                                                                const Standard_Integer theColumn) 
342 {
343   if(theRow > myNbRows || theRow < 1) return Standard_False;
344   if(theColumn > myNbColumns || theColumn < 1) return Standard_False;
345
346   Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
347   return myTable.IsBound(anIndex); 
348 }
349
350 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetValue(const Standard_Integer theRow,
351                                                                          const Standard_Integer theColumn) 
352 {
353   if(theRow > myNbRows || theRow < 1) Standard_Failure::Raise("Invalid cell index");
354   if(theColumn > myNbColumns || theColumn < 1) Standard_Failure::Raise("Invalid cell index");
355
356   Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
357   if(myTable.IsBound(anIndex)) return myTable.Find(anIndex);
358   
359   Standard_Failure::Raise("Invalid cell index");
360   return 0.;
361 }
362
363 const Standard_GUID& SALOMEDSImpl_AttributeTableOfString::ID() const
364 {
365   return GetID();
366 }
367
368 void SALOMEDSImpl_AttributeTableOfString::Restore(const Handle(TDF_Attribute)& with) 
369 {
370   Standard_Integer anIndex;
371   Handle(SALOMEDSImpl_AttributeTableOfString) aTable = Handle(SALOMEDSImpl_AttributeTableOfString)::DownCast(with);
372
373   myTable.Clear();
374   myCols->Clear();
375   myRows->Clear();
376
377   myTable = aTable->myTable;
378   myNbRows = aTable->myNbRows;
379   myNbColumns = aTable->myNbColumns;
380   myTitle = aTable->myTitle;
381   
382   for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
383     myRows->Append(aTable->GetRowTitle(anIndex));
384
385   for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++) 
386     myCols->Append(aTable->GetColumnTitle(anIndex));
387 }
388
389 Handle(TDF_Attribute) SALOMEDSImpl_AttributeTableOfString::NewEmpty() const
390 {
391   return new SALOMEDSImpl_AttributeTableOfString();
392 }
393
394 void SALOMEDSImpl_AttributeTableOfString::Paste(const Handle(TDF_Attribute)& into,
395                                              const Handle(TDF_RelocationTable)&) const
396 {
397   Standard_Integer anIndex;
398   Handle(SALOMEDSImpl_AttributeTableOfString) aTable = Handle(SALOMEDSImpl_AttributeTableOfString)::DownCast(into);
399
400   aTable->myTable.Clear();
401   aTable->myCols->Clear();
402   aTable->myRows->Clear();
403
404   aTable->myTable = myTable;
405   aTable->myTitle = myTitle;
406   aTable->myNbRows = myNbRows;
407   aTable->myNbColumns = myNbColumns;
408
409   for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
410     aTable->myRows->Append(GetRowTitle(anIndex));
411   for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++) 
412     aTable->myCols->Append(GetColumnTitle(anIndex));
413 }
414
415
416 Handle_TColStd_HSequenceOfInteger SALOMEDSImpl_AttributeTableOfString::GetSetRowIndices(const Standard_Integer theRow)
417 {
418   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
419
420   Standard_Integer i, aShift = myNbColumns*(theRow-1);
421   for(i = 1; i <= myNbColumns; i++) {
422     if(myTable.IsBound(aShift + i)) aSeq->Append(i);
423   }
424   
425   return aSeq;
426 }
427
428 Handle_TColStd_HSequenceOfInteger SALOMEDSImpl_AttributeTableOfString::GetSetColumnIndices(const Standard_Integer theColumn)
429 {
430   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
431
432   Standard_Integer i, anIndex;
433   for(i = 1; i <= myNbRows; i++) {
434     anIndex = myNbColumns*(i-1)+theColumn;
435     if(myTable.IsBound(anIndex)) aSeq->Append(i);
436   }
437   
438   return aSeq;
439 }
440
441
442
443 void SALOMEDSImpl_AttributeTableOfString::ConvertToString(ostrstream& theStream)
444 {
445   int i, j, l;
446   
447   //Title
448   l = myTitle.Length();
449   theStream << l << "\n";
450   for(i=1; i<=l; i++)
451     theStream << myTitle.Value(i) << "\n";
452
453   //Nb rows
454   theStream << myNbRows << "\n";
455
456   //Rows titles
457   for(i=1; i<=myNbRows; i++) {
458     l = myRows->Value(i).Length();
459     theStream << l << "\n";
460     for(j=1; j<=l; j++)
461       theStream << myRows->Value(i).Value(j) << "\n";
462   }
463
464   //Nb columns
465   theStream << myNbColumns << "\n";
466
467   //Columns titles
468   for(i=1; i<=myNbColumns; i++) {
469     l = myCols->Value(i).Length();
470     theStream << l << "\n";
471     for(j=1; j<=l; j++)
472       theStream << myCols->Value(i).Value(j) << "\n";
473   }
474
475   //Store the table values
476   l = myTable.Extent();
477   theStream << l << "\n";
478   DataMapIterator anIterator(myTable);
479   for(; anIterator.More(); anIterator.Next()) {
480     if (anIterator.Value().Length()) { // check empty string in the value table
481       theStream << anIterator.Key() << "\n";
482       unsigned long aValueSize = anIterator.Value().Length();
483       theStream<<aValueSize << "\n";
484       theStream.write((TCollection_AsciiString(anIterator.Value()).ToCString()),aValueSize);
485       theStream<<"\n";
486     } else { // write index only of kind: "0key"; "05", for an example
487       theStream << "0" << anIterator.Key() << "\n";
488     }
489   }
490   return;
491 }
492
493 bool SALOMEDSImpl_AttributeTableOfString::RestoreFromString(istrstream& theStream)
494 {
495   Backup();
496
497   theStream.seekg(0, ios::end);
498   long aSize = theStream.tellg();
499   theStream.seekg(0, ios::beg);
500
501   int i, j, l;
502   char *aValueString = new char[aSize];
503
504   Standard_ExtCharacter anExtChar;
505   TCollection_ExtendedString aStr;
506
507   //Title
508   theStream >> l;
509
510   myTitle = TCollection_ExtendedString(l, 0);
511   for(i=1; i<=l; i++) {
512     theStream >> anExtChar;
513     myTitle.SetValue(i, anExtChar);
514   }
515
516   //Nb rows
517   theStream >> myNbRows;
518
519   //Rows titles
520   myRows->Clear();  
521   for(i=1; i<=myNbRows; i++) { 
522     theStream >> l;
523     aStr = TCollection_ExtendedString(l,0);
524     for(j=1; j<=l; j++) {
525       theStream >> anExtChar;
526       aStr.SetValue(j, anExtChar);
527     }
528     myRows->Append(aStr);
529   }
530
531   //Nb columns
532   theStream >> myNbColumns;
533
534   //Columns titles
535   myCols->Clear();
536   for(i=1; i<=myNbColumns; i++) {
537     theStream >> l;
538     aStr = TCollection_ExtendedString(l,0);
539     for(j=1; j<=l; j++) {
540       theStream >> anExtChar;
541       aStr.SetValue(j, anExtChar);
542     }
543     myCols->Append(aStr);
544   }
545
546   //Restore the table values
547   TCollection_AsciiString aValue;
548   theStream >> l;
549   myTable.Clear();
550   theStream.getline(aValueString,aSize,'\n');
551   for(i=1; i<=l; i++) {
552     Standard_Integer aKey;
553
554     theStream.getline(aValueString,aSize,'\n');
555     aValue = aValueString;
556     aKey = aValue.IntegerValue();
557     if (aValue.Value(1) == '0')
558       aValue = "";
559     else {
560       unsigned long aValueSize;
561       theStream >> aValueSize;
562       theStream.read(aValueString, 1); // an '\n' omitting
563       theStream.read(aValueString, aValueSize);
564       theStream.read(aValueString, 1); // an '\n' omitting
565       aValue = aValueString;
566     }
567     myTable.Bind(aKey, aValue);
568   }
569   delete(aValueString);
570   return true;
571 }
572
573 TCollection_AsciiString SALOMEDSImpl_AttributeTableOfString::Save() 
574 {
575   ostrstream ostr;
576   ConvertToString(ostr);
577   TCollection_AsciiString aString((char*)ostr.rdbuf()->str());
578   return aString;
579 }
580
581 void SALOMEDSImpl_AttributeTableOfString::Load(const TCollection_AsciiString& value) 
582 {
583   istrstream aStream(value.ToCString(), strlen(value.ToCString()));
584   RestoreFromString(aStream);
585 }