root/OpenSceneGraph/trunk/src/osgDB/OutputStream.cpp @ 13041

Revision 13041, 24.9 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13// Written by Wang Rui, (C) 2010
14
15#include <osg/Version>
16#include <osg/Notify>
17#include <osgDB/FileUtils>
18#include <osgDB/WriteFile>
19#include <osgDB/ObjectWrapper>
20#include <fstream>
21#include <sstream>
22
23using namespace osgDB;
24
25OutputStream::OutputStream( const osgDB::Options* options )
26:   _writeImageHint(WRITE_USE_IMAGE_HINT), _useSchemaData(false)
27{
28    if ( !options ) return;
29    _options = options;
30
31    if ( options->getPluginStringData("SchemaData")=="true" )
32        _useSchemaData = true;
33    if ( !options->getPluginStringData("SchemaFile").empty() )
34        _schemaName = options->getPluginStringData("SchemaFile");
35    if ( !options->getPluginStringData("Compressor").empty() )
36        _compressorName = options->getPluginStringData("Compressor");
37    if ( !options->getPluginStringData("WriteImageHint").empty() )
38    {
39        std::string hintString = options->getPluginStringData("WriteImageHint");
40        if ( hintString=="IncludeData" ) _writeImageHint = WRITE_INLINE_DATA;
41        else if ( hintString=="IncludeFile" ) _writeImageHint = WRITE_INLINE_FILE;
42        else if ( hintString=="UseExternal" ) _writeImageHint = WRITE_USE_EXTERNAL;
43        else if ( hintString=="WriteOut" ) _writeImageHint = WRITE_EXTERNAL_FILE;
44    }
45}
46
47OutputStream::~OutputStream()
48{
49}
50
51OutputStream& OutputStream::operator<<( const osg::Vec2b& v )
52{ *this << v.x() << v.y(); return *this; }
53
54OutputStream& OutputStream::operator<<( const osg::Vec3b& v )
55{ *this << v.x() << v.y() << v.z(); return *this; }
56
57OutputStream& OutputStream::operator<<( const osg::Vec4b& v )
58{ *this << v.x() << v.y() << v.z() << v.w(); return *this; }
59
60OutputStream& OutputStream::operator<<( const osg::Vec4ub& v )
61{ *this << v.r() << v.g() << v.b() << v.a(); return *this; }
62
63OutputStream& OutputStream::operator<<( const osg::Vec2s& v )
64{ *this << v.x() << v.y(); return *this; }
65
66OutputStream& OutputStream::operator<<( const osg::Vec3s& v )
67{ *this << v.x() << v.y() << v.z(); return *this; }
68
69OutputStream& OutputStream::operator<<( const osg::Vec4s& v )
70{ *this << v.x() << v.y() << v.z() << v.w(); return *this; }
71
72OutputStream& OutputStream::operator<<( const osg::Vec2f& v )
73{ *this << v.x() << v.y(); return *this; }
74
75OutputStream& OutputStream::operator<<( const osg::Vec3f& v )
76{ *this << v.x() << v.y() << v.z(); return *this; }
77
78OutputStream& OutputStream::operator<<( const osg::Vec4f& v )
79{ *this << v.x() << v.y() << v.z() << v.w(); return *this; }
80
81OutputStream& OutputStream::operator<<( const osg::Vec2d& v )
82{ *this << v.x() << v.y(); return *this; }
83
84OutputStream& OutputStream::operator<<( const osg::Vec3d& v )
85{ *this << v.x() << v.y() << v.z(); return *this; }
86
87OutputStream& OutputStream::operator<<( const osg::Vec4d& v )
88{ *this << v.x() << v.y() << v.z() << v.w(); return *this; }
89
90OutputStream& OutputStream::operator<<( const osg::Quat& q )
91{ *this << q.x() << q.y() << q.z() << q.w(); return *this; }
92
93OutputStream& OutputStream::operator<<( const osg::Plane& p )
94{ *this << (double)p[0] << (double)p[1] << (double)p[2] << (double)p[3]; return *this; }
95
96
97#if 0
98OutputStream& OutputStream::operator<<( const osg::Matrixf& mat )
99{
100    *this << PROPERTY("Matrixf")<<BEGIN_BRACKET << std::endl;
101    for ( int r=0; r<4; ++r )
102    {
103        *this << mat(r, 0) << mat(r, 1)
104              << mat(r, 2) << mat(r, 3) << std::endl;
105    }
106    *this << END_BRACKET << std::endl;
107    return *this;
108}
109
110OutputStream& OutputStream::operator<<( const osg::Matrixd& mat )
111{
112    *this << PROPERTY("Matrixd")<<BEGIN_BRACKET << std::endl;
113    for ( int r=0; r<4; ++r )
114    {
115        *this << mat(r, 0) << mat(r, 1)
116              << mat(r, 2) << mat(r, 3) << std::endl;
117    }
118    *this << END_BRACKET << std::endl;
119    return *this;
120}
121#else
122OutputStream& OutputStream::operator<<( const osg::Matrixf& mat )
123{
124    *this << BEGIN_BRACKET << std::endl;
125    for ( int r=0; r<4; ++r )
126    {
127        *this << (double)mat(r, 0) << (double)mat(r, 1)
128              << (double)mat(r, 2) << (double)mat(r, 3) << std::endl;
129    }
130    *this << END_BRACKET << std::endl;
131    return *this;
132}
133
134OutputStream& OutputStream::operator<<( const osg::Matrixd& mat )
135{
136    *this << BEGIN_BRACKET << std::endl;
137    for ( int r=0; r<4; ++r )
138    {
139        *this << mat(r, 0) << mat(r, 1)
140              << mat(r, 2) << mat(r, 3) << std::endl;
141    }
142    *this << END_BRACKET << std::endl;
143    return *this;
144}
145#endif
146
147void OutputStream::writeArray( const osg::Array* a )
148{
149    if ( !a ) return;
150
151    bool newID = false;
152    unsigned int id = findOrCreateArrayID( a, newID );
153    *this << PROPERTY("ArrayID") << id;
154    if ( !newID )  // Shared array
155    {
156        *this << std::endl;
157        return;
158    }
159
160    switch ( a->getType() )
161    {
162    case osg::Array::ByteArrayType:
163        *this << MAPPEE(ArrayType, ID_BYTE_ARRAY);
164        writeArrayImplementation( static_cast<const osg::ByteArray*>(a), a->getNumElements(), 4 );
165        break;
166    case osg::Array::UByteArrayType:
167        *this << MAPPEE(ArrayType, ID_UBYTE_ARRAY);
168        writeArrayImplementation( static_cast<const osg::UByteArray*>(a), a->getNumElements(), 4 );
169        break;
170    case osg::Array::ShortArrayType:
171        *this << MAPPEE(ArrayType, ID_SHORT_ARRAY);
172        writeArrayImplementation( static_cast<const osg::ShortArray*>(a), a->getNumElements(), 4 );
173        break;
174    case osg::Array::UShortArrayType:
175        *this << MAPPEE(ArrayType, ID_USHORT_ARRAY);
176        writeArrayImplementation( static_cast<const osg::UShortArray*>(a), a->getNumElements(), 4 );
177        break;
178    case osg::Array::IntArrayType:
179        *this << MAPPEE(ArrayType, ID_INT_ARRAY);
180        writeArrayImplementation( static_cast<const osg::IntArray*>(a), a->getNumElements(), 4 );
181        break;
182    case osg::Array::UIntArrayType:
183        *this << MAPPEE(ArrayType, ID_UINT_ARRAY);
184        writeArrayImplementation( static_cast<const osg::UIntArray*>(a), a->getNumElements(), 4 );
185        break;
186    case osg::Array::FloatArrayType:
187        *this << MAPPEE(ArrayType, ID_FLOAT_ARRAY);
188        writeArrayImplementation( static_cast<const osg::FloatArray*>(a), a->getNumElements(), 4 );
189        break;
190    case osg::Array::DoubleArrayType:
191        *this << MAPPEE(ArrayType, ID_DOUBLE_ARRAY);
192        writeArrayImplementation( static_cast<const osg::DoubleArray*>(a), a->getNumElements(), 4 );
193        break;
194    case osg::Array::Vec2bArrayType:
195        *this << MAPPEE(ArrayType, ID_VEC2B_ARRAY);
196        writeArrayImplementation( static_cast<const osg::Vec2bArray*>(a), a->getNumElements() );
197        break;
198    case osg::Array::Vec3bArrayType:
199        *this << MAPPEE(ArrayType, ID_VEC3B_ARRAY);
200        writeArrayImplementation( static_cast<const osg::Vec3bArray*>(a), a->getNumElements() );
201        break;
202    case osg::Array::Vec4bArrayType:
203        *this << MAPPEE(ArrayType, ID_VEC4B_ARRAY);
204        writeArrayImplementation( static_cast<const osg::Vec4bArray*>(a), a->getNumElements() );
205        break;
206    case osg::Array::Vec4ubArrayType:
207        *this << MAPPEE(ArrayType, ID_VEC4UB_ARRAY);
208        writeArrayImplementation( static_cast<const osg::Vec4ubArray*>(a), a->getNumElements() );
209        break;
210    case osg::Array::Vec2sArrayType:
211        *this << MAPPEE(ArrayType, ID_VEC2S_ARRAY);
212        writeArrayImplementation( static_cast<const osg::Vec2sArray*>(a), a->getNumElements() );
213        break;
214    case osg::Array::Vec3sArrayType:
215        *this << MAPPEE(ArrayType, ID_VEC3S_ARRAY);
216        writeArrayImplementation( static_cast<const osg::Vec3sArray*>(a), a->getNumElements() );
217        break;
218    case osg::Array::Vec4sArrayType:
219        *this << MAPPEE(ArrayType, ID_VEC4S_ARRAY);
220        writeArrayImplementation( static_cast<const osg::Vec4sArray*>(a), a->getNumElements() );
221        break;
222    case osg::Array::Vec2ArrayType:
223        *this << MAPPEE(ArrayType, ID_VEC2_ARRAY);
224        writeArrayImplementation( static_cast<const osg::Vec2Array*>(a), a->getNumElements() );
225        break;
226    case osg::Array::Vec3ArrayType:
227        *this << MAPPEE(ArrayType, ID_VEC3_ARRAY);
228        writeArrayImplementation( static_cast<const osg::Vec3Array*>(a), a->getNumElements() );
229        break;
230    case osg::Array::Vec4ArrayType:
231        *this << MAPPEE(ArrayType, ID_VEC4_ARRAY);
232        writeArrayImplementation( static_cast<const osg::Vec4Array*>(a), a->getNumElements() );
233        break;
234    case osg::Array::Vec2dArrayType:
235        *this << MAPPEE(ArrayType, ID_VEC2D_ARRAY);
236        writeArrayImplementation( static_cast<const osg::Vec2dArray*>(a), a->getNumElements() );
237        break;
238    case osg::Array::Vec3dArrayType:
239        *this << MAPPEE(ArrayType, ID_VEC3D_ARRAY);
240        writeArrayImplementation( static_cast<const osg::Vec3dArray*>(a), a->getNumElements() );
241        break;
242    case osg::Array::Vec4dArrayType:
243        *this << MAPPEE(ArrayType, ID_VEC4D_ARRAY);
244        writeArrayImplementation( static_cast<const osg::Vec4dArray*>(a), a->getNumElements() );
245        break;
246    default:
247        throwException( "OutputStream::writeArray(): Unsupported array type." );
248    }
249}
250
251void OutputStream::writePrimitiveSet( const osg::PrimitiveSet* p )
252{
253    if ( !p ) return;
254
255    switch ( p->getType() )
256    {
257    case osg::PrimitiveSet::DrawArraysPrimitiveType:
258        *this << MAPPEE(PrimitiveType, ID_DRAWARRAYS);
259        {
260            const osg::DrawArrays* da = static_cast<const osg::DrawArrays*>(p);
261            *this << MAPPEE(PrimitiveType, da->getMode())
262                  << da->getFirst() << da->getCount() << std::endl;
263        }
264        break;
265    case osg::PrimitiveSet::DrawArrayLengthsPrimitiveType:
266        *this << MAPPEE(PrimitiveType, ID_DRAWARRAY_LENGTH);
267        {
268            const osg::DrawArrayLengths* dl = static_cast<const osg::DrawArrayLengths*>(p);
269            *this << MAPPEE(PrimitiveType, dl->getMode()) << dl->getFirst();
270            writeArrayImplementation( dl, dl->size(), 4 );
271        }
272        break;
273    case osg::PrimitiveSet::DrawElementsUBytePrimitiveType:
274        *this << MAPPEE(PrimitiveType, ID_DRAWELEMENTS_UBYTE);
275        {
276            const osg::DrawElementsUByte* de = static_cast<const osg::DrawElementsUByte*>(p);
277            *this << MAPPEE(PrimitiveType, de->getMode());
278            writeArrayImplementation( de, de->size(), 4 );
279        }
280        break;
281    case osg::PrimitiveSet::DrawElementsUShortPrimitiveType:
282        *this << MAPPEE(PrimitiveType, ID_DRAWELEMENTS_USHORT);
283        {
284            const osg::DrawElementsUShort* de = static_cast<const osg::DrawElementsUShort*>(p);
285            *this << MAPPEE(PrimitiveType, de->getMode());
286            writeArrayImplementation( de, de->size(), 4 );
287        }
288        break;
289    case osg::PrimitiveSet::DrawElementsUIntPrimitiveType:
290        *this << MAPPEE(PrimitiveType, ID_DRAWELEMENTS_UINT);
291        {
292            const osg::DrawElementsUInt* de = static_cast<const osg::DrawElementsUInt*>(p);
293            *this << MAPPEE(PrimitiveType, de->getMode());
294            writeArrayImplementation( de, de->size(), 4 );
295        }
296        break;
297    default:
298        throwException( "OutputStream::writePrimitiveSet(): Unsupported primitive type." );
299    }
300}
301
302void OutputStream::writeImage( const osg::Image* img )
303{
304    if ( !img ) return;
305
306    // std::string name = img->libraryName();
307    // name += std::string("::") + img->className();
308
309    bool newID = false;
310    unsigned int id = findOrCreateObjectID( img, newID );
311
312    // *this << name << BEGIN_BRACKET << std::endl;       // Write object name
313    *this << PROPERTY("UniqueID") << id << std::endl;  // Write image ID
314    if ( getException() ) return;
315
316    if (newID)
317    {
318        int decision = IMAGE_EXTERNAL;
319        switch ( _writeImageHint )
320        {
321        case OutputStream::WRITE_INLINE_DATA: decision = IMAGE_INLINE_DATA; break;
322        case OutputStream::WRITE_INLINE_FILE: decision = IMAGE_INLINE_FILE; break;
323        case OutputStream::WRITE_EXTERNAL_FILE: decision = IMAGE_WRITE_OUT; break;
324        case OutputStream::WRITE_USE_EXTERNAL: decision = IMAGE_EXTERNAL; break;
325        default:
326            if ( img->getWriteHint()==osg::Image::EXTERNAL_FILE )
327                decision = IMAGE_EXTERNAL;
328            else if ( isBinary() )
329                decision = IMAGE_INLINE_DATA;
330            break;
331        }
332
333
334        std::string imageFileName = img->getFileName();
335        if ( decision==IMAGE_WRITE_OUT || _writeImageHint==WRITE_EXTERNAL_FILE )
336        {
337            if (imageFileName.empty())
338            {
339                OSG_NOTICE<<"Empty Image::FileName resetting to image.dds"<<std::endl;
340                imageFileName = "image.dds";
341            }
342
343            bool result = osgDB::writeImageFile( *img, imageFileName );
344            OSG_NOTICE << "OutputStream::writeImage(): Write image data to external file " << imageFileName << std::endl;
345            if ( !result )
346            {
347                OSG_WARN << "OutputStream::writeImage(): Failed to write " << img->getFileName() << std::endl;
348            }
349        }
350
351        *this << PROPERTY("FileName"); writeWrappedString(imageFileName); *this << std::endl;
352        *this << PROPERTY("WriteHint") << (int)img->getWriteHint();
353        if ( getException() ) return;
354
355        *this << decision << std::endl;
356
357        switch ( decision )
358        {
359        case IMAGE_INLINE_DATA:
360            if ( isBinary() )
361            {
362                *this << img->getOrigin();  // _origin
363                *this << img->s() << img->t() << img->r(); // _s & _t & _r
364                *this << img->getInternalTextureFormat();  // _internalTextureFormat
365                *this << img->getPixelFormat();  // _pixelFormat
366                *this << img->getDataType();  // _dataType
367                *this << img->getPacking();  // _packing
368                *this << img->getAllocationMode();  // _allocationMode
369
370                // _data
371                unsigned int size = img->getTotalSizeInBytesIncludingMipmaps();
372                writeSize(size);
373
374                for(osg::Image::DataIterator img_itr(img); img_itr.valid(); ++img_itr)
375                {
376                    writeCharArray( (char*)img_itr.data(), img_itr.size() );
377                }
378
379                // _mipmapData
380                unsigned int numMipmaps = img->getNumMipmapLevels()-1;
381                writeSize(numMipmaps);
382                int s = img->s();
383                int t = img->t();
384                int r = img->r();
385                unsigned int offset = 0;
386                for (unsigned int i=0; i<numMipmaps; ++i)
387                {
388                    unsigned int size = osg::Image::computeImageSizeInBytes(s,t,r,img->getPixelFormat(),img->getDataType(),img->getPacking());
389                    offset += size;
390
391                    *this << offset;
392
393                    s >>= 1;
394                    t >>= 1;
395                    r >>= 1;
396                    if (s<1) s=1;
397                    if (t<1) t=1;
398                    if (r<1) r=1;
399                }
400            }
401            break;
402        case IMAGE_INLINE_FILE:
403            if ( isBinary() )
404            {
405                std::string fullPath = osgDB::findDataFile( img->getFileName() );
406                std::ifstream infile( fullPath.c_str(), std::ios::in|std::ios::binary );
407                if ( infile )
408                {
409                    infile.seekg( 0, std::ios::end );
410                    unsigned int size = infile.tellg();
411                    writeSize(size);
412
413                    if ( size>0 )
414                    {
415                        char* data = new char[size];
416                        if ( !data )
417                        {
418                            throwException( "OutputStream::writeImage(): Out of memory." );
419                            if ( getException() ) return;
420                        }
421
422                        infile.seekg( 0, std::ios::beg );
423                        infile.read( data, size );
424                        writeCharArray( data, size );
425                        delete[] data;
426                    }
427                    infile.close();
428                }
429                else
430                {
431                    OSG_WARN << "OutputStream::writeImage(): Failed to open image file "
432                                        << img->getFileName() << std::endl;
433                    *this << (unsigned int)0;
434                }
435            }
436            break;
437        case IMAGE_EXTERNAL:
438            break;
439        default:
440            break;
441        }
442
443        writeObjectFields( img );
444    }
445
446    // *this << END_BRACKET << std::endl;
447}
448
449void OutputStream::writeObject( const osg::Object* obj )
450{
451    if ( !obj ) return;
452
453    std::string name = obj->libraryName();
454    name += std::string("::") + obj->className();
455
456    bool newID = false;
457    unsigned int id = findOrCreateObjectID( obj, newID );
458
459    *this << name << BEGIN_BRACKET << std::endl;       // Write object name
460    *this << PROPERTY("UniqueID") << id << std::endl;  // Write object ID
461    if ( getException() ) return;
462
463    if (newID)
464    {
465        writeObjectFields(obj);
466    }
467
468    *this << END_BRACKET << std::endl;
469}
470
471void OutputStream::writeObjectFields( const osg::Object* obj )
472{
473    std::string name = obj->libraryName();
474    name += std::string("::") + obj->className();
475
476    ObjectWrapper* wrapper = Registry::instance()->getObjectWrapperManager()->findWrapper( name );
477    if ( !wrapper )
478    {
479        OSG_WARN << "OutputStream::writeObject(): Unsupported wrapper class "
480                                << name << std::endl;
481        return;
482    }
483    _fields.push_back( name );
484
485    const StringList& associates = wrapper->getAssociates();
486    for ( StringList::const_iterator itr=associates.begin(); itr!=associates.end(); ++itr )
487    {
488        const std::string& assocName = *itr;
489        ObjectWrapper* assocWrapper = Registry::instance()->getObjectWrapperManager()->findWrapper(assocName);
490        if ( !assocWrapper )
491        {
492            OSG_WARN << "OutputStream::writeObject(): Unsupported associated class "
493                                    << assocName << std::endl;
494            continue;
495        }
496        else if ( _useSchemaData )
497        {
498            if ( _inbuiltSchemaMap.find(assocName)==_inbuiltSchemaMap.end() )
499            {
500                StringList properties;
501                std::vector<int> types;
502                assocWrapper->writeSchema( properties, types );
503
504                unsigned int size = osg::minimum( properties.size(), types.size() );
505                if ( size>0 )
506                {
507                    std::stringstream propertiesStream;
508                    for ( unsigned int i=0; i<size; ++i )
509                    {
510                        propertiesStream << properties[i] << ":" << types[i] << " ";
511                    }
512                    _inbuiltSchemaMap[assocName] = propertiesStream.str();
513                }
514            }
515        }
516        _fields.push_back( assocWrapper->getName() );
517
518        assocWrapper->write( *this, *obj );
519        if ( getException() ) return;
520
521        _fields.pop_back();
522    }
523    _fields.pop_back();
524
525}
526
527void OutputStream::start( OutputIterator* outIterator, OutputStream::WriteType type )
528{
529    _fields.clear();
530    _fields.push_back( "Start" );
531
532    _out = outIterator;
533    if ( !_out )
534        throwException( "OutputStream: Null stream specified." );
535    if ( getException() ) return;
536
537    if ( isBinary() )
538    {
539        *this << (unsigned int)type << (unsigned int)OPENSCENEGRAPH_SOVERSION;
540
541        bool useCompressSource = false;
542        unsigned int attributes = 0;
543
544        if ( _useSchemaData )
545        {
546            attributes |= 0x2;  // Record if we use inbuilt schema data or not
547            useCompressSource = true;
548        }
549        *this << attributes;
550
551        if ( !_compressorName.empty() )
552        {
553            BaseCompressor* compressor = Registry::instance()->getObjectWrapperManager()->findCompressor(_compressorName);
554            if ( !compressor )
555            {
556                OSG_WARN << "OutputStream::start(): No such compressor "
557                                       << _compressorName << std::endl;
558                _compressorName.clear();
559            }
560            else
561            {
562                useCompressSource = true;
563            }
564        }
565        if ( !_compressorName.empty() ) *this << _compressorName;
566        else *this << std::string("0");  // No compressor
567
568        // Compressors and inbuilt schema use a new stream, which will be merged with the original one at the end.
569        if ( useCompressSource )
570        {
571            _out->flush();
572            _out->setStream( &_compressSource );
573        }
574    }
575    else
576    {
577        std::string typeString("Unknown");
578        switch ( type )
579        {
580        case WRITE_SCENE: typeString = "Scene"; break;
581        case WRITE_IMAGE: typeString = "Image"; break;
582        case WRITE_OBJECT: typeString = "Object"; break;
583        default: break;
584        }
585
586        *this << typeString << std::endl;
587        *this << PROPERTY("#Version") << (unsigned int)OPENSCENEGRAPH_SOVERSION << std::endl;
588        *this << PROPERTY("#Generator") << std::string("OpenSceneGraph")
589              << std::string(osgGetVersion()) << std::endl;
590        *this << std::endl;
591    }
592    _fields.pop_back();
593}
594
595void OutputStream::compress( std::ostream* ostream )
596{
597    _fields.clear();
598    if ( !isBinary() ) return;
599
600    std::stringstream schemaSource;
601    if ( _useSchemaData )
602    {
603        _fields.push_back( "SchemaData" );
604
605        std::string schemaData;
606        for ( std::map<std::string, std::string>::iterator itr=_inbuiltSchemaMap.begin();
607              itr!=_inbuiltSchemaMap.end(); ++itr )
608        {
609            schemaData += itr->first + '=';
610            schemaData += itr->second;
611            schemaData += '\n';
612        }
613
614        int size = schemaData.size();
615        schemaSource.write( (char*)&size, INT_SIZE );
616        schemaSource.write( schemaData.c_str(), size );
617
618        _inbuiltSchemaMap.clear();
619        _fields.pop_back();
620    }
621
622    if ( !_compressorName.empty() )
623    {
624        _fields.push_back( "Compression" );
625        BaseCompressor* compressor = Registry::instance()->getObjectWrapperManager()->findCompressor(_compressorName);
626        if ( !compressor || !ostream )
627        {
628            _fields.pop_back();
629            return;
630        }
631
632        if ( !compressor->compress(*ostream, schemaSource.str() + _compressSource.str()) )
633            throwException( "OutputStream: Failed to compress stream." );
634        if ( getException() ) return;
635        _fields.pop_back();
636    }
637    else if ( _useSchemaData )
638    {
639        std::string str = schemaSource.str() + _compressSource.str();
640        ostream->write( str.c_str(), str.size() );
641    }
642}
643
644void OutputStream::writeSchema( std::ostream& fout )
645{
646    // Write to external ascii stream
647    const ObjectWrapperManager::WrapperMap& wrappers = Registry::instance()->getObjectWrapperManager()->getWrapperMap();
648    for ( ObjectWrapperManager::WrapperMap::const_iterator itr=wrappers.begin();
649          itr!=wrappers.end(); ++itr )
650    {
651        ObjectWrapper* wrapper = itr->second.get();
652        fout << itr->first << " =";
653
654        StringList properties;
655        std::vector<int> types;
656        wrapper->writeSchema( properties, types );
657
658        std::string propertiesString;
659        unsigned int size = osg::minimum( properties.size(), types.size() );
660        for ( unsigned int i=0; i<size; ++i )
661        {
662            fout << " " << properties[i] << ":" << types[i];
663        }
664        fout << std::endl;
665    }
666}
667
668// PROTECTED METHODS
669
670template<typename T>
671void OutputStream::writeArrayImplementation( const T* a, int write_size, unsigned int numInRow )
672{
673    *this << write_size << BEGIN_BRACKET;
674    if ( numInRow>1 )
675    {
676        for ( int i=0; i<write_size; ++i )
677        {
678            if ( !(i%numInRow) )
679            {
680                *this << std::endl << (*a)[i];
681            }
682            else
683                *this << (*a)[i];
684        }
685        *this << std::endl;
686    }
687    else
688    {
689        *this << std::endl;
690        for ( int i=0; i<write_size; ++i )
691            *this << (*a)[i] << std::endl;
692    }
693    *this << END_BRACKET << std::endl;
694}
695
696unsigned int OutputStream::findOrCreateArrayID( const osg::Array* array, bool& newID )
697{
698    ArrayMap::iterator itr = _arrayMap.find( array );
699    if ( itr==_arrayMap.end() )
700    {
701        unsigned int id = _arrayMap.size()+1;
702        _arrayMap[array] = id;
703        newID = true;
704        return id;
705    }
706    newID = false;
707    return itr->second;
708}
709
710unsigned int OutputStream::findOrCreateObjectID( const osg::Object* obj, bool& newID )
711{
712    ObjectMap::iterator itr = _objectMap.find( obj );
713    if ( itr==_objectMap.end() )
714    {
715        unsigned int id = _objectMap.size()+1;
716        _objectMap[obj] = id;
717        newID = true;
718        return id;
719    }
720    newID = false;
721    return itr->second;
722}
Note: See TracBrowser for help on using the browser.