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>
25 #include <Standard_Failure.hxx>
26 #include <Standard_GUID.hxx>
28 #include <TColStd_HSequenceOfExtendedString.hxx>
32 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_AttributeTableOfString, SALOMEDSImpl_GenericAttribute )
33 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_AttributeTableOfString, SALOMEDSImpl_GenericAttribute )
35 typedef NCollection_DataMap<Standard_Integer, TCollection_ExtendedString>::Iterator DataMapIterator;
37 #define SEPARATOR '\1'
39 static TCollection_ExtendedString getUnit(TCollection_ExtendedString theString)
41 TCollection_ExtendedString aString(theString);
42 int aPos = aString.Search(SEPARATOR);
43 if(aPos <= 0 || aPos == aString.Length() ) return TCollection_ExtendedString();
44 return aString.Split(aPos);
47 static TCollection_ExtendedString getTitle(TCollection_ExtendedString theString)
49 TCollection_ExtendedString aString(theString);
50 int aPos = aString.Search(SEPARATOR);
51 if(aPos < 1) return aString;
52 if(aPos == 1) return TCollection_ExtendedString();
53 aString.Split(aPos-1);
57 const Standard_GUID& SALOMEDSImpl_AttributeTableOfString::GetID()
59 static Standard_GUID SALOMEDSImpl_AttributeTableOfStringID ("128371A4-8F52-11d6-A8A3-0001021E8C7F");
60 return SALOMEDSImpl_AttributeTableOfStringID;
63 Handle(SALOMEDSImpl_AttributeTableOfString) SALOMEDSImpl_AttributeTableOfString::Set(const TDF_Label& label)
65 Handle(SALOMEDSImpl_AttributeTableOfString) anAttr;
66 if (!label.FindAttribute(SALOMEDSImpl_AttributeTableOfString::GetID(),anAttr)) {
67 anAttr = new SALOMEDSImpl_AttributeTableOfString();
68 label.AddAttribute(anAttr);
73 SALOMEDSImpl_AttributeTableOfString::SALOMEDSImpl_AttributeTableOfString()
74 :SALOMEDSImpl_GenericAttribute("AttributeTableOfString")
76 myRows = new TColStd_HSequenceOfExtendedString();
77 myCols = new TColStd_HSequenceOfExtendedString();
82 void SALOMEDSImpl_AttributeTableOfString::SetNbColumns(const Standard_Integer theNbColumns)
87 DataMapOfIntegerString aMap;
91 DataMapIterator anIterator(aMap);
92 for(; anIterator.More(); anIterator.Next()) {
93 int aRow = (int)(anIterator.Key()/myNbColumns) + 1;
94 int aCol = (int)(anIterator.Key() - myNbColumns*(aRow-1));
95 if(aCol == 0) { aCol = myNbColumns; aRow--; }
96 if(aCol > theNbColumns) continue;
97 int aKey = (aRow-1)*theNbColumns+aCol;
98 myTable.Bind(aKey, anIterator.Value());
101 myNbColumns = theNbColumns;
103 while (myCols->Length() < myNbColumns) { // append empty columns titles
104 myCols->Append(TCollection_ExtendedString(""));
107 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
110 void SALOMEDSImpl_AttributeTableOfString::SetRowTitle(const Standard_Integer theRow,
111 const TCollection_ExtendedString& theTitle)
115 TCollection_ExtendedString aTitle(theTitle), aUnit = GetRowUnit(theRow);
116 if(aUnit.Length()>0) {
120 myRows->SetValue(theRow, aTitle);
122 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
125 void SALOMEDSImpl_AttributeTableOfString::SetRowUnit(const Standard_Integer theRow,
126 const TCollection_ExtendedString& theUnit)
130 TCollection_ExtendedString aTitle = GetRowTitle(theRow);
134 myRows->SetValue(theRow, aTitle);
136 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
139 void SALOMEDSImpl_AttributeTableOfString::SetRowUnits(const Handle(TColStd_HSequenceOfExtendedString)& theUnits)
141 if (theUnits->Length() != GetNbRows()) Standard_Failure::Raise("Invalid number of rows");
142 int aLength = theUnits->Length(), i;
143 for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits->Value(i));
146 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetRowUnits()
148 Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
149 int aLength = myRows->Length(), i;
150 for(i=1; i<=aLength; i++) aSeq->Append(getUnit(myRows->Value(i)));
154 void SALOMEDSImpl_AttributeTableOfString::SetRowTitles(const Handle(TColStd_HSequenceOfExtendedString)& theTitles)
156 if (theTitles->Length() != GetNbRows()) Standard_Failure::Raise("Invalid number of rows");
157 int aLength = theTitles->Length(), i;
158 for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles->Value(i));
160 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
163 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetRowTitles()
165 Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
166 int aLength = myRows->Length(), i;
167 for(i=1; i<=aLength; i++) aSeq->Append(getTitle(myRows->Value(i)));
172 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetRowTitle(const Standard_Integer theRow) const
174 return getTitle(myRows->Value(theRow));
178 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetRowUnit(const Standard_Integer theRow) const
180 return getUnit(myRows->Value(theRow));
183 void SALOMEDSImpl_AttributeTableOfString::SetRowData(const Standard_Integer theRow,
184 const Handle(TColStd_HSequenceOfExtendedString)& theData)
187 if(theData->Length() > myNbColumns) SetNbColumns(theData->Length());
191 while (myRows->Length() < theRow) { // append new row titles
192 myRows->Append(TCollection_ExtendedString(""));
195 Standard_Integer i, aShift = (theRow-1)*myNbColumns, aLength = theData->Length();
196 for(i = 1; i <= aLength; i++) {
197 myTable.Bind(aShift + i, theData->Value(i));
200 if(theRow > myNbRows) myNbRows = theRow;
202 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
205 void SALOMEDSImpl_AttributeTableOfString::SetTitle(const TCollection_ExtendedString& theTitle)
211 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
214 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetTitle() const
219 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetRowData(const Standard_Integer theRow)
221 Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString();
222 Standard_Integer i, aShift = (theRow-1)*myNbColumns;
223 for(i = 1; i <= myNbColumns; i++) {
224 if(myTable.IsBound(aShift+i))
225 aSeq->Append(myTable.Find(aShift+i));
233 void SALOMEDSImpl_AttributeTableOfString::SetColumnData(const Standard_Integer theColumn,
234 const Handle(TColStd_HSequenceOfExtendedString)& theData)
237 if(theColumn > myNbColumns) SetNbColumns(theColumn);
241 Standard_Integer i, aLength = theData->Length();
242 for(i = 1; i <= aLength; i++) {
243 myTable.Bind(myNbColumns*(i-1)+theColumn, theData->Value(i));
246 if(aLength > myNbRows) {
248 while (myRows->Length() < myNbRows) { // append empty row titles
249 myRows->Append(TCollection_ExtendedString(""));
253 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
257 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetColumnData(const Standard_Integer theColumn)
259 Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
261 Standard_Integer i, anIndex;
262 for(i = 1; i <= myNbRows; i++) {
263 anIndex = myNbColumns*(i-1) + theColumn;
264 if(myTable.IsBound(anIndex))
265 aSeq->Append(myTable.Find(anIndex));
273 void SALOMEDSImpl_AttributeTableOfString::SetColumnTitle(const Standard_Integer theColumn,
274 const TCollection_ExtendedString& theTitle)
278 while(myCols->Length() < theColumn) myCols->Append(TCollection_ExtendedString(""));
279 myCols->SetValue(theColumn,theTitle);
281 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
284 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetColumnTitle(const Standard_Integer theColumn) const
286 if(myCols.IsNull()) return "";
287 if(myCols->Length() < theColumn) return "";
288 return myCols->Value(theColumn);
292 void SALOMEDSImpl_AttributeTableOfString::SetColumnTitles(const Handle(TColStd_HSequenceOfExtendedString)& theTitles)
294 if (theTitles->Length() != myNbColumns) Standard_Failure::Raise("Invalid number of columns");
295 int aLength = theTitles->Length(), i;
296 for(i = 1; i <= aLength; i++) myCols->SetValue(i, theTitles->Value(i));
298 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
301 Handle(TColStd_HSequenceOfExtendedString) SALOMEDSImpl_AttributeTableOfString::GetColumnTitles()
303 Handle(TColStd_HSequenceOfExtendedString) aSeq = new TColStd_HSequenceOfExtendedString;
304 int aLength = myCols->Length(), i;
305 for(i=1; i<=aLength; i++) aSeq->Append(myCols->Value(i));
310 Standard_Integer SALOMEDSImpl_AttributeTableOfString::GetNbRows() const
315 Standard_Integer SALOMEDSImpl_AttributeTableOfString::GetNbColumns() const
320 void SALOMEDSImpl_AttributeTableOfString::PutValue(const TCollection_ExtendedString& theValue,
321 const Standard_Integer theRow,
322 const Standard_Integer theColumn)
325 if(theColumn > myNbColumns) SetNbColumns(theColumn);
327 Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
328 myTable.Bind(anIndex, theValue);
330 if(theRow > myNbRows) {
331 while (myRows->Length() < theRow) { // append empty row titles
332 myRows->Append(TCollection_ExtendedString(""));
337 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
340 Standard_Boolean SALOMEDSImpl_AttributeTableOfString::HasValue(const Standard_Integer theRow,
341 const Standard_Integer theColumn)
343 if(theRow > myNbRows || theRow < 1) return Standard_False;
344 if(theColumn > myNbColumns || theColumn < 1) return Standard_False;
346 Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
347 return myTable.IsBound(anIndex);
350 TCollection_ExtendedString SALOMEDSImpl_AttributeTableOfString::GetValue(const Standard_Integer theRow,
351 const Standard_Integer theColumn)
353 if(theRow > myNbRows || theRow < 1) Standard_Failure::Raise("Invalid cell index");
354 if(theColumn > myNbColumns || theColumn < 1) Standard_Failure::Raise("Invalid cell index");
356 Standard_Integer anIndex = (theRow-1)*myNbColumns + theColumn;
357 if(myTable.IsBound(anIndex)) return myTable.Find(anIndex);
359 Standard_Failure::Raise("Invalid cell index");
363 const Standard_GUID& SALOMEDSImpl_AttributeTableOfString::ID() const
368 void SALOMEDSImpl_AttributeTableOfString::Restore(const Handle(TDF_Attribute)& with)
370 Standard_Integer anIndex;
371 Handle(SALOMEDSImpl_AttributeTableOfString) aTable = Handle(SALOMEDSImpl_AttributeTableOfString)::DownCast(with);
377 myTable = aTable->myTable;
378 myNbRows = aTable->myNbRows;
379 myNbColumns = aTable->myNbColumns;
380 myTitle = aTable->myTitle;
382 for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
383 myRows->Append(aTable->GetRowTitle(anIndex));
385 for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++)
386 myCols->Append(aTable->GetColumnTitle(anIndex));
389 Handle(TDF_Attribute) SALOMEDSImpl_AttributeTableOfString::NewEmpty() const
391 return new SALOMEDSImpl_AttributeTableOfString();
394 void SALOMEDSImpl_AttributeTableOfString::Paste(const Handle(TDF_Attribute)& into,
395 const Handle(TDF_RelocationTable)&) const
397 Standard_Integer anIndex;
398 Handle(SALOMEDSImpl_AttributeTableOfString) aTable = Handle(SALOMEDSImpl_AttributeTableOfString)::DownCast(into);
400 aTable->myTable.Clear();
401 aTable->myCols->Clear();
402 aTable->myRows->Clear();
404 aTable->myTable = myTable;
405 aTable->myTitle = myTitle;
406 aTable->myNbRows = myNbRows;
407 aTable->myNbColumns = myNbColumns;
409 for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
410 aTable->myRows->Append(GetRowTitle(anIndex));
411 for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++)
412 aTable->myCols->Append(GetColumnTitle(anIndex));
416 Handle_TColStd_HSequenceOfInteger SALOMEDSImpl_AttributeTableOfString::GetSetRowIndices(const Standard_Integer theRow)
418 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
420 Standard_Integer i, aShift = myNbColumns*(theRow-1);
421 for(i = 1; i <= myNbColumns; i++) {
422 if(myTable.IsBound(aShift + i)) aSeq->Append(i);
428 Handle_TColStd_HSequenceOfInteger SALOMEDSImpl_AttributeTableOfString::GetSetColumnIndices(const Standard_Integer theColumn)
430 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
432 Standard_Integer i, anIndex;
433 for(i = 1; i <= myNbRows; i++) {
434 anIndex = myNbColumns*(i-1)+theColumn;
435 if(myTable.IsBound(anIndex)) aSeq->Append(i);
443 void SALOMEDSImpl_AttributeTableOfString::ConvertToString(ostrstream& theStream)
448 l = myTitle.Length();
449 theStream << l << "\n";
451 theStream << myTitle.Value(i) << "\n";
454 theStream << myNbRows << "\n";
457 for(i=1; i<=myNbRows; i++) {
458 l = myRows->Value(i).Length();
459 theStream << l << "\n";
461 theStream << myRows->Value(i).Value(j) << "\n";
465 theStream << myNbColumns << "\n";
468 for(i=1; i<=myNbColumns; i++) {
469 l = myCols->Value(i).Length();
470 theStream << l << "\n";
472 theStream << myCols->Value(i).Value(j) << "\n";
475 //Store the table values
476 l = myTable.Extent();
477 theStream << l << "\n";
478 DataMapIterator anIterator(myTable);
479 for(; anIterator.More(); anIterator.Next()) {
480 if (anIterator.Value().Length()) { // check empty string in the value table
481 theStream << anIterator.Key() << "\n";
482 unsigned long aValueSize = anIterator.Value().Length();
483 theStream<<aValueSize << "\n";
484 theStream.write((TCollection_AsciiString(anIterator.Value()).ToCString()),aValueSize);
486 } else { // write index only of kind: "0key"; "05", for an example
487 theStream << "0" << anIterator.Key() << "\n";
493 bool SALOMEDSImpl_AttributeTableOfString::RestoreFromString(istrstream& theStream)
497 theStream.seekg(0, ios::end);
498 long aSize = theStream.tellg();
499 theStream.seekg(0, ios::beg);
502 char *aValueString = new char[aSize];
504 Standard_ExtCharacter anExtChar;
505 TCollection_ExtendedString aStr;
510 myTitle = TCollection_ExtendedString(l, 0);
511 for(i=1; i<=l; i++) {
512 theStream >> anExtChar;
513 myTitle.SetValue(i, anExtChar);
517 theStream >> myNbRows;
521 for(i=1; i<=myNbRows; i++) {
523 aStr = TCollection_ExtendedString(l,0);
524 for(j=1; j<=l; j++) {
525 theStream >> anExtChar;
526 aStr.SetValue(j, anExtChar);
528 myRows->Append(aStr);
532 theStream >> myNbColumns;
536 for(i=1; i<=myNbColumns; i++) {
538 aStr = TCollection_ExtendedString(l,0);
539 for(j=1; j<=l; j++) {
540 theStream >> anExtChar;
541 aStr.SetValue(j, anExtChar);
543 myCols->Append(aStr);
546 //Restore the table values
547 TCollection_AsciiString aValue;
550 theStream.getline(aValueString,aSize,'\n');
551 for(i=1; i<=l; i++) {
552 Standard_Integer aKey;
554 theStream.getline(aValueString,aSize,'\n');
555 aValue = aValueString;
556 aKey = aValue.IntegerValue();
557 if (aValue.Value(1) == '0')
560 unsigned long aValueSize;
561 theStream >> aValueSize;
562 theStream.read(aValueString, 1); // an '\n' omitting
563 theStream.read(aValueString, aValueSize);
564 theStream.read(aValueString, 1); // an '\n' omitting
565 aValue = aValueString;
567 myTable.Bind(aKey, aValue);
569 delete(aValueString);
573 TCollection_AsciiString SALOMEDSImpl_AttributeTableOfString::Save()
576 ConvertToString(ostr);
577 TCollection_AsciiString aString((char*)ostr.rdbuf()->str());
581 void SALOMEDSImpl_AttributeTableOfString::Load(const TCollection_AsciiString& value)
583 istrstream aStream(value.ToCString(), strlen(value.ToCString()));
584 RestoreFromString(aStream);