Salome HOME
Base implementation of Notebook
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeTableOfReal.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_AttributeTableOfReal.cxx
23 //  Author : Michael Ponikarov
24 //  Module : SALOME
25 //
26 #include "SALOMEDSImpl_AttributeTableOfReal.hxx"
27 #include <stdio.h>
28 #include <sstream>
29
30 using namespace std;
31
32 #define SEPARATOR '\1'
33
34 typedef map<int, double>::const_iterator MI;
35
36 static std::string getUnit(std::string theString)
37 {
38   std::string aString(theString);
39   int aPos = aString.find(SEPARATOR);
40   if(aPos <= 0 || aPos == aString.size() ) return std::string();
41   return aString.substr(aPos+1, aString.size());
42 }
43
44 static std::string getTitle(std::string theString)
45 {
46   std::string aString(theString);
47   int aPos = aString.find(SEPARATOR);
48   if(aPos < 0) return aString;
49   if(aPos == 0) return std::string();
50   return aString.substr(0, aPos);
51 }
52
53 const std::string& SALOMEDSImpl_AttributeTableOfReal::GetID() 
54 {
55   static std::string SALOMEDSImpl_AttributeTableOfRealID ("128371A1-8F52-11d6-A8A3-0001021E8C7F");
56   return SALOMEDSImpl_AttributeTableOfRealID;
57 }
58
59 SALOMEDSImpl_AttributeTableOfReal* SALOMEDSImpl_AttributeTableOfReal::Set(const DF_Label& label) 
60 {
61   SALOMEDSImpl_AttributeTableOfReal* A = NULL;
62   if (!(A=(SALOMEDSImpl_AttributeTableOfReal*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfReal::GetID()))) {
63     A = new SALOMEDSImpl_AttributeTableOfReal();
64     label.AddAttribute(A);
65   }
66   return A;
67 }
68
69 SALOMEDSImpl_AttributeTableOfReal::SALOMEDSImpl_AttributeTableOfReal() 
70 :SALOMEDSImpl_GenericAttribute("AttributeTableOfReal")
71 {
72   myNbRows = 0;
73   myNbColumns = 0;
74 }
75
76 void SALOMEDSImpl_AttributeTableOfReal::SetNbColumns(const int theNbColumns)
77 {
78   CheckLocked();  
79   Backup();
80   
81   map<int, double> aMap;
82   aMap = myTable;
83   myTable.clear();
84
85   for(MI p = aMap.begin(); p != aMap.end(); p++) {
86     int aRow = (int)(p->first/myNbColumns) + 1;
87     int aCol = (int)(p->first - myNbColumns*(aRow-1));
88     if(aCol == 0) { aCol = myNbColumns; aRow--; }
89     if(aCol > theNbColumns) continue;
90     int aKey = (aRow-1)*theNbColumns+aCol;
91     myTable[aKey] = p->second;
92   }
93
94   myNbColumns = theNbColumns;
95
96   while (myCols.size() < myNbColumns) { // append empty columns titles
97     myCols.push_back(string(""));
98   }
99   
100   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
101 }
102
103 void SALOMEDSImpl_AttributeTableOfReal::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_AttributeTableOfReal::GetTitle() const 
113 {
114   return myTitle;
115 }
116
117 void SALOMEDSImpl_AttributeTableOfReal::SetRowData(const int theRow,
118                                                    const vector<double>& 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<double> SALOMEDSImpl_AttributeTableOfReal::GetRowData(const int theRow)
140 {
141   vector<double> 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
154 void SALOMEDSImpl_AttributeTableOfReal::SetRowTitle(const int theRow,
155                                                     const std::string& theTitle) 
156 {
157   CheckLocked();  
158   Backup();
159   std::string aTitle(theTitle), aUnit = GetRowUnit(theRow);
160   if(aUnit.size()>0) {
161     aTitle += SEPARATOR;
162     aTitle += aUnit;
163   }
164   myRows[theRow-1] = aTitle;
165   
166   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
167 }
168
169 void SALOMEDSImpl_AttributeTableOfReal::SetRowUnit(const int theRow,
170                                                    const std::string& theUnit) 
171 {
172   CheckLocked();  
173   Backup();
174   std::string aTitle = GetRowTitle(theRow);
175   aTitle += SEPARATOR;
176   aTitle += theUnit;
177   
178   myRows[theRow-1] = aTitle;
179   
180   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
181 }
182
183 void SALOMEDSImpl_AttributeTableOfReal::SetRowUnits(const vector<string>& theUnits)
184 {
185   if (theUnits.size() != GetNbRows()) throw DFexception("Invalid number of rows");
186   int aLength = theUnits.size(), i;
187   for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits[i-1]);
188   
189   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
190 }
191
192 vector<string> SALOMEDSImpl_AttributeTableOfReal::GetRowUnits()
193 {
194   vector<string> aSeq;
195   int aLength = myRows.size(), i;
196   for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
197   return aSeq;
198 }
199
200 void SALOMEDSImpl_AttributeTableOfReal::SetRowTitles(const vector<string>& theTitles)
201 {
202   if (theTitles.size() != GetNbRows()) throw DFexception("Invalid number of rows");
203   int aLength = theTitles.size(), i;
204   for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles[i-1]);
205   
206   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
207 }
208
209 vector<string> SALOMEDSImpl_AttributeTableOfReal::GetRowTitles()
210 {
211   vector<string> aSeq;
212   int aLength = myRows.size(), i;
213   for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
214   return aSeq;
215 }
216
217
218 std::string SALOMEDSImpl_AttributeTableOfReal::GetRowTitle(const int theRow) const 
219 {
220   return getTitle(myRows[theRow-1]);
221 }
222
223
224 std::string SALOMEDSImpl_AttributeTableOfReal::GetRowUnit(const int theRow) const 
225 {
226   return getUnit(myRows[theRow-1]);
227 }
228
229 void SALOMEDSImpl_AttributeTableOfReal::SetColumnData(const int theColumn,
230                                                       const vector<double>& 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(string(""));
246     }
247   }
248   
249   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
250 }
251
252
253 vector<double> SALOMEDSImpl_AttributeTableOfReal::GetColumnData(const int theColumn)
254 {
255   vector<double> aSeq;
256   
257   int i, anIndex;
258   for(i = 1; i <= myNbRows; i++) {
259     anIndex = myNbColumns*(i-1) + theColumn;
260     if(myTable.find(anIndex) != myTable.end()) 
261       aSeq.push_back(myTable[anIndex]);
262     else
263       aSeq.push_back(0.);
264   }
265   
266   return aSeq;
267 }
268
269 void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitle(const int theColumn,
270                                                        const std::string& theTitle) 
271 {
272   CheckLocked();  
273   Backup();
274   while(myCols.size() < theColumn) myCols.push_back(std::string(""));
275   myCols[theColumn-1] = theTitle;
276
277   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
278 }
279
280 std::string SALOMEDSImpl_AttributeTableOfReal::GetColumnTitle(const int theColumn) const 
281 {
282   if(myCols.empty()) return "";
283   if(myCols.size() < theColumn) return "";
284   return myCols[theColumn-1];
285 }
286
287 void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitles(const vector<string>& theTitles)
288 {
289   if (theTitles.size() != myNbColumns) throw DFexception("Invalid number of columns");
290   int aLength = theTitles.size(), i;
291   for(i = 0; i < aLength; i++)  myCols[i] = theTitles[i];
292   
293   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
294 }
295
296 vector<string> SALOMEDSImpl_AttributeTableOfReal::GetColumnTitles()
297 {
298   vector<string> aSeq;
299   int aLength = myCols.size(), i;
300   for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
301   return aSeq;
302 }
303
304 int SALOMEDSImpl_AttributeTableOfReal::GetNbRows() const
305 {
306   return myNbRows;
307 }
308
309 int SALOMEDSImpl_AttributeTableOfReal::GetNbColumns() const
310 {
311   return myNbColumns;
312 }
313
314 void SALOMEDSImpl_AttributeTableOfReal::PutValue(const double& theValue,
315                                                  const int theRow,
316                                                  const int theColumn) 
317 {
318   CheckLocked();      
319   if(theColumn > myNbColumns) SetNbColumns(theColumn);
320
321   int anIndex = (theRow-1)*myNbColumns + theColumn;
322   myTable[anIndex] =  theValue;
323
324   if(theRow > myNbRows) {
325     while (myRows.size() < theRow) { // append empty row titles
326       myRows.push_back(std::string(""));
327     }
328     myNbRows = theRow;
329   }
330   
331   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
332 }
333
334 bool SALOMEDSImpl_AttributeTableOfReal::HasValue(const int theRow,
335                                                  const int theColumn) 
336 {
337   if(theRow > myNbRows || theRow < 1) return false;
338   if(theColumn > myNbColumns || theColumn < 1) return false;
339   int anIndex = (theRow-1)*myNbColumns + theColumn;
340   return (myTable.find(anIndex) != myTable.end()); 
341 }
342
343 double SALOMEDSImpl_AttributeTableOfReal::GetValue(const int theRow,
344                                                    const int theColumn) 
345 {
346   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
347   if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
348
349   int anIndex = (theRow-1)*myNbColumns + theColumn;
350   if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
351   
352   throw DFexception("Invalid cell index");
353   return 0.;
354 }
355
356 const std::string& SALOMEDSImpl_AttributeTableOfReal::ID() const
357 {
358   return GetID();
359 }
360
361 void SALOMEDSImpl_AttributeTableOfReal::Restore(DF_Attribute* with) 
362 {
363   int anIndex;
364   SALOMEDSImpl_AttributeTableOfReal* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfReal*>(with);
365   if(!aTable) throw DFexception("Can't Restore from a null attribute");
366
367   myTable.clear();
368   myCols.clear();
369   myRows.clear();
370
371   myTable = aTable->myTable;
372   myNbRows = aTable->myNbRows;
373   myNbColumns = aTable->myNbColumns;
374   myTitle = aTable->myTitle;
375   
376   for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
377     myRows.push_back(aTable->GetRowTitle(anIndex));
378
379   for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++) 
380     myCols.push_back(aTable->GetColumnTitle(anIndex));
381 }
382
383 DF_Attribute* SALOMEDSImpl_AttributeTableOfReal::NewEmpty() const
384 {
385   return new SALOMEDSImpl_AttributeTableOfReal();
386 }
387
388 void SALOMEDSImpl_AttributeTableOfReal::Paste(DF_Attribute* into)
389 {
390   int anIndex;
391   SALOMEDSImpl_AttributeTableOfReal* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfReal*>(into);
392   if(!aTable) throw DFexception("Can't Paste into a null attribute"); 
393
394   aTable->myTable.clear();
395   aTable->myCols.clear();
396   aTable->myRows.clear();
397
398   aTable->myTable = myTable;
399   aTable->myTitle = myTitle;
400   aTable->myNbRows = myNbRows;
401   aTable->myNbColumns = myNbColumns;
402
403   for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
404     aTable->myRows.push_back(GetRowTitle(anIndex));
405   for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++) 
406     aTable->myCols.push_back(GetColumnTitle(anIndex));
407 }
408
409
410 vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetRowIndices(const int theRow)
411 {
412   vector<int> aSeq;
413
414   int i, aShift = myNbColumns*(theRow-1);
415   for(i = 1; i <= myNbColumns; i++) {
416     if(myTable.find(aShift + i) != myTable.end()) aSeq.push_back(i);
417   }
418   
419   return aSeq;
420 }
421
422 vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetColumnIndices(const int theColumn)
423 {
424   vector<int> aSeq;
425
426   int i, anIndex;
427   for(i = 1; i <= myNbRows; i++) {
428     anIndex = myNbColumns*(i-1)+theColumn;
429     if(myTable.find(anIndex) != myTable.end()) aSeq.push_back(i);
430   }
431   
432   return aSeq;
433 }
434
435 string SALOMEDSImpl_AttributeTableOfReal::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%.64e\n", p->first, p->second);
486     aString += buffer;
487   }
488
489   delete []buffer;
490   return aString;
491 }
492
493 void SALOMEDSImpl_AttributeTableOfReal::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     double aValue = strtod(v[pos++].c_str(), NULL);
551     myTable[aKey] = aValue;
552   }
553
554 }