1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SALOMEDSImpl_AttributeTableOfReal.cxx
23 // Author : Michael Ponikarov
26 #include "SALOMEDSImpl_AttributeTableOfReal.hxx"
32 #define SEPARATOR '\1'
34 typedef map<int, double>::const_iterator MI;
36 static std::string getUnit(std::string theString)
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());
44 static std::string getTitle(std::string theString)
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);
53 const std::string& SALOMEDSImpl_AttributeTableOfReal::GetID()
55 static std::string SALOMEDSImpl_AttributeTableOfRealID ("128371A1-8F52-11d6-A8A3-0001021E8C7F");
56 return SALOMEDSImpl_AttributeTableOfRealID;
59 SALOMEDSImpl_AttributeTableOfReal* SALOMEDSImpl_AttributeTableOfReal::Set(const DF_Label& label)
61 SALOMEDSImpl_AttributeTableOfReal* A = NULL;
62 if (!(A=(SALOMEDSImpl_AttributeTableOfReal*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfReal::GetID()))) {
63 A = new SALOMEDSImpl_AttributeTableOfReal();
64 label.AddAttribute(A);
69 SALOMEDSImpl_AttributeTableOfReal::SALOMEDSImpl_AttributeTableOfReal()
70 :SALOMEDSImpl_GenericAttribute("AttributeTableOfReal")
76 void SALOMEDSImpl_AttributeTableOfReal::SetNbColumns(const int theNbColumns)
81 map<int, double> aMap;
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;
94 myNbColumns = theNbColumns;
96 while (myCols.size() < myNbColumns) { // append empty columns titles
97 myCols.push_back(string(""));
100 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
103 void SALOMEDSImpl_AttributeTableOfReal::SetTitle(const std::string& theTitle)
109 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
112 std::string SALOMEDSImpl_AttributeTableOfReal::GetTitle() const
117 void SALOMEDSImpl_AttributeTableOfReal::SetRowData(const int theRow,
118 const vector<double>& theData)
121 if(theData.size() > myNbColumns) SetNbColumns(theData.size());
125 while (myRows.size() < theRow) { // append new row titles
126 myRows.push_back(std::string(""));
129 int i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
130 for(i = 1; i <= aLength; i++) {
131 myTable[aShift + i] = theData[i-1];
134 if(theRow > myNbRows) myNbRows = theRow;
136 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
139 vector<double> SALOMEDSImpl_AttributeTableOfReal::GetRowData(const int theRow)
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]);
154 void SALOMEDSImpl_AttributeTableOfReal::SetRowTitle(const int theRow,
155 const std::string& theTitle)
159 std::string aTitle(theTitle), aUnit = GetRowUnit(theRow);
164 myRows[theRow-1] = aTitle;
166 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
169 void SALOMEDSImpl_AttributeTableOfReal::SetRowUnit(const int theRow,
170 const std::string& theUnit)
174 std::string aTitle = GetRowTitle(theRow);
178 myRows[theRow-1] = aTitle;
180 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
183 void SALOMEDSImpl_AttributeTableOfReal::SetRowUnits(const vector<string>& theUnits)
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]);
189 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
192 vector<string> SALOMEDSImpl_AttributeTableOfReal::GetRowUnits()
195 int aLength = myRows.size(), i;
196 for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
200 void SALOMEDSImpl_AttributeTableOfReal::SetRowTitles(const vector<string>& theTitles)
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]);
206 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
209 vector<string> SALOMEDSImpl_AttributeTableOfReal::GetRowTitles()
212 int aLength = myRows.size(), i;
213 for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
218 std::string SALOMEDSImpl_AttributeTableOfReal::GetRowTitle(const int theRow) const
220 return getTitle(myRows[theRow-1]);
224 std::string SALOMEDSImpl_AttributeTableOfReal::GetRowUnit(const int theRow) const
226 return getUnit(myRows[theRow-1]);
229 void SALOMEDSImpl_AttributeTableOfReal::SetColumnData(const int theColumn,
230 const vector<double>& theData)
233 if(theColumn > myNbColumns) SetNbColumns(theColumn);
237 int i, aLength = theData.size();
238 for(i = 1; i <= aLength; i++) {
239 myTable[myNbColumns*(i-1)+theColumn] = theData[i-1];
242 if(aLength > myNbRows) {
244 while (myRows.size() < myNbRows) { // append empty row titles
245 myRows.push_back(string(""));
249 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
253 vector<double> SALOMEDSImpl_AttributeTableOfReal::GetColumnData(const int theColumn)
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]);
269 void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitle(const int theColumn,
270 const std::string& theTitle)
274 while(myCols.size() < theColumn) myCols.push_back(std::string(""));
275 myCols[theColumn-1] = theTitle;
277 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
280 std::string SALOMEDSImpl_AttributeTableOfReal::GetColumnTitle(const int theColumn) const
282 if(myCols.empty()) return "";
283 if(myCols.size() < theColumn) return "";
284 return myCols[theColumn-1];
287 void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitles(const vector<string>& theTitles)
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];
293 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
296 vector<string> SALOMEDSImpl_AttributeTableOfReal::GetColumnTitles()
299 int aLength = myCols.size(), i;
300 for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
304 int SALOMEDSImpl_AttributeTableOfReal::GetNbRows() const
309 int SALOMEDSImpl_AttributeTableOfReal::GetNbColumns() const
314 void SALOMEDSImpl_AttributeTableOfReal::PutValue(const double& theValue,
319 if(theColumn > myNbColumns) SetNbColumns(theColumn);
321 int anIndex = (theRow-1)*myNbColumns + theColumn;
322 myTable[anIndex] = theValue;
324 if(theRow > myNbRows) {
325 while (myRows.size() < theRow) { // append empty row titles
326 myRows.push_back(std::string(""));
331 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
334 bool SALOMEDSImpl_AttributeTableOfReal::HasValue(const int theRow,
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());
343 double SALOMEDSImpl_AttributeTableOfReal::GetValue(const int theRow,
346 if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
347 if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
349 int anIndex = (theRow-1)*myNbColumns + theColumn;
350 if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
352 throw DFexception("Invalid cell index");
356 const std::string& SALOMEDSImpl_AttributeTableOfReal::ID() const
361 void SALOMEDSImpl_AttributeTableOfReal::Restore(DF_Attribute* with)
364 SALOMEDSImpl_AttributeTableOfReal* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfReal*>(with);
365 if(!aTable) throw DFexception("Can't Restore from a null attribute");
371 myTable = aTable->myTable;
372 myNbRows = aTable->myNbRows;
373 myNbColumns = aTable->myNbColumns;
374 myTitle = aTable->myTitle;
376 for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
377 myRows.push_back(aTable->GetRowTitle(anIndex));
379 for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++)
380 myCols.push_back(aTable->GetColumnTitle(anIndex));
383 DF_Attribute* SALOMEDSImpl_AttributeTableOfReal::NewEmpty() const
385 return new SALOMEDSImpl_AttributeTableOfReal();
388 void SALOMEDSImpl_AttributeTableOfReal::Paste(DF_Attribute* into)
391 SALOMEDSImpl_AttributeTableOfReal* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfReal*>(into);
392 if(!aTable) throw DFexception("Can't Paste into a null attribute");
394 aTable->myTable.clear();
395 aTable->myCols.clear();
396 aTable->myRows.clear();
398 aTable->myTable = myTable;
399 aTable->myTitle = myTitle;
400 aTable->myNbRows = myNbRows;
401 aTable->myNbColumns = myNbColumns;
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));
410 vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetRowIndices(const int theRow)
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);
422 vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetColumnIndices(const int theColumn)
427 for(i = 1; i <= myNbRows; i++) {
428 anIndex = myNbColumns*(i-1)+theColumn;
429 if(myTable.find(anIndex) != myTable.end()) aSeq.push_back(i);
435 string SALOMEDSImpl_AttributeTableOfReal::Save()
438 char* buffer = new char[1024];
443 sprintf(buffer, "%d\n", l);
446 aString += myTitle[i];
451 sprintf(buffer, "%d\n", myNbRows);
455 for(i=0; i<myNbRows; i++) {
456 l = myRows[i].size();
457 sprintf(buffer, "%d\n", l);
460 aString += myRows[i][j];
466 sprintf(buffer, "%d\n", myNbColumns);
470 for(i=0; i<myNbColumns; i++) {
471 l = myCols[i].size();
472 sprintf(buffer, "%d\n", l);
475 aString += myCols[i][j];
480 //Store the table values
482 sprintf(buffer, "%d\n", l);
484 for(MI p = myTable.begin(); p != myTable.end(); p++) {
485 sprintf(buffer, "%d\n%.64e\n", p->first, p->second);
493 void SALOMEDSImpl_AttributeTableOfReal::Load(const string& value)
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));
510 l = strtol(v[pos++].c_str(), NULL, 10);
512 myTitle = std::string(l, 0);
514 myTitle[i] = v[pos++][0];
518 myNbRows = strtol(v[pos++].c_str(), NULL, 10);
522 for(i=1; i<=myNbRows; i++) {
523 l = strtol(v[pos++].c_str(), NULL, 10);
524 aStr = std::string(l,0);
526 aStr[j] = v[pos++][0];
528 myRows.push_back(aStr);
532 myNbColumns = strtol(v[pos++].c_str(), NULL, 10);
536 for(i=1; i<=myNbColumns; i++) {
537 l = strtol(v[pos++].c_str(), NULL, 10);
538 aStr = std::string(l,0);
540 aStr[j] = v[pos++][0];
542 myCols.push_back(aStr);
545 //Restore the table values
546 l = strtol(v[pos++].c_str(), NULL, 10);
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;