fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / FileIO / OSG / OSGOSGWriter.cpp
blobb22a2a94ccf29664d7ebb67fae13068c4b496a41
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright 2000-2002 by OpenSG Forum *
6 * *
7 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
8 * *
9 \*---------------------------------------------------------------------------*/
10 /*---------------------------------------------------------------------------*\
11 * License *
12 * *
13 * This library is free software; you can redistribute it and/or modify it *
14 * under the terms of the GNU Library General Public License as published *
15 * by the Free Software Foundation, version 2. *
16 * *
17 * This library is distributed in the hope that it will be useful, but *
18 * WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
20 * Library General Public License for more details. *
21 * *
22 * You should have received a copy of the GNU Library General Public *
23 * License along with this library; if not, write to the Free Software *
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
25 * *
26 \*---------------------------------------------------------------------------*/
27 /*---------------------------------------------------------------------------*\
28 * Changes *
29 * *
30 * *
31 * *
32 * *
33 * *
34 * *
35 \*---------------------------------------------------------------------------*/
37 //---------------------------------------------------------------------------
38 // Includes
39 //---------------------------------------------------------------------------
41 #include "OSGOSGWriter.h"
42 //#include "OSGAttachment.h"
43 //#include "OSGSimpleAttachments.h"
44 //#include "OSGVRMLNodeDescs.h"
46 #include "OSGAttachmentMapSFields.h"
47 #include "OSGAttachment.h"
48 #include "OSGNameAttachment.h"
50 #include <boost/bind.hpp>
52 OSG_USING_NAMESPACE
54 #define WFC
56 #if 0
57 #if defined(OSG_WIN32_ICL)
58 #pragma warning (disable : 383)
59 #endif
61 #if defined(OSG_WIN32_ICL)
62 #pragma warning (default : 383)
63 #endif
64 #endif
66 const UInt32 OSGWriter::DefaultSFWidth = TypeTraits<UInt32>::getMax();
67 const UInt32 OSGWriter::DefaultMFWidth = 60;
69 /*-------------------------------------------------------------------------*/
70 /* Constructor */
72 /*! Constructor. Set members to initial values.
74 OSGWriter::FCInfoHelper::FCInfoHelper(void) :
75 written (false),
76 hasName (false),
77 containerName( )
81 /*! Constructor. Set members to initial values.
83 OSGWriter::OSGWriter(OutStream &stream, UInt32 indentStep) :
84 _visitedFCMap( ),
85 _outStream (stream )
89 /*-------------------------------------------------------------------------*/
90 /* Destructor */
92 /*! Destructor. There are no dynamic members to destroy.
94 OSGWriter::~OSGWriter(void)
98 /*-------------------------------------------------------------------------*/
99 /* Methods */
101 /*! Write a single FieldContainer with all its "children", i.e. everything
102 * that can be reached via Ptr-Fields.
104 void OSGWriter::write(FieldContainer *container)
106 _visitedFCMap.clear();
107 // _indent.setIndent(0);
109 _outStream << "#OSG V1.0 ";
110 _outStream << "\n";
112 visitContainer(container);
113 writeContainer(container, true);
117 /*! Write all FieldContainers in containers with their "children",
118 * i.e. everything that can be reached via Ptr-Fields.
120 void OSGWriter::write(std::vector<FieldContainer *> containers)
122 _visitedFCMap.clear();
123 // _indent.setIndent(0);
125 _outStream << "#OSG V1.0 " << "\n";
127 std::vector<FieldContainer *>::reverse_iterator iter;
129 for(iter = containers.rbegin(); iter != containers.rend(); ++iter)
131 visitContainer(*iter);
134 for(iter = containers.rbegin(); iter != containers.rend(); ++iter)
136 writeContainer(*iter, true);
141 /*! Set the name by which this FieldContainer is referenced. If available
142 * a NameAttachment is used, otherwise the name is constructed from
143 * the type name and the container id.
146 void OSGWriter::FCInfoHelper::setName(FieldContainer * const pFC)
148 AttachmentContainer *pAttCon = dynamic_cast<AttachmentContainer *>(pFC);
150 if(pAttCon != NULL)
152 const Char8 *szName = getName(pAttCon);
154 if(szName != NULL)
156 containerName = szName;
157 return;
161 //no NameAttachment. Build name from Type and Id
162 containerName = pFC->getTypeName();
164 TypeTraits<UInt32>::putToString(pFC->getId(), containerName);
168 void OSGWriter::visitContainer(FieldContainer * const pFC)
171 if(pFC == NULL)
173 return;
176 typedef std::pair<FCInfoHelperMap::iterator, bool> MapInsertInfo;
178 std::string containerName;
179 // const FieldContainerType &fcType = pFC->getType();
180 UInt32 numFields = pFC->getNumFields();
181 MapInsertInfo insertInfo;
183 insertInfo = _visitedFCMap.insert(std::make_pair(pFC, FCInfoHelper()));
185 if(insertInfo.second == true)
187 //the FC was NOT visited before
188 for(UInt32 field = 1; field <= numFields; field++)
190 GetFieldHandlePtr fHandle = pFC->getField(field);
192 if(fHandle == NULL || (fHandle != NULL && fHandle->isInternal()))
194 continue;
197 visitField(fHandle);
200 else
202 //the FC was in the map => FC is shared
204 FCInfoHelperMap::iterator iter = _visitedFCMap.find(pFC);
206 if(iter == _visitedFCMap.end())
208 SWARNING << "OSGWriter::visitContainer(): FieldContainer * "
209 << "not found in map" << std::endl;
210 return;
212 if(iter->second.hasName == false)
214 iter->second.setName(pFC);
215 iter->second.hasName = true;
220 void OSGWriter::visitField(GetFieldHandlePtr hF)
222 if(hF->isValid() == false)
224 return;
227 // const FieldType &fType = hF->getType();
229 GetMapFieldHandlePtr sfMap =
230 boost::dynamic_pointer_cast<
231 GetMapFieldHandle>(hF);
233 if(sfMap != NULL && sfMap->isValid() == true)
235 sfMap->traverse(boost::bind(&OSGWriter::visitContainer, this, _1));
237 else
239 FieldContainerPtrSFieldBase::GetHandlePtr sfFCPtr =
240 boost::dynamic_pointer_cast<
241 FieldContainerPtrSFieldBase::GetHandle>(hF);
243 FieldContainerPtrMFieldBase::GetHandlePtr mfFCPtr =
244 boost::dynamic_pointer_cast<
245 FieldContainerPtrMFieldBase::GetHandle>(hF);
247 if(sfFCPtr != NULL && sfFCPtr->isValid() == true)
249 visitContainer((*sfFCPtr)->getValue());
251 else if(mfFCPtr != NULL && mfFCPtr->isValid() == true)
253 SizeT mfSize = (*mfFCPtr)->size();
255 for(SizeT i = 0; i < mfSize; i++)
257 visitContainer((**mfFCPtr)[i]);
264 void OSGWriter::writeContainer(FieldContainer * const pFC,
265 bool bIndent)
267 if(pFC == NULL)
269 return;
272 UInt32 numFields = pFC->getNumFields();
274 FCInfoHelperMap::iterator iter = _visitedFCMap.find(pFC);
276 if(iter == _visitedFCMap.end())
278 SWARNING << "OSGWriter::writeContainer(): FieldContainer * "
279 << "not found in map" << std::endl;
280 return;
283 if(!iter->second.written)
285 //FC is not written yet
286 iter->second.written = true;
288 if(bIndent == true)
290 _outStream << BeginElem;
293 if(iter->second.hasName)
295 _outStream << "DEF "
296 << iter->second.containerName
297 << " "
298 << pFC->getTypeName()
299 << EndElemNL
300 << BeginElem
301 << "{"
302 << EndElemNL;
304 else
306 _outStream << pFC->getTypeName()
307 << EndElemNL
308 << BeginElem
309 << "{"
310 << EndElemNL;
313 _outStream << IncIndent;
315 for(UInt32 field = numFields; field > 0; field--)
317 GetFieldHandlePtr fHandle = pFC->getField(field);
319 if(fHandle == NULL || (fHandle != NULL && fHandle->isInternal()))
321 continue;
324 writeField(fHandle);
327 _outStream << DecIndent;
329 _outStream << BeginElem
330 << "}"
331 << EndElemNL;
333 else
335 //FC is already written -> its shared -> write reference
336 if(!iter->second.hasName)
338 SWARNING << "OSGWriter::writeContainer(): FieldContainer is "
339 << "shared, but not named"
340 << std::endl;
341 return;
344 if(bIndent == true)
346 _outStream << BeginElem;
349 _outStream << "USE "
350 << iter->second.containerName
351 << EndElemNL;
357 void OSGWriter::writeField(GetFieldHandlePtr hF)
359 if(hF->isValid() == false)
361 return;
364 // const FieldType& fType = hF->getType();
366 GetMapFieldHandlePtr sfMap =
367 boost::dynamic_pointer_cast<
368 GetMapFieldHandle>(hF);
370 FieldContainerPtrSFieldBase::GetHandlePtr sfFCPtr =
371 boost::dynamic_pointer_cast<FieldContainerPtrSFieldBase::GetHandle>(hF);
373 FieldContainerPtrMFieldBase::GetHandlePtr mfFCPtr =
374 boost::dynamic_pointer_cast<FieldContainerPtrMFieldBase::GetHandle>(hF);
376 if(sfMap != NULL && sfMap->isValid() == true)
378 _outStream << BeginElem
379 << hF->getName();
381 //if the Attachment Map is empty write [] as its content
382 if(sfMap->empty() == true)
384 _outStream << " [ ] " << EndElemNL;
386 else
388 _outStream << EndElemNL
389 << BeginElem
390 << "["
391 << EndElemNL;
393 _outStream << IncIndent;
395 EditMapFieldHandle::MapList fcList;
397 sfMap->flatten(fcList);
399 EditMapFieldHandle::MapList::iterator iter = fcList.begin();
400 EditMapFieldHandle::MapList::iterator end = fcList.end ();
402 for(; iter!=end; ++iter)
404 _outStream << BeginElem
405 << "MapHelper"
406 << EndElemNL
407 << BeginElem
408 << "{"
409 << EndElemNL;
411 _outStream << IncIndent;
413 _outStream << BeginElem
414 << "keys"
415 << EndElemNL
416 << BeginElem
417 << "["
418 << EndElemNL;
420 _outStream << IncIndent;
422 std::vector<std::string>::const_iterator kIt =
423 iter->first.begin();
425 std::vector<std::string>::const_iterator kEnd =
426 iter->first.end();
428 for(; kIt != kEnd; ++kIt)
430 _outStream << BeginElem
431 << "\""
432 << *kIt
433 << "\""
434 << EndElemNL;
437 _outStream << DecIndent;
439 _outStream << BeginElem
440 << "]"
441 << EndElemNL;
443 _outStream << BeginElem
444 << "container ";
446 if(iter->second == NULL)
448 _outStream << "NULL"
449 << EndElemNL;
451 else
453 writeContainer(iter->second, false);
454 _outStream << EndElemNL;
457 _outStream << DecIndent;
459 _outStream << BeginElem
460 << "}"
461 << EndElemNL;
464 _outStream << DecIndent;
466 _outStream << BeginElem
467 << "]"
468 << EndElemNL;
471 else if(sfFCPtr != NULL || mfFCPtr != NULL)
473 //this Field points to FC
475 if(hF->getDescription()->isDynamic() == true)
477 _outStream << BeginElem
478 << "field "
479 << hF->getType().getCName()
480 << " "
481 << hF->getName();
483 else
485 _outStream << BeginElem
486 << hF->getName();
489 if(sfFCPtr != NULL && sfFCPtr->isValid() == true)
491 if((*sfFCPtr)->getValue() == NULL)
493 _outStream << " NULL" << EndElemNL;
495 else
497 _outStream << " ";
498 writeContainer((*sfFCPtr)->getValue(), false);
501 else if(mfFCPtr != NULL && mfFCPtr->isValid() == true)
503 _outStream << EndElemNL
504 << BeginElem
505 << "["
506 << EndElemNL;
508 _outStream << IncIndent;
510 SizeT mfSize = (*mfFCPtr)->size();
512 for(SizeT i = 0; i < mfSize; i++)
514 if((*(*mfFCPtr))[i] == NULL)
516 _outStream << BeginElem
517 << "NULL"
518 << EndElemNL;
520 else
522 writeContainer((*(*mfFCPtr))[i], true);
526 _outStream << DecIndent;
528 _outStream << BeginElem
529 << "]"
530 << EndElemNL;
533 else
535 //this Field contains data -> write it out
537 if(hF->getDescription()->isDynamic() == true)
539 _outStream << BeginElem
540 << "field "
541 << hF->getType().getCName()
542 << " "
543 << hF->getName();
545 else
547 _outStream << BeginElem << hF->getName();
550 //to access the content of a field via a Field*
551 //one must know the cardinality
552 if(hF->getCardinality() == FieldType::SingleField)
554 _outStream << " ";
556 hF->pushValueToStream(_outStream);
558 _outStream << EndElemNL;
560 else if(hF->getCardinality() == FieldType::MultiField)
562 _outStream << " #";
564 hF->pushSizeToStream(_outStream);
566 _outStream << EndElemNL
567 << BeginElem
568 << "["
569 << EndElemNL;
571 _outStream << IncIndent;
573 #ifdef WFC
574 hF->pushValueToStream(_outStream);
576 _outStream << EndElemNL;
577 #endif
580 _outStream << DecIndent;
582 _outStream << BeginElem
583 << "]"
584 << EndElemNL;