Salome HOME
PR: last merge from BR_V5_DEV
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeTableOfString.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_AttributeTableOfString.cxx
23 //  Author : Sergey Ruin
24 //  Module : SALOME
25 //
26 #include "SALOMEDSImpl_AttributeTableOfString.hxx"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <strstream>
30
31 using namespace std;
32
33 #define SEPARATOR '\1'
34
35 typedef map<int, string>::const_iterator MI;
36
37 static std::string getUnit(std::string theString)
38 {
39   std::string aString(theString);
40   int aPos = aString.find(SEPARATOR);
41   if(aPos <= 0 || aPos == aString.size() ) return std::string();
42   return aString.substr(aPos+1, aString.size());
43 }
44
45 static std::string getTitle(std::string theString)
46 {
47   std::string aString(theString);
48   int aPos = aString.find(SEPARATOR);
49   if(aPos < 1) return aString;
50   if(aPos == 0) return std::string();
51   return aString.substr(0, aPos);
52 }
53
54 const std::string& SALOMEDSImpl_AttributeTableOfString::GetID() 
55 {
56   static std::string SALOMEDSImpl_AttributeTableOfStringID ("128371A4-8F52-11d6-A8A3-0001021E8C7F");
57   return SALOMEDSImpl_AttributeTableOfStringID;
58 }
59
60 SALOMEDSImpl_AttributeTableOfString* SALOMEDSImpl_AttributeTableOfString::Set(const DF_Label& label) 
61 {
62   SALOMEDSImpl_AttributeTableOfString* A = NULL;
63   if (!(A=(SALOMEDSImpl_AttributeTableOfString*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfString::GetID()))) {
64     A = new SALOMEDSImpl_AttributeTableOfString();
65     label.AddAttribute(A);
66   }
67   return A;
68 }
69
70 SALOMEDSImpl_AttributeTableOfString::SALOMEDSImpl_AttributeTableOfString() 
71 :SALOMEDSImpl_GenericAttribute("AttributeTableOfString")
72 {
73   myNbRows = 0;
74   myNbColumns = 0;
75 }
76
77 void SALOMEDSImpl_AttributeTableOfString::SetNbColumns(const int theNbColumns)
78 {
79   CheckLocked();  
80   Backup();
81   
82   map<int, string> aMap;
83   aMap = myTable;
84   myTable.clear();
85
86   for(MI p = aMap.begin(); p!=aMap.end(); p++) {
87     int aRow = (int)(p->first/myNbColumns) + 1;
88     int aCol = (int)(p->first - myNbColumns*(aRow-1));
89     if(aCol == 0) { aCol = myNbColumns; aRow--; }
90     if(aCol > theNbColumns) continue;
91     int aKey = (aRow-1)*theNbColumns+aCol;
92     myTable[aKey] = p->second;
93   }
94
95   myNbColumns = theNbColumns;
96
97   while (myCols.size() < myNbColumns) { // append empty columns titles
98     myCols.push_back(std::string(""));
99   }
100
101   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
102 }
103
104 void SALOMEDSImpl_AttributeTableOfString::SetRowTitle(const int theRow,
105                                                       const std::string& theTitle) 
106 {
107   CheckLocked();  
108   Backup();
109   std::string aTitle(theTitle), aUnit = GetRowUnit(theRow);
110   if(aUnit.size()>0) {
111     aTitle += SEPARATOR;
112     aTitle += aUnit;
113   }
114   myRows[theRow-1] = aTitle;
115   
116   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
117 }
118
119 void SALOMEDSImpl_AttributeTableOfString::SetRowUnit(const int theRow,
120                                                      const std::string& theUnit) 
121 {
122   CheckLocked();  
123   Backup();
124   std::string aTitle = GetRowTitle(theRow);
125   aTitle += SEPARATOR;
126   aTitle += theUnit;
127
128   myRows[theRow-1] = aTitle;
129   
130   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
131 }
132
133 void SALOMEDSImpl_AttributeTableOfString::SetRowUnits(const vector<string>& theUnits)
134 {
135   if (theUnits.size() != GetNbRows()) throw DFexception("Invalid number of rows");
136   int aLength = theUnits.size(), i;
137   for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits[i-1]);
138 }
139
140 vector<string> SALOMEDSImpl_AttributeTableOfString::GetRowUnits()
141 {
142   vector<string> aSeq;
143   int aLength = myRows.size(), i;
144   for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
145   return aSeq;
146 }
147
148 void SALOMEDSImpl_AttributeTableOfString::SetRowTitles(const vector<string>& theTitles)
149 {
150   if (theTitles.size() != GetNbRows()) throw DFexception("Invalid number of rows");
151   int aLength = theTitles.size(), i;
152   for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles[i-1]);
153   
154   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
155 }
156
157 vector<string> SALOMEDSImpl_AttributeTableOfString::GetRowTitles()
158 {
159   vector<string> aSeq;
160   int aLength = myRows.size(), i;
161   for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
162   return aSeq;
163 }
164
165
166 std::string SALOMEDSImpl_AttributeTableOfString::GetRowTitle(const int theRow) const 
167 {
168   return getTitle(myRows[theRow-1]);
169 }
170
171
172 std::string SALOMEDSImpl_AttributeTableOfString::GetRowUnit(const int theRow) const 
173 {
174   return getUnit(myRows[theRow-1]);
175 }
176
177 void SALOMEDSImpl_AttributeTableOfString::SetRowData(const int theRow,
178                                                      const vector<string>& theData) 
179 {
180   CheckLocked();  
181   if(theData.size() > myNbColumns) SetNbColumns(theData.size());
182
183   Backup();
184
185   while (myRows.size() < theRow) { // append new row titles
186     myRows.push_back(std::string(""));
187   }
188
189   int i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
190   for(i = 1; i <= aLength; i++) {
191     myTable[aShift + i] = theData[i-1];
192   }
193
194   if(theRow > myNbRows) myNbRows = theRow;
195   
196   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
197 }
198
199 void SALOMEDSImpl_AttributeTableOfString::SetTitle(const std::string& theTitle) 
200 {
201   CheckLocked();  
202   Backup();
203   myTitle = theTitle;
204   
205   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
206 }
207
208 std::string SALOMEDSImpl_AttributeTableOfString::GetTitle() const 
209 {
210   return myTitle;
211 }
212
213 vector<string> SALOMEDSImpl_AttributeTableOfString::GetRowData(const int theRow)
214 {
215   vector<string> aSeq;
216   int i, aShift = (theRow-1)*myNbColumns;
217   for(i = 1; i <= myNbColumns; i++) {
218      if(myTable.find(aShift+i) != myTable.end()) 
219        aSeq.push_back(myTable[aShift+i]);
220      else
221        aSeq.push_back("");
222   }
223   
224   return aSeq;
225 }
226
227 void SALOMEDSImpl_AttributeTableOfString::SetColumnData(const int theColumn,
228                                                         const vector<string>& 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<string> SALOMEDSImpl_AttributeTableOfString::GetColumnData(const int theColumn)
252 {
253   vector<string> 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("");
262   }
263   
264   return aSeq;
265 }
266
267 void SALOMEDSImpl_AttributeTableOfString::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_AttributeTableOfString::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
286 void SALOMEDSImpl_AttributeTableOfString::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_AttributeTableOfString::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
304 int SALOMEDSImpl_AttributeTableOfString::GetNbRows() const
305 {
306   return myNbRows;
307 }
308
309 int SALOMEDSImpl_AttributeTableOfString::GetNbColumns() const
310 {
311   return myNbColumns;
312 }
313
314 void SALOMEDSImpl_AttributeTableOfString::PutValue(const std::string& 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_AttributeTableOfString::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
340   int anIndex = (theRow-1)*myNbColumns + theColumn;
341   return (myTable.find(anIndex) !=  myTable.end()); 
342 }
343
344 std::string SALOMEDSImpl_AttributeTableOfString::GetValue(const int theRow,
345                                                           const int theColumn) 
346 {
347   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
348   if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
349
350   int anIndex = (theRow-1)*myNbColumns + theColumn;
351   if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
352   
353   throw DFexception("Invalid cell index");
354   return "";
355 }
356
357 const std::string& SALOMEDSImpl_AttributeTableOfString::ID() const
358 {
359   return GetID();
360 }
361
362 void SALOMEDSImpl_AttributeTableOfString::Restore(DF_Attribute* with) 
363 {
364   int anIndex;
365   SALOMEDSImpl_AttributeTableOfString* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfString*>(with);
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_AttributeTableOfString::NewEmpty() const
384 {
385   return new SALOMEDSImpl_AttributeTableOfString();
386 }
387
388 void SALOMEDSImpl_AttributeTableOfString::Paste(DF_Attribute* into)
389 {
390   int anIndex;
391   SALOMEDSImpl_AttributeTableOfString* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfString*>(into);
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_AttributeTableOfString::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_AttributeTableOfString::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
436 string SALOMEDSImpl_AttributeTableOfString::Save() 
437 {
438   string aString;
439   char* buffer = new char[1024];
440   int i, j, l;
441
442   //Title
443   l = myTitle.size();
444   sprintf(buffer, "%d\n", l);
445   aString+=buffer;
446   for(i=0; i<l; i++) {
447     aString += myTitle[i];
448     aString +='\n';
449   }
450   
451   //Nb rows
452   sprintf(buffer, "%d\n", myNbRows);
453   aString+=buffer;
454
455   //Row titles
456   for(i=0; i<myNbRows; i++) {
457     l = myRows[i].size();
458     sprintf(buffer, "%d\n", l);
459     aString+=buffer;
460     for(j=0; j<l; j++) {
461       aString += myRows[i][j];
462       aString += '\n';
463     }
464   }  
465
466   //Nb columns
467   sprintf(buffer, "%d\n", myNbColumns);
468   aString+=buffer;
469
470   //Columns titles
471   for(i=0; i<myNbColumns; i++) {
472     l = myCols[i].size();
473     sprintf(buffer, "%d\n", l);
474     aString+=buffer;
475     for(j=0; j<l; j++) {
476       aString += myCols[i][j];
477       aString += '\n';
478     }
479   }
480
481   //Store the table values
482   l = myTable.size();
483   sprintf(buffer, "%d\n", l);
484   aString+=buffer;
485   for(MI p = myTable.begin(); p!=myTable.end(); p++) {
486     if (p->second.size()) { // check empty string in the value table
487       sprintf(buffer, "%d\n", p->first);
488       aString += buffer;
489       unsigned long aValueSize = p->second.size();
490       sprintf(buffer, "%ld\n", aValueSize);
491       aString +=buffer;
492       aString += p->second;
493       aString += '\n';
494     } else { // write index only of kind: "0key"; "05", for an example
495       sprintf(buffer, "0%d\n", p->first);
496       aString+=buffer;
497     }
498   }
499
500   delete []buffer;
501   return aString;
502 }
503
504 void SALOMEDSImpl_AttributeTableOfString::Load(const string& value) 
505 {
506   vector<string> v;
507   int i,  j, l, pos, aSize = (int)value.size(); 
508   for(i = 0, pos = 0; i<aSize; i++) {
509     if(value[i] == '\n') {
510        v.push_back(value.substr(pos, i-pos));
511        pos = i+1;
512     }
513   }
514
515   Backup();
516
517   pos = 0;
518   std::string aStr;
519
520   //Title
521   l = strtol(v[pos++].c_str(), NULL, 10);
522
523   myTitle = std::string(l, 0);
524   for(i=0; i<l; i++) {
525     myTitle[i] = v[pos++][0];
526   }
527
528   //Nb rows
529   myNbRows = strtol(v[pos++].c_str(), NULL, 10);
530
531   //Rows titles
532   myRows.clear();  
533   for(i=1; i<=myNbRows; i++) { 
534     l = strtol(v[pos++].c_str(), NULL, 10);
535     aStr = std::string(l,0);
536     for(j=0; j<l; j++) {
537       aStr[j] = v[pos++][0];
538     }
539     myRows.push_back(aStr);
540   }
541
542   //Nb columns
543   myNbColumns = strtol(v[pos++].c_str(), NULL, 10);
544
545   //Columns titles
546   myCols.clear();
547   for(i=1; i<=myNbColumns; i++) {
548     l = strtol(v[pos++].c_str(), NULL, 10);
549     aStr = std::string(l,0);
550     for(j=0; j<l; j++) {
551       aStr[j] = v[pos++][0];
552     }
553     myCols.push_back(aStr);
554   }
555
556   //Restore the table values
557   l = strtol(v[pos++].c_str(), NULL, 10);
558   myTable.clear();
559   for(i=1; i<=l; i++) {
560     aStr = v[pos++]; //Ket as a string 
561     int aKey = strtol(aStr.c_str(), NULL, 10);
562     string aValue;
563     if(aStr[0] == '0') //If the first character of the key is 0, then empty value
564       aValue = "";
565     else {
566       strtol(v[pos++].c_str(), NULL, 10);
567       aValue = v[pos++];
568     }
569     myTable[aKey] = aValue;
570   }
571 }