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