Salome HOME
0539b5e8125c0b9b21818fb1eaaeebf824bfd9c0
[modules/kernel.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   ostrstream theStream;
436   int i, j, l;
437
438   theStream.precision(64);
439   
440   //Title
441   l = myTitle.size();
442   theStream << l << "\n";
443   for(i=0; i<l; i++)
444     theStream << myTitle[i] << "\n";
445
446   //Nb rows
447   theStream << myNbRows << "\n";
448
449   //Rows titles
450   for(i=0; i<myNbRows; i++) {
451     l = myRows[i].size();
452     theStream << l << "\n";
453     for(j=0; j<l; j++)
454       theStream << myRows[i][j] << "\n";
455   }
456
457   //Nb columns
458   theStream << myNbColumns << "\n";
459
460   //Columns titles
461   for(i=0; i<myNbColumns; i++) {
462     l = myCols[i].size();
463     theStream << l << "\n";
464     for(j=0; j<l; j++)
465       theStream << myCols[i][j] << "\n";
466   }
467
468   //Store the table values
469   l = myTable.size();
470   theStream << l << "\n";
471   for(MI p = myTable.begin(); p != myTable.end(); p++) {
472     theStream << p->first << "\n";
473     theStream << p->second << "\n";
474   }
475
476   string aString((char*)theStream.rdbuf()->str());
477   return aString;
478 }
479
480 void SALOMEDSImpl_AttributeTableOfInteger::Load(const string& value) 
481 {
482   istrstream theStream(value.c_str(), strlen(value.c_str()));
483   Backup();
484
485   int i, j, l;
486
487   char anExtChar;
488   std::string aStr;
489
490   //Title
491   theStream >> l;
492
493   myTitle = std::string(l, 0);
494   for(i=0; i<l; i++) {
495     theStream >> anExtChar;
496     myTitle[i] = anExtChar;
497   }
498
499   //Nb rows
500   theStream >> myNbRows;
501
502   //Rows titles
503   myRows.clear();  
504   for(i=1; i<=myNbRows; i++) { 
505     theStream >> l;
506     aStr = std::string(l,0);
507     for(j=0; j<l; j++) {
508       theStream >> anExtChar;
509       aStr[j] = anExtChar;
510     }
511     myRows.push_back(aStr);
512   }
513
514   //Nb columns
515   theStream >> myNbColumns;
516
517   //Columns titles
518   myCols.clear();
519   for(i=1; i<=myNbColumns; i++) {
520     theStream >> l;
521     aStr = std::string(l,0);
522     for(j=0; j<l; j++) {
523       theStream >> anExtChar;
524       aStr[j] = anExtChar;
525     }
526     myCols.push_back(aStr);
527   }
528
529   //Restore the table values
530   theStream >> l;
531   myTable.clear();
532   for(i=1; i<=l; i++) {
533     int aKey, aValue;
534     theStream >> aKey;
535     theStream >> aValue;
536     myTable[aKey] = aValue;
537   }
538 }