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_AttributeTableOfString.cxx
23 // Author : Sergey Ruin
26 #include "SALOMEDSImpl_AttributeTableOfString.hxx"
33 #define SEPARATOR '\1'
35 typedef map<int, string>::const_iterator MI;
37 static std::string getUnit(std::string theString)
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());
45 static std::string getTitle(std::string theString)
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);
54 const std::string& SALOMEDSImpl_AttributeTableOfString::GetID()
56 static std::string SALOMEDSImpl_AttributeTableOfStringID ("128371A4-8F52-11d6-A8A3-0001021E8C7F");
57 return SALOMEDSImpl_AttributeTableOfStringID;
60 SALOMEDSImpl_AttributeTableOfString* SALOMEDSImpl_AttributeTableOfString::Set(const DF_Label& label)
62 SALOMEDSImpl_AttributeTableOfString* A = NULL;
63 if (!(A=(SALOMEDSImpl_AttributeTableOfString*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfString::GetID()))) {
64 A = new SALOMEDSImpl_AttributeTableOfString();
65 label.AddAttribute(A);
70 SALOMEDSImpl_AttributeTableOfString::SALOMEDSImpl_AttributeTableOfString()
71 :SALOMEDSImpl_GenericAttribute("AttributeTableOfString")
77 void SALOMEDSImpl_AttributeTableOfString::SetNbColumns(const int theNbColumns)
82 map<int, string> aMap;
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;
95 myNbColumns = theNbColumns;
97 while (myCols.size() < myNbColumns) { // append empty columns titles
98 myCols.push_back(std::string(""));
101 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
104 void SALOMEDSImpl_AttributeTableOfString::SetRowTitle(const int theRow,
105 const std::string& theTitle)
109 std::string aTitle(theTitle), aUnit = GetRowUnit(theRow);
114 myRows[theRow-1] = aTitle;
116 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
119 void SALOMEDSImpl_AttributeTableOfString::SetRowUnit(const int theRow,
120 const std::string& theUnit)
124 std::string aTitle = GetRowTitle(theRow);
128 myRows[theRow-1] = aTitle;
130 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
133 void SALOMEDSImpl_AttributeTableOfString::SetRowUnits(const vector<string>& theUnits)
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]);
140 vector<string> SALOMEDSImpl_AttributeTableOfString::GetRowUnits()
143 int aLength = myRows.size(), i;
144 for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
148 void SALOMEDSImpl_AttributeTableOfString::SetRowTitles(const vector<string>& theTitles)
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]);
154 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
157 vector<string> SALOMEDSImpl_AttributeTableOfString::GetRowTitles()
160 int aLength = myRows.size(), i;
161 for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
166 std::string SALOMEDSImpl_AttributeTableOfString::GetRowTitle(const int theRow) const
168 return getTitle(myRows[theRow-1]);
172 std::string SALOMEDSImpl_AttributeTableOfString::GetRowUnit(const int theRow) const
174 return getUnit(myRows[theRow-1]);
177 void SALOMEDSImpl_AttributeTableOfString::SetRowData(const int theRow,
178 const vector<string>& theData)
181 if(theData.size() > myNbColumns) SetNbColumns(theData.size());
185 while (myRows.size() < theRow) { // append new row titles
186 myRows.push_back(std::string(""));
189 int i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
190 for(i = 1; i <= aLength; i++) {
191 myTable[aShift + i] = theData[i-1];
194 if(theRow > myNbRows) myNbRows = theRow;
196 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
199 void SALOMEDSImpl_AttributeTableOfString::SetTitle(const std::string& theTitle)
205 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
208 std::string SALOMEDSImpl_AttributeTableOfString::GetTitle() const
213 vector<string> SALOMEDSImpl_AttributeTableOfString::GetRowData(const int theRow)
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]);
227 void SALOMEDSImpl_AttributeTableOfString::SetColumnData(const int theColumn,
228 const vector<string>& 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(std::string(""));
247 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
251 vector<string> SALOMEDSImpl_AttributeTableOfString::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_AttributeTableOfString::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_AttributeTableOfString::GetColumnTitle(const int theColumn) const
280 if(myCols.empty()) return "";
281 if(myCols.size() < theColumn) return "";
282 return myCols[theColumn-1];
286 void SALOMEDSImpl_AttributeTableOfString::SetColumnTitles(const vector<string>& theTitles)
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];
292 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
295 vector<string> SALOMEDSImpl_AttributeTableOfString::GetColumnTitles()
298 int aLength = myCols.size(), i;
299 for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
304 int SALOMEDSImpl_AttributeTableOfString::GetNbRows() const
309 int SALOMEDSImpl_AttributeTableOfString::GetNbColumns() const
314 void SALOMEDSImpl_AttributeTableOfString::PutValue(const std::string& 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_AttributeTableOfString::HasValue(const int theRow,
337 if(theRow > myNbRows || theRow < 1) return false;
338 if(theColumn > myNbColumns || theColumn < 1) return false;
340 int anIndex = (theRow-1)*myNbColumns + theColumn;
341 return (myTable.find(anIndex) != myTable.end());
344 std::string SALOMEDSImpl_AttributeTableOfString::GetValue(const int theRow,
347 if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
348 if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
350 int anIndex = (theRow-1)*myNbColumns + theColumn;
351 if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
353 throw DFexception("Invalid cell index");
357 const std::string& SALOMEDSImpl_AttributeTableOfString::ID() const
362 void SALOMEDSImpl_AttributeTableOfString::Restore(DF_Attribute* with)
365 SALOMEDSImpl_AttributeTableOfString* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfString*>(with);
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_AttributeTableOfString::NewEmpty() const
385 return new SALOMEDSImpl_AttributeTableOfString();
388 void SALOMEDSImpl_AttributeTableOfString::Paste(DF_Attribute* into)
391 SALOMEDSImpl_AttributeTableOfString* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfString*>(into);
393 aTable->myTable.clear();
394 aTable->myCols.clear();
395 aTable->myRows.clear();
397 aTable->myTable = myTable;
398 aTable->myTitle = myTitle;
399 aTable->myNbRows = myNbRows;
400 aTable->myNbColumns = myNbColumns;
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));
409 vector<int> SALOMEDSImpl_AttributeTableOfString::GetSetRowIndices(const int theRow)
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);
421 vector<int> SALOMEDSImpl_AttributeTableOfString::GetSetColumnIndices(const int theColumn)
426 for(i = 1; i <= myNbRows; i++) {
427 anIndex = myNbColumns*(i-1)+theColumn;
428 if(myTable.find(anIndex) != myTable.end()) aSeq.push_back(i);
436 string SALOMEDSImpl_AttributeTableOfString::Save()
439 char* buffer = new char[1024];
444 sprintf(buffer, "%d\n", l);
447 aString += myTitle[i];
452 sprintf(buffer, "%d\n", myNbRows);
456 for(i=0; i<myNbRows; i++) {
457 l = myRows[i].size();
458 sprintf(buffer, "%d\n", l);
461 aString += myRows[i][j];
467 sprintf(buffer, "%d\n", myNbColumns);
471 for(i=0; i<myNbColumns; i++) {
472 l = myCols[i].size();
473 sprintf(buffer, "%d\n", l);
476 aString += myCols[i][j];
481 //Store the table values
483 sprintf(buffer, "%d\n", l);
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);
489 unsigned long aValueSize = p->second.size();
490 sprintf(buffer, "%ld\n", aValueSize);
492 aString += p->second;
494 } else { // write index only of kind: "0key"; "05", for an example
495 sprintf(buffer, "0%d\n", p->first);
504 void SALOMEDSImpl_AttributeTableOfString::Load(const string& value)
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));
521 l = strtol(v[pos++].c_str(), NULL, 10);
523 myTitle = std::string(l, 0);
525 myTitle[i] = v[pos++][0];
529 myNbRows = strtol(v[pos++].c_str(), NULL, 10);
533 for(i=1; i<=myNbRows; i++) {
534 l = strtol(v[pos++].c_str(), NULL, 10);
535 aStr = std::string(l,0);
537 aStr[j] = v[pos++][0];
539 myRows.push_back(aStr);
543 myNbColumns = strtol(v[pos++].c_str(), NULL, 10);
547 for(i=1; i<=myNbColumns; i++) {
548 l = strtol(v[pos++].c_str(), NULL, 10);
549 aStr = std::string(l,0);
551 aStr[j] = v[pos++][0];
553 myCols.push_back(aStr);
556 //Restore the table values
557 l = strtol(v[pos++].c_str(), NULL, 10);
559 for(i=1; i<=l; i++) {
560 aStr = v[pos++]; //Ket as a string
561 int aKey = strtol(aStr.c_str(), NULL, 10);
563 if(aStr[0] == '0') //If the first character of the key is 0, then empty value
566 strtol(v[pos++].c_str(), NULL, 10);
569 myTable[aKey] = aValue;