1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : SALOMEDSImpl_AttributeTableOfReal.cxx
21 // Author : Michael Ponikarov
24 #include "SALOMEDSImpl_AttributeTableOfReal.hxx"
30 #define SEPARATOR '\1'
32 typedef map<int, double>::const_iterator MI;
34 static std::string getUnit(std::string theString)
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());
42 static std::string getTitle(std::string theString)
44 std::string aString(theString);
45 int aPos = aString.find(SEPARATOR);
46 if(aPos < 1) return aString;
47 if(aPos == 1) return std::string();
48 return aString.substr(0, aPos);
51 const std::string& SALOMEDSImpl_AttributeTableOfReal::GetID()
53 static std::string SALOMEDSImpl_AttributeTableOfRealID ("128371A1-8F52-11d6-A8A3-0001021E8C7F");
54 return SALOMEDSImpl_AttributeTableOfRealID;
57 SALOMEDSImpl_AttributeTableOfReal* SALOMEDSImpl_AttributeTableOfReal::Set(const DF_Label& label)
59 SALOMEDSImpl_AttributeTableOfReal* A = NULL;
60 if (!(A=(SALOMEDSImpl_AttributeTableOfReal*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfReal::GetID()))) {
61 A = new SALOMEDSImpl_AttributeTableOfReal();
62 label.AddAttribute(A);
67 SALOMEDSImpl_AttributeTableOfReal::SALOMEDSImpl_AttributeTableOfReal()
68 :SALOMEDSImpl_GenericAttribute("AttributeTableOfReal")
74 void SALOMEDSImpl_AttributeTableOfReal::SetNbColumns(const int theNbColumns)
79 map<int, double> aMap;
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;
92 myNbColumns = theNbColumns;
94 while (myCols.size() < myNbColumns) { // append empty columns titles
95 myCols.push_back(string(""));
98 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
101 void SALOMEDSImpl_AttributeTableOfReal::SetTitle(const std::string& theTitle)
107 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
110 std::string SALOMEDSImpl_AttributeTableOfReal::GetTitle() const
115 void SALOMEDSImpl_AttributeTableOfReal::SetRowData(const int theRow,
116 const vector<double>& theData)
119 if(theData.size() > myNbColumns) SetNbColumns(theData.size());
123 while (myRows.size() < theRow) { // append new row titles
124 myRows.push_back(std::string(""));
127 int i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
128 for(i = 1; i <= aLength; i++) {
129 myTable[aShift + i] = theData[i-1];
132 if(theRow > myNbRows) myNbRows = theRow;
134 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
137 vector<double> SALOMEDSImpl_AttributeTableOfReal::GetRowData(const int theRow)
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]);
152 void SALOMEDSImpl_AttributeTableOfReal::SetRowTitle(const int theRow,
153 const std::string& theTitle)
157 std::string aTitle(theTitle), aUnit = GetRowUnit(theRow);
162 myRows[theRow-1] = aTitle;
164 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
167 void SALOMEDSImpl_AttributeTableOfReal::SetRowUnit(const int theRow,
168 const std::string& theUnit)
172 std::string aTitle = GetRowTitle(theRow);
176 myRows[theRow-1] = aTitle;
178 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
181 void SALOMEDSImpl_AttributeTableOfReal::SetRowUnits(const vector<string>& theUnits)
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]);
187 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
190 vector<string> SALOMEDSImpl_AttributeTableOfReal::GetRowUnits()
193 int aLength = myRows.size(), i;
194 for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
198 void SALOMEDSImpl_AttributeTableOfReal::SetRowTitles(const vector<string>& theTitles)
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]);
204 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
207 vector<string> SALOMEDSImpl_AttributeTableOfReal::GetRowTitles()
210 int aLength = myRows.size(), i;
211 for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
216 std::string SALOMEDSImpl_AttributeTableOfReal::GetRowTitle(const int theRow) const
218 return getTitle(myRows[theRow-1]);
222 std::string SALOMEDSImpl_AttributeTableOfReal::GetRowUnit(const int theRow) const
224 return getUnit(myRows[theRow-1]);
227 void SALOMEDSImpl_AttributeTableOfReal::SetColumnData(const int theColumn,
228 const vector<double>& theData)
231 if(theColumn > myNbColumns) SetNbColumns(theColumn);
235 int i, aLength = theData.size();
236 for(i = 1; i <= aLength; i++) {
237 myTable[myNbColumns*(i-1)+theColumn] = theData[i-1];
240 if(aLength > myNbRows) {
242 while (myRows.size() < myNbRows) { // append empty row titles
243 myRows.push_back(string(""));
247 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
251 vector<double> SALOMEDSImpl_AttributeTableOfReal::GetColumnData(const int theColumn)
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]);
267 void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitle(const int theColumn,
268 const std::string& theTitle)
272 while(myCols.size() < theColumn) myCols.push_back(std::string(""));
273 myCols[theColumn-1] = theTitle;
275 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
278 std::string SALOMEDSImpl_AttributeTableOfReal::GetColumnTitle(const int theColumn) const
280 if(myCols.empty()) return "";
281 if(myCols.size() < theColumn) return "";
282 return myCols[theColumn-1];
285 void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitles(const vector<string>& theTitles)
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];
291 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
294 vector<string> SALOMEDSImpl_AttributeTableOfReal::GetColumnTitles()
297 int aLength = myCols.size(), i;
298 for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
302 int SALOMEDSImpl_AttributeTableOfReal::GetNbRows() const
307 int SALOMEDSImpl_AttributeTableOfReal::GetNbColumns() const
312 void SALOMEDSImpl_AttributeTableOfReal::PutValue(const double& theValue,
317 if(theColumn > myNbColumns) SetNbColumns(theColumn);
319 int anIndex = (theRow-1)*myNbColumns + theColumn;
320 myTable[anIndex] = theValue;
322 if(theRow > myNbRows) {
323 while (myRows.size() < theRow) { // append empty row titles
324 myRows.push_back(std::string(""));
329 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
332 bool SALOMEDSImpl_AttributeTableOfReal::HasValue(const int theRow,
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());
341 double SALOMEDSImpl_AttributeTableOfReal::GetValue(const int theRow,
344 if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
345 if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
347 int anIndex = (theRow-1)*myNbColumns + theColumn;
348 if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
350 throw DFexception("Invalid cell index");
354 const std::string& SALOMEDSImpl_AttributeTableOfReal::ID() const
359 void SALOMEDSImpl_AttributeTableOfReal::Restore(DF_Attribute* with)
362 SALOMEDSImpl_AttributeTableOfReal* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfReal*>(with);
363 if(!aTable) throw DFexception("Can't Restore from a null attribute");
369 myTable = aTable->myTable;
370 myNbRows = aTable->myNbRows;
371 myNbColumns = aTable->myNbColumns;
372 myTitle = aTable->myTitle;
374 for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
375 myRows.push_back(aTable->GetRowTitle(anIndex));
377 for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++)
378 myCols.push_back(aTable->GetColumnTitle(anIndex));
381 DF_Attribute* SALOMEDSImpl_AttributeTableOfReal::NewEmpty() const
383 return new SALOMEDSImpl_AttributeTableOfReal();
386 void SALOMEDSImpl_AttributeTableOfReal::Paste(DF_Attribute* into)
389 SALOMEDSImpl_AttributeTableOfReal* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfReal*>(into);
390 if(!aTable) throw DFexception("Can't Paste into a null attribute");
392 aTable->myTable.clear();
393 aTable->myCols.clear();
394 aTable->myRows.clear();
396 aTable->myTable = myTable;
397 aTable->myTitle = myTitle;
398 aTable->myNbRows = myNbRows;
399 aTable->myNbColumns = myNbColumns;
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));
408 vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetRowIndices(const int theRow)
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);
420 vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetColumnIndices(const int theColumn)
425 for(i = 1; i <= myNbRows; i++) {
426 anIndex = myNbColumns*(i-1)+theColumn;
427 if(myTable.find(anIndex) != myTable.end()) aSeq.push_back(i);
433 string SALOMEDSImpl_AttributeTableOfReal::Save()
435 ostrstream theStream;
440 theStream << l << "\n";
442 theStream << myTitle[i] << "\n";
445 theStream << myNbRows << "\n";
448 for(i=0; i<myNbRows; i++) {
449 l = myRows[i].size();
450 theStream << l << "\n";
452 theStream << myRows[i][j] << "\n";
456 theStream << myNbColumns << "\n";
459 for(i=0; i<myNbColumns; i++) {
460 l = myCols[i].size();
461 theStream << l << "\n";
463 theStream << myCols[i][j] << "\n";
466 //Store the table values
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";
477 string aString((char*)theStream.rdbuf()->str());
481 void SALOMEDSImpl_AttributeTableOfReal::Load(const string& value)
483 istrstream theStream(value.c_str(), strlen(value.c_str()));
494 myTitle = std::string(l, 0);
496 theStream >> anExtChar;
497 myTitle[i] = anExtChar;
501 theStream >> myNbRows;
505 for(i=1; i<=myNbRows; i++) {
507 aStr = std::string(l,0);
509 theStream >> anExtChar;
512 myRows.push_back(aStr);
516 theStream >> myNbColumns;
520 for(i=1; i<=myNbColumns; i++) {
522 aStr = std::string(l,0);
524 theStream >> anExtChar;
527 myCols.push_back(aStr);
530 //Restore the table values
533 for(i=1; i<=l; i++) {
538 myTable[aKey] = aValue;