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