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_AttributeTableOfString.cxx
21 // Author : Sergey Ruin
24 #include <SALOMEDSImpl_AttributeTableOfString.hxx>
31 #define SEPARATOR '\1'
33 typedef map<int, string>::const_iterator MI;
35 static std::string getUnit(std::string theString)
37 std::string aString(theString);
38 int aPos = aString.find(SEPARATOR);
39 if(aPos <= 0 || aPos == aString.size() ) return std::string();
40 return aString.substr(aPos+1, aString.size());
43 static std::string getTitle(std::string theString)
45 std::string aString(theString);
46 int aPos = aString.find(SEPARATOR);
47 if(aPos < 1) return aString;
48 if(aPos == 1) return std::string();
49 return aString.substr(0, aPos);
52 const std::string& SALOMEDSImpl_AttributeTableOfString::GetID()
54 static std::string SALOMEDSImpl_AttributeTableOfStringID ("128371A4-8F52-11d6-A8A3-0001021E8C7F");
55 return SALOMEDSImpl_AttributeTableOfStringID;
58 SALOMEDSImpl_AttributeTableOfString* SALOMEDSImpl_AttributeTableOfString::Set(const DF_Label& label)
60 SALOMEDSImpl_AttributeTableOfString* A = NULL;
61 if (!(A=(SALOMEDSImpl_AttributeTableOfString*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfString::GetID()))) {
62 A = new SALOMEDSImpl_AttributeTableOfString();
63 label.AddAttribute(A);
68 SALOMEDSImpl_AttributeTableOfString::SALOMEDSImpl_AttributeTableOfString()
69 :SALOMEDSImpl_GenericAttribute("AttributeTableOfString")
75 void SALOMEDSImpl_AttributeTableOfString::SetNbColumns(const int theNbColumns)
80 map<int, string> aMap;
84 for(MI p = aMap.begin(); p!=aMap.end(); p++) {
85 int aRow = (int)(p->first/myNbColumns) + 1;
86 int aCol = (int)(p->first - myNbColumns*(aRow-1));
87 if(aCol == 0) { aCol = myNbColumns; aRow--; }
88 if(aCol > theNbColumns) continue;
89 int aKey = (aRow-1)*theNbColumns+aCol;
90 myTable[aKey] = p->second;
93 myNbColumns = theNbColumns;
95 while (myCols.size() < myNbColumns) { // append empty columns titles
96 myCols.push_back(std::string(""));
99 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
102 void SALOMEDSImpl_AttributeTableOfString::SetRowTitle(const int theRow,
103 const std::string& theTitle)
107 std::string aTitle(theTitle), aUnit = GetRowUnit(theRow);
112 myRows[theRow-1] = aTitle;
114 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
117 void SALOMEDSImpl_AttributeTableOfString::SetRowUnit(const int theRow,
118 const std::string& theUnit)
122 std::string aTitle = GetRowTitle(theRow);
126 myRows[theRow-1] = aTitle;
128 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
131 void SALOMEDSImpl_AttributeTableOfString::SetRowUnits(const vector<string>& theUnits)
133 if (theUnits.size() != GetNbRows()) throw DFexception("Invalid number of rows");
134 int aLength = theUnits.size(), i;
135 for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits[i-1]);
138 vector<string> SALOMEDSImpl_AttributeTableOfString::GetRowUnits()
141 int aLength = myRows.size(), i;
142 for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
146 void SALOMEDSImpl_AttributeTableOfString::SetRowTitles(const vector<string>& theTitles)
148 if (theTitles.size() != GetNbRows()) throw DFexception("Invalid number of rows");
149 int aLength = theTitles.size(), i;
150 for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles[i-1]);
152 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
155 vector<string> SALOMEDSImpl_AttributeTableOfString::GetRowTitles()
158 int aLength = myRows.size(), i;
159 for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
164 std::string SALOMEDSImpl_AttributeTableOfString::GetRowTitle(const int theRow) const
166 return getTitle(myRows[theRow-1]);
170 std::string SALOMEDSImpl_AttributeTableOfString::GetRowUnit(const int theRow) const
172 return getUnit(myRows[theRow-1]);
175 void SALOMEDSImpl_AttributeTableOfString::SetRowData(const int theRow,
176 const vector<string>& theData)
179 if(theData.size() > myNbColumns) SetNbColumns(theData.size());
183 while (myRows.size() < theRow) { // append new row titles
184 myRows.push_back(std::string(""));
187 int i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
188 for(i = 1; i <= aLength; i++) {
189 myTable[aShift + i] = theData[i-1];
192 if(theRow > myNbRows) myNbRows = theRow;
194 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
197 void SALOMEDSImpl_AttributeTableOfString::SetTitle(const std::string& theTitle)
203 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
206 std::string SALOMEDSImpl_AttributeTableOfString::GetTitle() const
211 vector<string> SALOMEDSImpl_AttributeTableOfString::GetRowData(const int theRow)
214 int i, aShift = (theRow-1)*myNbColumns;
215 for(i = 1; i <= myNbColumns; i++) {
216 if(myTable.find(aShift+i) != myTable.end())
217 aSeq.push_back(myTable[aShift+i]);
225 void SALOMEDSImpl_AttributeTableOfString::SetColumnData(const int theColumn,
226 const vector<string>& theData)
229 if(theColumn > myNbColumns) SetNbColumns(theColumn);
233 int i, aLength = theData.size();
234 for(i = 1; i <= aLength; i++) {
235 myTable[myNbColumns*(i-1)+theColumn] = theData[i-1];
238 if(aLength > myNbRows) {
240 while (myRows.size() < myNbRows) { // append empty row titles
241 myRows.push_back(std::string(""));
245 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
249 vector<string> SALOMEDSImpl_AttributeTableOfString::GetColumnData(const int theColumn)
254 for(i = 1; i <= myNbRows; i++) {
255 anIndex = myNbColumns*(i-1) + theColumn;
256 if(myTable.find(anIndex) != myTable.end())
257 aSeq.push_back(myTable[anIndex]);
265 void SALOMEDSImpl_AttributeTableOfString::SetColumnTitle(const int theColumn,
266 const std::string& theTitle)
270 while(myCols.size() < theColumn) myCols.push_back(std::string(""));
271 myCols[theColumn-1] = theTitle;
273 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
276 std::string SALOMEDSImpl_AttributeTableOfString::GetColumnTitle(const int theColumn) const
278 if(myCols.empty()) return "";
279 if(myCols.size() < theColumn) return "";
280 return myCols[theColumn-1];
284 void SALOMEDSImpl_AttributeTableOfString::SetColumnTitles(const vector<string>& theTitles)
286 if (theTitles.size() != myNbColumns) throw DFexception("Invalid number of columns");
287 int aLength = theTitles.size(), i;
288 for(i = 0; i < aLength; i++) myCols[i] = theTitles[i];
290 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
293 vector<string> SALOMEDSImpl_AttributeTableOfString::GetColumnTitles()
296 int aLength = myCols.size(), i;
297 for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
302 int SALOMEDSImpl_AttributeTableOfString::GetNbRows() const
307 int SALOMEDSImpl_AttributeTableOfString::GetNbColumns() const
312 void SALOMEDSImpl_AttributeTableOfString::PutValue(const std::string& 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_AttributeTableOfString::HasValue(const int theRow,
335 if(theRow > myNbRows || theRow < 1) return false;
336 if(theColumn > myNbColumns || theColumn < 1) return false;
338 int anIndex = (theRow-1)*myNbColumns + theColumn;
339 return (myTable.find(anIndex) != myTable.end());
342 std::string SALOMEDSImpl_AttributeTableOfString::GetValue(const int theRow,
345 if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
346 if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
348 int anIndex = (theRow-1)*myNbColumns + theColumn;
349 if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
351 throw DFexception("Invalid cell index");
355 const std::string& SALOMEDSImpl_AttributeTableOfString::ID() const
360 void SALOMEDSImpl_AttributeTableOfString::Restore(DF_Attribute* with)
363 SALOMEDSImpl_AttributeTableOfString* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfString*>(with);
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_AttributeTableOfString::NewEmpty() const
383 return new SALOMEDSImpl_AttributeTableOfString();
386 void SALOMEDSImpl_AttributeTableOfString::Paste(DF_Attribute* into)
389 SALOMEDSImpl_AttributeTableOfString* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfString*>(into);
391 aTable->myTable.clear();
392 aTable->myCols.clear();
393 aTable->myRows.clear();
395 aTable->myTable = myTable;
396 aTable->myTitle = myTitle;
397 aTable->myNbRows = myNbRows;
398 aTable->myNbColumns = myNbColumns;
400 for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
401 aTable->myRows.push_back(GetRowTitle(anIndex));
402 for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++)
403 aTable->myCols.push_back(GetColumnTitle(anIndex));
407 vector<int> SALOMEDSImpl_AttributeTableOfString::GetSetRowIndices(const int theRow)
411 int i, aShift = myNbColumns*(theRow-1);
412 for(i = 1; i <= myNbColumns; i++) {
413 if(myTable.find(aShift + i) != myTable.end()) aSeq.push_back(i);
419 vector<int> SALOMEDSImpl_AttributeTableOfString::GetSetColumnIndices(const int theColumn)
424 for(i = 1; i <= myNbRows; i++) {
425 anIndex = myNbColumns*(i-1)+theColumn;
426 if(myTable.find(anIndex) != myTable.end()) aSeq.push_back(i);
434 string SALOMEDSImpl_AttributeTableOfString::Save()
436 ostrstream theStream;
441 theStream << l << "\n";
443 theStream << myTitle[i] << "\n";
446 theStream << myNbRows << "\n";
449 for(i=0; i<myNbRows; i++) {
450 l = myRows[i].size();
451 theStream << l << "\n";
453 theStream << myRows[i][j] << "\n";
457 theStream << myNbColumns << "\n";
460 for(i=0; i<myNbColumns; i++) {
461 l = myCols[i].size();
462 theStream << l << "\n";
464 theStream << myCols[i][j] << "\n";
467 //Store the table values
469 theStream << l << "\n";
470 for(MI p = myTable.begin(); p!=myTable.end(); p++) {
471 if (p->second.size()) { // check empty string in the value table
472 theStream << p->first << "\n";
473 unsigned long aValueSize = p->second.size();
474 theStream<<aValueSize << "\n";
475 theStream.write(p->second.c_str(),aValueSize);
477 } else { // write index only of kind: "0key"; "05", for an example
478 theStream << "0" << p->first << "\n";
481 string aString((char*)theStream.rdbuf()->str());
485 void SALOMEDSImpl_AttributeTableOfString::Load(const string& value)
487 istrstream theStream(value.c_str(), strlen(value.c_str()));
490 theStream.seekg(0, ios::end);
491 long aSize = theStream.tellg();
492 theStream.seekg(0, ios::beg);
495 char *aValueString = new char[aSize];
503 myTitle = std::string(l, 0);
505 theStream >> anExtChar;
506 myTitle[i] = anExtChar;
510 theStream >> myNbRows;
514 for(i=0; i<myNbRows; i++) {
516 aStr = std::string(l,0);
518 theStream >> anExtChar;
521 myRows.push_back(aStr);
525 theStream >> myNbColumns;
529 for(i=0; i<myNbColumns; i++) {
531 aStr = std::string(l,0);
533 theStream >> anExtChar;
536 myCols.push_back(aStr);
539 //Restore the table values
543 theStream.getline(aValueString,aSize,'\n');
544 for(i=1; i<=l; i++) {
547 theStream.getline(aValueString,aSize,'\n');
548 aValue = aValueString;
549 aKey = atoi(aValue.c_str());
550 if (aValue[0] == '0')
553 unsigned long aValueSize;
554 theStream >> aValueSize;
555 theStream.read(aValueString, 1); // an '\n' omitting
556 theStream.read(aValueString, aValueSize);
557 theStream.read(aValueString, 1); // an '\n' omitting
558 aValue = aValueString;
560 myTable[aKey] = aValue;
562 delete(aValueString);