Salome HOME
BugID: IPAL19426 Fixed methods Save/Load
[modules/yacs.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeTableOfInteger.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/ or email : webmaster.salome@opencascade.com
19 //
20 //  File   : SALOMEDSImpl_AttributeTableOfInteger.cxx
21 //  Author : Michael Ponikarov
22 //  Module : SALOME
23
24 #include "SALOMEDSImpl_AttributeTableOfInteger.hxx"
25 #include <strstream>
26
27 using namespace std;
28
29 #define SEPARATOR '\1'
30 typedef map<int, int>::const_iterator MI;
31
32 static std::string getUnit(std::string theString)
33 {
34   std::string aString(theString);
35   int aPos = aString.find(SEPARATOR);
36   if(aPos <= 0 || aPos == aString.size() ) return std::string();
37   return aString.substr(aPos+1, aString.size());
38 }
39
40 static std::string getTitle(std::string theString)
41 {
42   std::string aString(theString);
43   int aPos = aString.find(SEPARATOR);
44   if(aPos < 1) return aString;
45   if(aPos == 0) return std::string();
46   return aString.substr(0, aPos);
47 }
48
49 const std::string& SALOMEDSImpl_AttributeTableOfInteger::GetID() 
50 {
51   static std::string SALOMEDSImpl_AttributeTableOfIntegerID ("128371A0-8F52-11d6-A8A3-0001021E8C7F");
52   return SALOMEDSImpl_AttributeTableOfIntegerID;
53 }
54
55 SALOMEDSImpl_AttributeTableOfInteger* SALOMEDSImpl_AttributeTableOfInteger::Set(const DF_Label& label) 
56 {
57   SALOMEDSImpl_AttributeTableOfInteger* A = NULL;
58   if (!(A=(SALOMEDSImpl_AttributeTableOfInteger*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfInteger::GetID()))) {
59     A = new SALOMEDSImpl_AttributeTableOfInteger();
60     label.AddAttribute(A);
61   }
62   return A;
63 }
64
65 SALOMEDSImpl_AttributeTableOfInteger::SALOMEDSImpl_AttributeTableOfInteger() 
66 :SALOMEDSImpl_GenericAttribute("AttributeTableOfInteger")
67 {
68   myNbRows = 0;
69   myNbColumns = 0;
70 }
71
72 void SALOMEDSImpl_AttributeTableOfInteger::SetNbColumns(const int theNbColumns)
73 {
74   CheckLocked();  
75   Backup();
76   
77   map<int, int> aMap;
78   aMap = myTable;
79   myTable.clear();
80
81   
82   for(MI p = aMap.begin(); p != aMap.end(); p++) {
83     int aRow = (int)(p->first/myNbColumns) + 1;
84     int aCol = (int)(p->first - myNbColumns*(aRow-1));
85     if(aCol == 0) { aCol = myNbColumns; aRow--; }
86     if(aCol > theNbColumns) continue;
87     int aKey = (aRow-1)*theNbColumns+aCol;
88     myTable[aKey] = p->second;
89   }
90
91   myNbColumns = theNbColumns;
92
93   while (myCols.size() < myNbColumns) { // append empty columns titles
94     myCols.push_back(std::string(""));
95   }
96
97   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
98
99 }
100
101 void SALOMEDSImpl_AttributeTableOfInteger::SetTitle(const std::string& theTitle) 
102 {
103   CheckLocked();  
104   Backup();
105   myTitle = theTitle;
106   
107   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
108 }
109
110 std::string SALOMEDSImpl_AttributeTableOfInteger::GetTitle() const 
111 {
112   return myTitle;
113 }
114
115 void SALOMEDSImpl_AttributeTableOfInteger::SetRowData(const int theRow,
116                                                       const vector<int>& theData) 
117 {
118   CheckLocked();  
119   if(theData.size() > myNbColumns) SetNbColumns(theData.size());
120
121   Backup();
122
123   while (myRows.size() < theRow) { // append new row titles
124     myRows.push_back(std::string(""));
125   }
126
127   int i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
128   for(i = 1; i <= aLength; i++) {
129     myTable[aShift + i] = theData[i-1];
130   }
131
132   if(theRow > myNbRows) myNbRows = theRow;
133   
134   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
135 }
136
137 vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetRowData(const int theRow)
138 {
139   vector<int> aSeq;
140   int i, aShift = (theRow-1)*myNbColumns;
141   for(i = 1; i <= myNbColumns; i++) {
142      if(myTable.find(aShift+i) != myTable.end()) 
143        aSeq.push_back(myTable[aShift+i]);
144      else
145        aSeq.push_back(0);
146   }
147   
148   return aSeq;
149 }
150
151 void SALOMEDSImpl_AttributeTableOfInteger::SetRowTitle(const int theRow,
152                                                        const std::string& theTitle) 
153 {
154   CheckLocked();  
155   Backup();
156   string aTitle(theTitle), aUnit = GetRowUnit(theRow);
157   if(aUnit.size()>0) {
158     aTitle += SEPARATOR;
159     aTitle += aUnit;
160   }
161   myRows[theRow-1] =  aTitle;
162   
163   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
164 }
165
166 void SALOMEDSImpl_AttributeTableOfInteger::SetRowUnit(const int theRow,
167                                                       const std::string& theUnit) 
168 {
169   CheckLocked();  
170   Backup();
171   std::string aTitle = GetRowTitle(theRow);
172   aTitle += SEPARATOR;
173   aTitle += theUnit;
174
175   myRows[theRow-1] = aTitle;
176   
177   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
178 }
179
180 void SALOMEDSImpl_AttributeTableOfInteger::SetRowUnits(const vector<string>& theUnits)
181 {
182   if (theUnits.size() != GetNbRows()) throw DFexception("Invalid number of rows");
183   int aLength = theUnits.size(), i;
184   for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits[i-1]);
185   
186   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
187 }
188
189 vector<string> SALOMEDSImpl_AttributeTableOfInteger::GetRowUnits()
190 {
191   vector<string> aSeq;
192   int aLength = myRows.size(), i;
193   for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
194   return aSeq;
195 }
196
197 void SALOMEDSImpl_AttributeTableOfInteger::SetRowTitles(const vector<string>& theTitles)
198 {
199   if (theTitles.size() != GetNbRows()) throw DFexception("Invalid number of rows");
200   int aLength = theTitles.size(), i;
201   for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles[i-1]);
202   
203   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
204 }
205
206 vector<string> SALOMEDSImpl_AttributeTableOfInteger::GetRowTitles()
207 {
208   vector<string> aSeq;
209   int aLength = myRows.size(), i;
210   for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
211   return aSeq;
212 }
213
214
215 std::string SALOMEDSImpl_AttributeTableOfInteger::GetRowTitle(const int theRow) const 
216 {
217   return getTitle(myRows[theRow-1]);
218 }
219
220
221 std::string SALOMEDSImpl_AttributeTableOfInteger::GetRowUnit(const int theRow) const 
222 {
223   return getUnit(myRows[theRow-1]);
224 }
225
226
227 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnData(const int theColumn,
228                                                          const vector<int>& theData) 
229 {
230   CheckLocked();  
231   if(theColumn > myNbColumns) SetNbColumns(theColumn);
232
233   Backup();
234
235   int i, aLength = theData.size();
236   for(i = 1; i <= aLength; i++) {
237     myTable[myNbColumns*(i-1)+theColumn] = theData[i-1];
238   }
239
240   if(aLength > myNbRows) {
241     myNbRows = aLength;
242     while (myRows.size() < myNbRows) { // append empty row titles
243       myRows.push_back(std::string(""));
244     }
245   }
246   
247   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
248 }
249
250
251 vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetColumnData(const int theColumn)
252 {
253   vector<int> aSeq;
254   int i, anIndex;
255   for(i = 1; i <= myNbRows; i++) {
256     anIndex = myNbColumns*(i-1) + theColumn;
257     if(myTable.find(anIndex) != myTable.end()) 
258       aSeq.push_back(myTable[anIndex]);
259     else
260       aSeq.push_back(0);
261   }
262   
263   return aSeq;
264 }
265
266 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnTitle(const int theColumn,
267                                                       const std::string& theTitle) 
268 {
269   CheckLocked();                                                      
270   Backup();
271   while(myCols.size() < theColumn) myCols.push_back(std::string(""));
272   myCols[theColumn-1] = theTitle;
273   
274   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
275 }
276
277 std::string SALOMEDSImpl_AttributeTableOfInteger::GetColumnTitle(const int theColumn) const 
278 {
279   if(myCols.empty()) return "";
280   if(myCols.size() < theColumn) return "";
281   return myCols[theColumn-1];
282 }
283
284 void SALOMEDSImpl_AttributeTableOfInteger::SetColumnTitles(const vector<string>& theTitles)
285 {
286   if (theTitles.size() != myNbColumns) throw DFexception("Invalid number of columns");
287   int aLength = theTitles.size(), i;
288   for(i = 0; i < aLength; i++)  myCols[i] = theTitles[i];
289   
290   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
291 }
292
293 vector<string> SALOMEDSImpl_AttributeTableOfInteger::GetColumnTitles()
294 {
295   vector<string> aSeq;
296   int aLength = myCols.size(), i;
297   for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
298   return aSeq;
299 }
300
301 int SALOMEDSImpl_AttributeTableOfInteger::GetNbRows() const
302 {
303   return myNbRows;
304 }
305
306 int SALOMEDSImpl_AttributeTableOfInteger::GetNbColumns() const
307 {
308   return myNbColumns;
309 }
310
311 void SALOMEDSImpl_AttributeTableOfInteger::PutValue(const int theValue,
312                                                     const int theRow,
313                                                     const int theColumn) 
314 {
315   CheckLocked();  
316   if(theColumn > myNbColumns) SetNbColumns(theColumn);
317
318   int anIndex = (theRow-1)*myNbColumns + theColumn;
319   myTable[anIndex] = theValue;
320
321   if(theRow > myNbRows) {
322     while (myRows.size() < theRow) { // append empty row titles
323       myRows.push_back(std::string(""));
324     }
325     myNbRows = theRow;
326   }
327   
328   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
329 }
330
331 bool SALOMEDSImpl_AttributeTableOfInteger::HasValue(const int theRow,
332                                                     const int theColumn) 
333 {
334   if(theRow > myNbRows || theRow < 1) return false;
335   if(theColumn > myNbColumns || theColumn < 1) return false;
336   int anIndex = (theRow-1)*myNbColumns + theColumn;
337   return (myTable.find(anIndex) != myTable.end()); 
338 }
339
340 int SALOMEDSImpl_AttributeTableOfInteger::GetValue(const int theRow,
341                                                    const int theColumn) 
342 {
343   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
344   if(theColumn > myNbColumns || theColumn < 1) DFexception("Invalid cell index");
345
346   int anIndex = (theRow-1)*myNbColumns + theColumn;
347   if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
348   
349   throw DFexception("Invalid cell index");
350   return 0;
351 }
352
353 const std::string& SALOMEDSImpl_AttributeTableOfInteger::ID() const
354 {
355   return GetID();
356 }
357
358 void SALOMEDSImpl_AttributeTableOfInteger::Restore(DF_Attribute* with) 
359 {
360   int anIndex;
361   SALOMEDSImpl_AttributeTableOfInteger* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfInteger*>(with);
362   if(!aTable) throw DFexception("Can't Restore from a null attribute");    
363
364   myTable.clear();
365   myCols.clear();
366   myRows.clear();
367
368   myTable = aTable->myTable;
369   myNbRows = aTable->myNbRows;
370   myNbColumns = aTable->myNbColumns;
371   myTitle = aTable->myTitle;
372   
373   for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
374     myRows.push_back(aTable->GetRowTitle(anIndex));
375
376   for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++) 
377     myCols.push_back(aTable->GetColumnTitle(anIndex));
378 }
379
380 DF_Attribute* SALOMEDSImpl_AttributeTableOfInteger::NewEmpty() const
381 {
382   return new SALOMEDSImpl_AttributeTableOfInteger();
383 }
384
385 void SALOMEDSImpl_AttributeTableOfInteger::Paste(DF_Attribute* into)
386 {
387   int anIndex;
388   SALOMEDSImpl_AttributeTableOfInteger* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfInteger*>(into);
389   if(!aTable) throw DFexception("Can't Paste into a null attribute");    
390
391   aTable->myTable.clear();
392   aTable->myCols.clear();
393   aTable->myRows.clear();
394
395   aTable->myTable = myTable;
396   aTable->myTitle = myTitle;
397   aTable->myNbRows = myNbRows;
398   aTable->myNbColumns = myNbColumns;
399
400   for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
401     aTable->myRows.push_back(GetRowTitle(anIndex));
402   for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++) 
403     aTable->myCols.push_back(GetColumnTitle(anIndex));
404 }
405
406
407 vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetSetRowIndices(const int theRow)
408 {
409   vector<int> aSeq;
410
411   int i, aShift = myNbColumns*(theRow-1);
412   for(i = 1; i <= myNbColumns; i++) {
413     if(myTable.find(aShift + i) != myTable.end()) aSeq.push_back(i);
414   }
415   
416   return aSeq;
417 }
418
419 vector<int> SALOMEDSImpl_AttributeTableOfInteger::GetSetColumnIndices(const int theColumn)
420 {
421   vector<int> aSeq;
422
423   int i, anIndex;
424   for(i = 1; i <= myNbRows; i++) {
425     anIndex = myNbColumns*(i-1)+theColumn;
426     if(myTable.find(anIndex) != myTable.end()) aSeq.push_back(i);
427   }
428   
429   return aSeq;
430 }
431
432
433 string SALOMEDSImpl_AttributeTableOfInteger::Save() 
434 {
435   string aString;
436   char* buffer = new char[1024];
437   int i, j, l;
438
439   //Title
440   l = myTitle.size();
441   sprintf(buffer, "%d\n", l);
442   aString+=buffer;
443   for(i=0; i<l; i++) {
444     aString += myTitle[i];
445     aString +='\n';
446   }
447   
448   //Nb rows
449   sprintf(buffer, "%d\n", myNbRows);
450   aString+=buffer;
451
452   //Row titles
453   for(i=0; i<myNbRows; i++) {
454     l = myRows[i].size();
455     sprintf(buffer, "%d\n", l);
456     aString+=buffer;
457     for(j=0; j<l; j++) {
458       aString += myRows[i][j];
459       aString += '\n';
460     }
461   }  
462
463   //Nb columns
464   sprintf(buffer, "%d\n", myNbColumns);
465   aString+=buffer;
466
467   //Columns titles
468   for(i=0; i<myNbColumns; i++) {
469     l = myCols[i].size();
470     sprintf(buffer, "%d\n", l);
471     aString+=buffer;
472     for(j=0; j<l; j++) {
473       aString += myCols[i][j];
474       aString += '\n';
475     }
476   }
477
478   //Store the table values
479   l = myTable.size();
480   sprintf(buffer, "%d\n", l);
481   aString+=buffer;
482   for(MI p = myTable.begin(); p != myTable.end(); p++) {
483     sprintf(buffer, "%d\n%d\n", p->first, p->second);
484     aString += buffer;
485   }
486
487   delete []buffer;
488   return aString;
489 }
490
491
492
493 void SALOMEDSImpl_AttributeTableOfInteger::Load(const string& value) 
494 {
495   vector<string> v;
496   int i,  j, l, pos, aSize = (int)value.size(); 
497   for(i = 0, pos = 0; i<aSize; i++) {
498     if(value[i] == '\n') {
499        v.push_back(value.substr(pos, i-pos));
500        pos = i+1;
501     }
502   }
503
504   Backup();
505
506   pos = 0;
507   std::string aStr;
508
509   //Title
510   l = strtol(v[pos++].c_str(), NULL, 10);
511
512   myTitle = std::string(l, 0);
513   for(i=0; i<l; i++) {
514     myTitle[i] = v[pos++][0];
515   }
516
517   //Nb rows
518   myNbRows = strtol(v[pos++].c_str(), NULL, 10);
519
520   //Rows titles
521   myRows.clear();  
522   for(i=1; i<=myNbRows; i++) { 
523     l = strtol(v[pos++].c_str(), NULL, 10);
524     aStr = std::string(l,0);
525     for(j=0; j<l; j++) {
526       aStr[j] = v[pos++][0];
527     }
528     myRows.push_back(aStr);
529   }
530
531   //Nb columns
532   myNbColumns = strtol(v[pos++].c_str(), NULL, 10);
533
534   //Columns titles
535   myCols.clear();
536   for(i=1; i<=myNbColumns; i++) {
537     l = strtol(v[pos++].c_str(), NULL, 10);
538     aStr = std::string(l,0);
539     for(j=0; j<l; j++) {
540       aStr[j] = v[pos++][0];
541     }
542     myCols.push_back(aStr);
543   }
544
545   //Restore the table values
546   l = strtol(v[pos++].c_str(), NULL, 10);
547   myTable.clear();
548   for(i=1; i<=l; i++) {
549     int aKey = strtol(v[pos++].c_str(), NULL, 10);
550     int aValue = strtol(v[pos++].c_str(), NULL, 10);
551     myTable[aKey] = aValue;
552   }
553 }