root/OpenSceneGraph/trunk/src/osgPlugins/ive/DataInputStream.cpp @ 13557

Revision 13557, 58.7 kB (checked in by robert, 18 hours ago)

Added VolumeSettings::Filename property.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/**********************************************************************
2 *
3 *    FILE:            DataInputStream.cpp
4 *
5 *    DESCRIPTION:    Implements methods to read simple datatypes from an
6 *                    input stream.
7 *
8 *    CREATED BY:        Rune Schmidt Jensen
9 *
10 *    HISTORY:        Created 11.03.2003
11 *                    Updated for texture1D by Don Burns, 27.1.2004
12 *                      Updated for light model - Stan Blinov at 25 august 7512 from World Creation (7.09.2004)
13 *
14 *
15 *    Copyright 2003 VR-C
16 **********************************************************************/
17
18#include "DataInputStream.h"
19#include "StateSet.h"
20#include "AlphaFunc.h"
21#include "BlendColor.h"
22#include "Stencil.h"
23#include "StencilTwoSided.h"
24#include "BlendFunc.h"
25#include "BlendEquation.h"
26#include "Depth.h"
27#include "Material.h"
28#include "CullFace.h"
29#include "ColorMask.h"
30#include "ClipPlane.h"
31#include "PolygonOffset.h"
32#include "PolygonMode.h"
33#include "ShadeModel.h"
34#include "Point.h"
35#include "LineWidth.h"
36#include "LineStipple.h"
37#include "Texture1D.h"
38#include "Texture2D.h"
39#include "Texture2DArray.h"
40#include "Texture3D.h"
41#include "TextureCubeMap.h"
42#include "TextureRectangle.h"
43#include "TexEnv.h"
44#include "TexEnvCombine.h"
45#include "TexGen.h"
46#include "TexMat.h"
47#include "FragmentProgram.h"
48#include "VertexProgram.h"
49#include "LightModel.h"
50#include "ProxyNode.h"
51#include "FrontFace.h"
52#include "Program.h"
53#include "Viewport.h"
54#include "Scissor.h"
55#include "Image.h"
56#include "ImageSequence.h"
57#include "PointSprite.h"
58#include "Multisample.h"
59#include "Fog.h"
60#include "Light.h"
61#include "PolygonStipple.h"
62
63#include "Node.h"
64#include "Group.h"
65#include "MatrixTransform.h"
66#include "Camera.h"
67#include "CameraView.h"
68#include "Geode.h"
69#include "LightSource.h"
70#include "TexGenNode.h"
71#include "ClipNode.h"
72#include "Billboard.h"
73#include "Sequence.h"
74#include "LOD.h"
75#include "PagedLOD.h"
76#include "PositionAttitudeTransform.h"
77#include "AutoTransform.h"
78#include "DOFTransform.h"
79#include "Transform.h"
80#include "Switch.h"
81#include "OccluderNode.h"
82#include "OcclusionQueryNode.h"
83#include "Impostor.h"
84#include "CoordinateSystemNode.h"
85#include "Uniform.h"
86#include "Shader.h"
87
88#include "LightPointNode.h"
89#include "MultiSwitch.h"
90#include "VisibilityGroup.h"
91
92#include "MultiTextureControl.h"
93#include "ShapeAttributeList.h"
94#include "Effect.h"
95#include "AnisotropicLighting.h"
96#include "BumpMapping.h"
97#include "Cartoon.h"
98#include "Scribe.h"
99#include "SpecularHighlights.h"
100
101#include "Volume.h"
102#include "VolumeTile.h"
103#include "VolumeImageLayer.h"
104#include "VolumeCompositeLayer.h"
105#include "VolumeLocator.h"
106#include "VolumeCompositeProperty.h"
107#include "VolumeSwitchProperty.h"
108#include "VolumeScalarProperty.h"
109#include "VolumeTransferFunctionProperty.h"
110
111#include "Geometry.h"
112#include "ShapeDrawable.h"
113#include "Shape.h"
114
115#include "Text.h"
116
117#include "Terrain.h"
118#include "TerrainTile.h"
119#include "Locator.h"
120#include "ImageLayer.h"
121#include "HeightFieldLayer.h"
122#include "CompositeLayer.h"
123#include "SwitchLayer.h"
124
125#include "FadeText.h"
126#include "Text3D.h"
127
128#include <osg/Endian>
129#include <osg/Notify>
130#include <osg/io_utils>
131#include <osgDB/ReadFile>
132#include <osgDB/FileNameUtils>
133
134#include <stdio.h>
135#include <sstream>
136
137using namespace ive;
138using namespace std;
139
140DataInputStream::DataInputStream(std::istream* istream, const osgDB::ReaderWriter::Options* options)
141{
142    unsigned int endianType ;
143
144    _loadExternalReferenceFiles = false;
145
146    _verboseOutput = false;
147
148    _istream = istream;
149    _owns_istream = false;
150    _peeking = false;
151    _peekValue = 0;
152    _byteswap = 0;
153
154    _options = options;
155
156    if (_options.get())
157    {
158        setLoadExternalReferenceFiles(_options->getOptionString().find("noLoadExternalReferenceFiles")==std::string::npos);
159        OSG_DEBUG << "ive::DataInputStream.setLoadExternalReferenceFiles()=" << getLoadExternalReferenceFiles() << std::endl;
160    }
161
162    if(!istream){
163        throwException("DataInputStream::DataInputStream(): null pointer exception in argument.");
164    }
165
166    endianType = readUInt() ;
167
168    if ( endianType != ENDIAN_TYPE) {
169      // Make sure the file is simply swapped
170      if ( endianType != OPPOSITE_ENDIAN_TYPE ) {
171         throwException("DataInputStream::DataInputStream(): This file has an unreadable endian type.") ;
172      }
173      OSG_INFO<<"DataInputStream::DataInputStream: Reading a byteswapped file" << std::endl ;
174      _byteswap = 1 ;
175   }
176
177    _version = readUInt();
178
179    // Are we trying to open a binary .ive file which version are newer than this library.
180    if(_version>VERSION){
181        throwException("DataInputStream::DataInputStream(): The version found in the file is newer than this library can handle.");
182    }
183
184    if (_version>=VERSION_0033)
185    {
186        int compressionLevel = readInt();
187
188        if (compressionLevel>0)
189        {
190            OSG_INFO<<"compressed ive stream"<<std::endl;
191
192            unsigned int maxSize = readUInt();
193
194            std::string data;
195            data.reserve(maxSize);
196
197            if (!uncompress(*istream, data))
198            {
199                throwException("Error in uncompressing .ive");
200                return;
201            }
202
203            _istream = new std::stringstream(data);
204            _owns_istream = true;
205        }
206        else
207        {
208            OSG_INFO<<"uncompressed ive stream"<<std::endl;
209        }
210    }
211}
212
213DataInputStream::~DataInputStream()
214{
215    if (_owns_istream) delete _istream;
216}
217
218#ifdef USE_ZLIB
219
220#include <zlib.h>
221
222bool DataInputStream::uncompress(std::istream& fin, std::string& destination) const
223{
224    //#define CHUNK 16384
225    #define CHUNK 32768
226
227    int ret;
228    unsigned have;
229    z_stream strm;
230    unsigned char in[CHUNK];
231    unsigned char out[CHUNK];
232
233    /* allocate inflate state */
234    strm.zalloc = Z_NULL;
235    strm.zfree = Z_NULL;
236    strm.opaque = Z_NULL;
237    strm.avail_in = 0;
238    strm.next_in = Z_NULL;
239    ret = inflateInit2(&strm,
240                       15 + 32 // autodected zlib or gzip header
241                       );
242    if (ret != Z_OK)
243    {
244        OSG_INFO<<"failed to init"<<std::endl;
245        return ret != 0;
246    }
247
248    /* decompress until deflate stream ends or end of file */
249    do {
250        //strm.avail_in = fin.readsome((char*)in, CHUNK);
251        fin.read((char *)in, CHUNK);
252        strm.avail_in = fin.gcount();
253
254        if (strm.avail_in == 0)
255        {
256            break;
257        }
258        strm.next_in = in;
259
260        /* run inflate() on input until output buffer not full */
261        do {
262            strm.avail_out = CHUNK;
263            strm.next_out = out;
264            ret = inflate(&strm, Z_NO_FLUSH);
265
266            switch (ret) {
267            case Z_NEED_DICT:
268            case Z_DATA_ERROR:
269            case Z_MEM_ERROR:
270                (void)inflateEnd(&strm);
271                return false;
272            }
273            have = CHUNK - strm.avail_out;
274
275            destination.append((char*)out, have);
276
277        } while (strm.avail_out == 0);
278
279        /* done when inflate() says it's done */
280    } while (ret != Z_STREAM_END);
281
282    /* clean up and return */
283    (void)inflateEnd(&strm);
284
285    return ret == Z_STREAM_END ? true : false;
286}
287#else
288bool DataInputStream::uncompress(std::istream& fin, std::string& destination) const
289{
290    return false;
291}
292#endif
293
294bool DataInputStream::readBool(){
295    char c;
296    _istream->read(&c, CHARSIZE);
297
298    if (_istream->rdstate() & _istream->failbit)
299        throwException("DataInputStream::readBool(): Failed to read boolean value.");
300
301    if (_verboseOutput) std::cout<<"read/writeBool() ["<<(int)c<<"]"<<std::endl;
302
303    return c!=0;
304}
305
306char DataInputStream::readChar(){
307    char c;
308    _istream->read(&c, CHARSIZE);
309
310    if (_istream->rdstate() & _istream->failbit)
311        throwException("DataInputStream::readChar(): Failed to read char value.");
312
313    if (_verboseOutput) std::cout<<"read/writeChar() ["<<(int)c<<"]"<<std::endl;
314
315    return c;
316}
317
318unsigned char DataInputStream::readUChar(){
319    unsigned char c;
320    _istream->read((char*)&c, CHARSIZE);
321
322    if (_istream->rdstate() & _istream->failbit)
323        throwException("DataInputStream::readUChar(): Failed to read unsigned char value.");
324
325    if (_verboseOutput) std::cout<<"read/writeUChar() ["<<(int)c<<"]"<<std::endl;
326
327    return c;
328}
329
330unsigned short DataInputStream::readUShort(){
331    unsigned short s;
332    _istream->read((char*)&s, SHORTSIZE);
333    if (_istream->rdstate() & _istream->failbit)
334        throwException("DataInputStream::readUShort(): Failed to read unsigned short value.");
335
336    if (_verboseOutput) std::cout<<"read/writeUShort() ["<<s<<"]"<<std::endl;
337
338    if (_byteswap) osg::swapBytes((char *)&s,SHORTSIZE);
339
340    return s;
341}
342
343unsigned int DataInputStream::readUInt(){
344    unsigned int s;
345    _istream->read((char*)&s, INTSIZE);
346
347    if (_istream->rdstate() & _istream->failbit)
348        throwException("DataInputStream::readUInt(): Failed to read unsigned int value.");
349
350    if (_byteswap) osg::swapBytes((char *)&s,INTSIZE) ;
351
352    if (_verboseOutput) std::cout<<"read/writeUInt() ["<<s<<"]"<<std::endl;
353
354    return s;
355}
356
357int DataInputStream::readInt(){
358    if(_peeking){
359        _peeking = false;
360        return _peekValue;
361    }
362    int i;
363    _istream->read((char*)&i, INTSIZE);
364
365    // comment out for time being as this check seems to eroneously cause a
366    // premature exit when reading .ive files under OSX!#?:!
367    // Robet Osfield, September 12th 2003.
368    // if (_istream->rdstate() & _istream->failbit)
369    //    throwException("DataInputStream::readInt(): Failed to read int value.");
370
371
372    if (_byteswap) osg::swapBytes((char *)&i,INTSIZE) ;
373
374    if (_verboseOutput) std::cout<<"read/writeInt() ["<<i<<"]"<<std::endl;
375
376    return i;
377}
378
379/**
380 * Read an integer from the stream, but
381 * save it such that the next readInt call will
382 * return the same integer.
383 */
384int DataInputStream::peekInt(){
385    if(_peeking){
386        return _peekValue;
387    }
388    _peekValue  = readInt();
389    _peeking = true;
390    return _peekValue;
391}
392
393float DataInputStream::readFloat(){
394    float f;
395    _istream->read((char*)&f, FLOATSIZE);
396    if (_istream->rdstate() & _istream->failbit)
397        throwException("DataInputStream::readFloat(): Failed to read float value.");
398
399    if (_byteswap) osg::swapBytes((char *)&f,FLOATSIZE) ;
400
401    if (_verboseOutput) std::cout<<"read/writeFloat() ["<<f<<"]"<<std::endl;
402    return f;
403}
404
405long DataInputStream::readLong(){
406    long l;
407    _istream->read((char*)&l, LONGSIZE);
408    if (_istream->rdstate() & _istream->failbit)
409        throwException("DataInputStream::readLong(): Failed to read long value.");
410
411    if (_byteswap) osg::swapBytes((char *)&l,LONGSIZE) ;
412
413    if (_verboseOutput) std::cout<<"read/writeLong() ["<<l<<"]"<<std::endl;
414    return l;
415}
416
417unsigned long DataInputStream::readULong(){
418    unsigned long l;
419    _istream->read((char*)&l, LONGSIZE);
420    if (_istream->rdstate() & _istream->failbit)
421        throwException("DataInputStream::readULong(): Failed to read unsigned long value.");
422
423    if (_byteswap) osg::swapBytes((char *)&l,LONGSIZE) ;
424
425    if (_verboseOutput) std::cout<<"read/writeULong() ["<<l<<"]"<<std::endl;
426
427    return l;
428}
429
430double DataInputStream::readDouble()
431{
432    double d;
433    _istream->read((char*)&d, DOUBLESIZE);
434    if (_istream->rdstate() & _istream->failbit)
435        throwException("DataInputStream::readDouble(): Failed to read double value.");
436
437    if (_byteswap) osg::swapBytes((char *)&d,DOUBLESIZE) ;
438    if (_verboseOutput) std::cout<<"read/writeDouble() ["<<d<<"]"<<std::endl;
439    return d;
440}
441
442std::string DataInputStream::readString()
443{
444    std::string s;
445    int size = readInt();
446    if (size != 0)
447    {
448        s.resize(size);
449        _istream->read((char*)s.c_str(), size);
450        //if (_istream->rdstate() & _istream->failbit)
451        //   throwException("DataInputStream::readString(): Failed to read string value.");
452
453        if (_verboseOutput) std::cout<<"read/writeString() ["<<s<<"]"<<std::endl;
454    }
455
456    return s;
457}
458
459void DataInputStream::readCharArray(char* data, int size)
460{
461    _istream->read(data, size);
462    if (_istream->rdstate() & _istream->failbit)
463        throwException("DataInputStream::readCharArray(): Failed to read char value.");
464
465    if (_verboseOutput) std::cout<<"read/writeCharArray() ["<<data<<"]"<<std::endl;
466}
467
468osg::Vec2 DataInputStream::readVec2()
469{
470    osg::Vec2 v;
471    v.x()=readFloat();
472    v.y()=readFloat();
473
474    if (_verboseOutput) std::cout<<"read/writeVec2() ["<<v<<"]"<<std::endl;
475
476    return v;
477}
478
479osg::Vec3 DataInputStream::readVec3(){
480    osg::Vec3 v;
481    v.x()=readFloat();
482    v.y()=readFloat();
483    v.z()=readFloat();
484
485    if (_verboseOutput) std::cout<<"read/writeVec3() ["<<v<<"]"<<std::endl;
486
487    return v;
488}
489
490osg::Vec4 DataInputStream::readVec4(){
491    osg::Vec4 v;
492    v.x()=readFloat();
493    v.y()=readFloat();
494    v.z()=readFloat();
495    v.w()=readFloat();
496
497    if (_verboseOutput) std::cout<<"read/writeVec4() ["<<v<<"]"<<std::endl;
498
499    return v;
500}
501osg::Vec2d DataInputStream::readVec2d()
502{
503    osg::Vec2d v;
504    v.x()=readDouble();
505    v.y()=readDouble();
506
507    if (_verboseOutput) std::cout<<"read/writeVec2d() ["<<v<<"]"<<std::endl;
508
509    return v;
510}
511
512osg::Vec3d DataInputStream::readVec3d(){
513    osg::Vec3d v;
514    v.x()=readDouble();
515    v.y()=readDouble();
516    v.z()=readDouble();
517
518    if (_verboseOutput) std::cout<<"read/writeVec3d() ["<<v<<"]"<<std::endl;
519
520    return v;
521}
522
523osg::Vec4d DataInputStream::readVec4d(){
524    osg::Vec4d v;
525    v.x()=readDouble();
526    v.y()=readDouble();
527    v.z()=readDouble();
528    v.w()=readDouble();
529
530    if (_verboseOutput) std::cout<<"read/writeVec4d() ["<<v<<"]"<<std::endl;
531
532    return v;
533}
534
535osg::Plane DataInputStream::readPlane(){
536    osg::Plane v;
537
538    if (getVersion() <= VERSION_0018)
539    {
540        v[0]=readFloat();
541        v[1]=readFloat();
542        v[2]=readFloat();
543        v[3]=readFloat();
544    }
545    else
546    {
547        // assume double for planes even if Plane::value_type is float
548        // to ensure that the .ive format does vary.
549        v[0]=readDouble();
550        v[1]=readDouble();
551        v[2]=readDouble();
552        v[3]=readDouble();
553    }
554
555    if (_verboseOutput) std::cout<<"read/writePlane() ["<<v<<"]"<<std::endl;
556
557    return v;
558}
559
560osg::Vec4ub DataInputStream::readVec4ub(){
561    osg::Vec4ub v;
562    v.r()=readChar();
563    v.g()=readChar();
564    v.b()=readChar();
565    v.a()=readChar();
566
567    if (_verboseOutput) std::cout<<"read/writeVec4ub() ["<<v<<"]"<<std::endl;
568
569    return v;
570}
571
572osg::Quat DataInputStream::readQuat(){
573    osg::Quat q;
574    q.x()=readFloat();
575    q.y()=readFloat();
576    q.z()=readFloat();
577    q.w()=readFloat();
578
579    if (_verboseOutput) std::cout<<"read/writeQuat() ["<<q<<"]"<<std::endl;
580
581    return q;
582}
583
584
585
586
587deprecated_osg::Geometry::AttributeBinding DataInputStream::readBinding(){
588    char c = readChar();
589
590    if (_verboseOutput) std::cout<<"readBinding() ["<<(int)c<<"]"<<std::endl;
591
592    switch((int)c){
593        case 0:    return deprecated_osg::Geometry::BIND_OFF;
594        case 1: return deprecated_osg::Geometry::BIND_OVERALL;
595        case 2: return deprecated_osg::Geometry::BIND_PER_PRIMITIVE;
596        case 3: return deprecated_osg::Geometry::BIND_PER_PRIMITIVE_SET;
597        case 4: return deprecated_osg::Geometry::BIND_PER_VERTEX;
598        default:
599            throwException("Unknown binding type in DataInputStream::readBinding()");
600            return deprecated_osg::Geometry::BIND_OFF;
601    }
602}
603
604osg::Array* DataInputStream::readArray(){
605    char c = readChar();
606    switch((int)c){
607        case 0: return readIntArray();
608        case 1: return readUByteArray();
609        case 2: return readUShortArray();
610        case 3: return readUIntArray();
611        case 4: return readVec4ubArray();
612        case 5: return readFloatArray();
613        case 6:    return readVec2Array();
614        case 7:    return readVec3Array();
615        case 8:    return readVec4Array();
616        case 9:    return readVec2sArray();
617        case 10:   return readVec3sArray();
618        case 11:   return readVec4sArray();
619        case 12:   return readVec2bArray();
620        case 13:   return readVec3bArray();
621        case 14:   return readVec4bArray();
622        case 15:   return readVec2dArray();
623        case 16:   return readVec3dArray();
624        case 17:   return readVec4dArray();
625        default:
626            throwException("Unknown array type in DataInputStream::readArray()");
627            return 0;
628    }
629}
630
631osg::IntArray* DataInputStream::readIntArray()
632{
633    int size = readInt();
634    if (size == 0)
635        return NULL;
636
637    osg::ref_ptr<osg::IntArray> a = new osg::IntArray(size);
638
639    _istream->read((char*)&((*a)[0]), INTSIZE*size);
640
641    if (_istream->rdstate() & _istream->failbit)
642    {
643        throwException("DataInputStream::readIntArray(): Failed to read Int array.");
644        return 0;
645    }
646
647    if (_verboseOutput) std::cout<<"read/writeIntArray() ["<<size<<"]"<<std::endl;
648
649    if (_byteswap) {
650       for (int  i = 0 ; i < size ; i++ ) osg::swapBytes((char *)&((*a)[i]),INTSIZE) ;
651    }
652
653    return a.release();
654}
655
656osg::UByteArray* DataInputStream::readUByteArray()
657{
658    int size = readInt();
659    if (size == 0)
660        return NULL;
661
662    osg::ref_ptr<osg::UByteArray> a = new osg::UByteArray(size);
663
664    _istream->read((char*)&((*a)[0]), CHARSIZE*size);
665
666    if (_istream->rdstate() & _istream->failbit)
667    {
668        throwException("DataInputStream::readUByteArray(): Failed to read UByte array.");
669        return 0;
670    }
671
672    if (_verboseOutput) std::cout<<"read/writeUByteArray() ["<<size<<"]"<<std::endl;
673
674    return a.release();
675}
676
677osg::UShortArray* DataInputStream::readUShortArray()
678{
679    int size = readInt();
680    if (size == 0)
681        return NULL;
682
683    osg::ref_ptr<osg::UShortArray> a = new osg::UShortArray(size);
684
685    _istream->read((char*)&((*a)[0]), SHORTSIZE*size);
686
687    if (_istream->rdstate() & _istream->failbit)
688    {
689        throwException("DataInputStream::readUShortArray(): Failed to read UShort array.");
690        return 0;
691    }
692
693    if (_verboseOutput) std::cout<<"read/writeUShortArray() ["<<size<<"]"<<std::endl;
694
695    if (_byteswap)
696    {
697        for (int i = 0 ; i < size ; i++ )
698            osg::swapBytes((char *)&((*a)[i]),SHORTSIZE) ;
699    }
700    return a.release();
701}
702
703osg::UIntArray* DataInputStream::readUIntArray()
704{
705    int size = readInt();
706    if (size == 0)
707        return NULL;
708
709    osg::ref_ptr<osg::UIntArray> a = new osg::UIntArray(size);
710
711    _istream->read((char*)&((*a)[0]), INTSIZE*size);
712
713    if (_istream->rdstate() & _istream->failbit)
714    {
715        throwException("DataInputStream::readUIntArray(): Failed to read UInt array.");
716        return 0;
717    }
718
719    if (_verboseOutput) std::cout<<"read/writeUIntArray() ["<<size<<"]"<<std::endl;
720
721    if (_byteswap)
722    {
723        for (int i = 0 ; i < size ; i++ )
724            osg::swapBytes((char *)&((*a)[i]),INTSIZE) ;
725    }
726    return a.release();
727}
728
729osg::Vec4ubArray* DataInputStream::readVec4ubArray()
730{
731    int size = readInt();
732    if (size == 0)
733        return NULL;
734
735    osg::ref_ptr<osg::Vec4ubArray> a = new osg::Vec4ubArray(size);
736
737    _istream->read((char*)&((*a)[0]), INTSIZE*size);
738
739    if (_istream->rdstate() & _istream->failbit)
740    {
741        throwException("DataInputStream::readVec4ubArray(): Failed to read Vec4ub array.");
742        return 0;
743    }
744
745    if (_verboseOutput) std::cout<<"read/writeVec4ubArray() ["<<size<<"]"<<std::endl;
746
747    return a.release();
748}
749
750bool DataInputStream::readPackedFloatArray(osg::FloatArray* a)
751{
752    int size = readInt();
753
754    a->resize(size);
755
756    if (size == 0)
757        return true;
758
759    if (readBool())
760    {
761        float value = readFloat();
762
763        for(int i=0; i<size; ++i)
764        {
765            (*a)[i] = value;
766        }
767    }
768    else
769    {
770        int packingSize = readInt();
771
772        if (packingSize==1)
773        {
774            float minValue = readFloat();
775            float maxValue = readFloat();
776
777            float byteMultiplier = 255.0f/(maxValue-minValue);
778            float byteInvMultiplier = 1.0f/byteMultiplier;
779
780            for(int i=0; i<size; ++i)
781            {
782                unsigned char byte_value = readUChar();
783                float value = minValue + float(byte_value)*byteInvMultiplier;
784                (*a)[i] = value;
785            }
786        }
787        else if (packingSize==2)
788        {
789            float minValue = readFloat();
790            float maxValue = readFloat();
791
792            float shortMultiplier = 65535.0f/(maxValue-minValue);
793            float shortInvMultiplier = 1.0f/shortMultiplier;
794
795            for(int i=0; i<size; ++i)
796            {
797                unsigned short short_value = readUShort();
798                float value = minValue + float(short_value)*shortInvMultiplier;
799                (*a)[i] = value;
800            }
801        }
802        else
803        {
804            for(int i=0; i<size; ++i)
805            {
806                (*a)[i] = readFloat();
807            }
808        }
809    }
810
811    if (_istream->rdstate() & _istream->failbit)
812    {
813        throwException("DataInputStream::readFloatArray(): Failed to read float array.");
814        return false;
815    }
816
817    if (_verboseOutput) std::cout<<"read/writeFloatArray() ["<<size<<"]"<<std::endl;
818
819    return true;
820}
821
822
823osg::FloatArray* DataInputStream::readFloatArray()
824{
825    int size = readInt();
826    if (size == 0)
827        return NULL;
828
829    osg::ref_ptr<osg::FloatArray> a = new osg::FloatArray(size);
830
831    _istream->read((char*)&((*a)[0]), FLOATSIZE*size);
832
833    if (_istream->rdstate() & _istream->failbit)
834    {
835        throwException("DataInputStream::readFloatArray(): Failed to read float array.");
836        return 0;
837    }
838
839    if (_verboseOutput) std::cout<<"read/writeFloatArray() ["<<size<<"]"<<std::endl;
840
841    if (_byteswap)
842    {
843        for (int i = 0 ; i < size ; i++ )
844            osg::swapBytes((char *)&((*a)[i]),FLOATSIZE) ;
845    }
846    return a.release();
847}
848
849osg::Vec2Array* DataInputStream::readVec2Array()
850{
851    int size = readInt();
852    if (size == 0)
853        return NULL;
854
855    osg::ref_ptr<osg::Vec2Array> a = new osg::Vec2Array(size);
856
857    _istream->read((char*)&((*a)[0]), FLOATSIZE*2*size);
858
859    if (_istream->rdstate() & _istream->failbit)
860    {
861        throwException("DataInputStream::readVec2Array(): Failed to read Vec2 array.");
862        return 0;
863    }
864
865    if (_verboseOutput) std::cout<<"read/writeVec2Array() ["<<size<<"]"<<std::endl;
866
867    if (_byteswap)
868    {
869       float *ptr = (float*)&((*a)[0]) ;
870       for (int i = 0 ; i < size*2 ; i++ )
871       {
872          osg::swapBytes((char *)&(ptr[i]), FLOATSIZE) ;
873       }
874    }
875    return a.release();
876}
877
878osg::Vec3Array* DataInputStream::readVec3Array()
879{
880    int size = readInt();
881    if (size == 0)
882        return NULL;
883
884    osg::ref_ptr<osg::Vec3Array> a = new osg::Vec3Array(size);
885
886    _istream->read((char*)&((*a)[0]), FLOATSIZE*3*size);
887
888    if (_istream->rdstate() & _istream->failbit)
889    {
890        throwException("DataInputStream::readVec3Array(): Failed to read Vec3 array.");
891        return 0;
892    }
893
894    if (_verboseOutput) std::cout<<"read/writeVec3Array() ["<<size<<"]"<<std::endl;
895
896
897    if (_byteswap)
898    {
899       float *ptr = (float*)&((*a)[0]) ;
900       for (int i = 0 ; i < size*3 ; i++ )
901       {
902          osg::swapBytes((char *)&(ptr[i]),FLOATSIZE) ;
903       }
904    }
905    return a.release();
906}
907
908osg::Vec4Array* DataInputStream::readVec4Array(){
909    int size = readInt();
910    if (size == 0)
911        return NULL;
912
913    osg::ref_ptr<osg::Vec4Array> a = new osg::Vec4Array(size);
914
915    _istream->read((char*)&((*a)[0]), FLOATSIZE*4*size);
916
917    if (_istream->rdstate() & _istream->failbit)
918    {
919        throwException("DataInputStream::readVec4Array(): Failed to read Vec4 array.");
920        return 0;
921    }
922
923    if (_verboseOutput) std::cout<<"read/writeVec4Array() ["<<size<<"]"<<std::endl;
924
925    if (_byteswap) {
926       float *ptr = (float*)&((*a)[0]) ;
927       for (int i = 0 ; i < size*4 ; i++ ) {
928          osg::swapBytes((char *)&(ptr[i]),FLOATSIZE) ;
929       }
930    }
931    return a.release();
932}
933
934osg::Vec2bArray* DataInputStream::readVec2bArray()
935{
936    int size = readInt();
937    if (size == 0)
938        return NULL;
939
940    osg::ref_ptr<osg::Vec2bArray> a = new osg::Vec2bArray(size);
941
942    _istream->read((char*)&((*a)[0]), CHARSIZE * 2 * size);
943
944    if (_istream->rdstate() & _istream->failbit)
945    {
946        throwException("DataInputStream::readVec2bArray(): Failed to read Vec2b array.");
947        return 0;
948    }
949
950    if (_verboseOutput) std::cout<<"read/writeVec2bArray() ["<<size<<"]"<<std::endl;
951
952    return a.release();
953}
954
955osg::Vec3bArray* DataInputStream::readVec3bArray()
956{
957    int size = readInt();
958    if (size == 0)
959        return NULL;
960
961    osg::ref_ptr<osg::Vec3bArray> a = new osg::Vec3bArray(size);
962
963    _istream->read((char*)&((*a)[0]), CHARSIZE * 3 * size);
964
965    if (_istream->rdstate() & _istream->failbit)
966    {
967        throwException("DataInputStream::readVec3bArray(): Failed to read Vec3b array.");
968        return 0;
969    }
970
971    if (_verboseOutput) std::cout<<"read/writeVec3bArray() ["<<size<<"]"<<std::endl;
972
973    return a.release();
974}
975
976osg::Vec4bArray* DataInputStream::readVec4bArray()
977{
978    int size = readInt();
979    if (size == 0)
980        return NULL;
981
982    osg::ref_ptr<osg::Vec4bArray> a = new osg::Vec4bArray(size);
983
984    _istream->read((char*)&((*a)[0]), CHARSIZE * 4 * size);
985
986    if (_istream->rdstate() & _istream->failbit)
987    {
988        throwException("DataInputStream::readVec4bArray(): Failed to read Vec4b array.");
989        return 0;
990    }
991
992    if (_verboseOutput) std::cout<<"read/writeVec4bArray() ["<<size<<"]"<<std::endl;
993
994    return a.release();
995}
996
997osg::Vec2sArray* DataInputStream::readVec2sArray()
998{
999    int size = readInt();
1000    if (size == 0)
1001        return NULL;
1002
1003    osg::ref_ptr<osg::Vec2sArray> a = new osg::Vec2sArray(size);
1004
1005    _istream->read((char*)&((*a)[0]), SHORTSIZE * 2 * size);
1006
1007    if (_istream->rdstate() & _istream->failbit)
1008    {
1009        throwException("DataInputStream::readVec2sArray(): Failed to read Vec2s array.");
1010        return 0;
1011    }
1012
1013    if (_verboseOutput) std::cout<<"read/writeVec2sArray() ["<<size<<"]"<<std::endl;
1014
1015    if (_byteswap)
1016    {
1017       short *ptr = (short*)&((*a)[0]) ;
1018       for (int i = 0 ; i < size*2 ; i++ )
1019       {
1020          osg::swapBytes((char *)&(ptr[i]), SHORTSIZE) ;
1021       }
1022    }
1023
1024    return a.release();
1025}
1026
1027osg::Vec3sArray* DataInputStream::readVec3sArray()
1028{
1029    int size = readInt();
1030    if (size == 0)
1031        return NULL;
1032
1033    osg::ref_ptr<osg::Vec3sArray> a = new osg::Vec3sArray(size);
1034
1035    _istream->read((char*)&((*a)[0]), SHORTSIZE * 3 * size);
1036
1037    if (_istream->rdstate() & _istream->failbit)
1038    {
1039        throwException("DataInputStream::readVec3sArray(): Failed to read Vec3s array.");
1040        return 0;
1041    }
1042
1043    if (_verboseOutput) std::cout<<"read/writeVec3sArray() ["<<size<<"]"<<std::endl;
1044
1045
1046    if (_byteswap)
1047    {
1048       short *ptr = (short*)&((*a)[0]) ;
1049       for (int i = 0 ; i < size*3 ; i++ )
1050       {
1051          osg::swapBytes((char *)&(ptr[i]), SHORTSIZE) ;
1052       }
1053    }
1054
1055    return a.release();
1056}
1057
1058osg::Vec4sArray* DataInputStream::readVec4sArray()
1059{
1060    int size = readInt();
1061    if (size == 0)
1062        return NULL;
1063
1064    osg::ref_ptr<osg::Vec4sArray> a = new osg::Vec4sArray(size);
1065
1066    _istream->read((char*)&((*a)[0]), SHORTSIZE * 4 * size);
1067
1068    if (_istream->rdstate() & _istream->failbit)
1069    {
1070        throwException("DataInputStream::readVec4sArray(): Failed to read Vec4s array.");
1071        return 0;
1072    }
1073
1074    if (_verboseOutput) std::cout<<"read/writeVec4sArray() ["<<size<<"]"<<std::endl;
1075
1076    if (_byteswap)
1077    {
1078       short *ptr = (short*)&((*a)[0]) ;
1079       for (int i = 0 ; i < size*4 ; i++ )
1080       {
1081          osg::swapBytes((char *)&(ptr[i]), SHORTSIZE) ;
1082       }
1083    }
1084
1085    return a.release();
1086}
1087
1088osg::Vec2dArray* DataInputStream::readVec2dArray()
1089{
1090    int size = readInt();
1091    if (size == 0)
1092        return NULL;
1093
1094    osg::ref_ptr<osg::Vec2dArray> a = new osg::Vec2dArray(size);
1095
1096    _istream->read((char*)&((*a)[0]), DOUBLESIZE*2*size);
1097
1098    if (_istream->rdstate() & _istream->failbit)
1099    {
1100        throwException("DataInputStream::readVec2dArray(): Failed to read Vec2d array.");
1101        return 0;
1102    }
1103
1104    if (_verboseOutput) std::cout<<"read/writeVec2dArray() ["<<size<<"]"<<std::endl;
1105
1106    if (_byteswap)
1107    {
1108       double *ptr = (double*)&((*a)[0]) ;
1109       for (int i = 0 ; i < size*2 ; i++ )
1110       {
1111          osg::swapBytes((char *)&(ptr[i]), DOUBLESIZE) ;
1112       }
1113    }
1114    return a.release();
1115}
1116
1117osg::Vec3dArray* DataInputStream::readVec3dArray()
1118{
1119    int size = readInt();
1120    if (size == 0)
1121        return NULL;
1122
1123    osg::ref_ptr<osg::Vec3dArray> a = new osg::Vec3dArray(size);
1124
1125    _istream->read((char*)&((*a)[0]), DOUBLESIZE*3*size);
1126
1127    if (_istream->rdstate() & _istream->failbit)
1128    {
1129        throwException("DataInputStream::readVec3dArray(): Failed to read Vec3d array.");
1130        return 0;
1131    }
1132
1133    if (_verboseOutput) std::cout<<"read/writeVec3dArray() ["<<size<<"]"<<std::endl;
1134
1135
1136    if (_byteswap)
1137    {
1138       double *ptr = (double*)&((*a)[0]) ;
1139       for (int i = 0 ; i < size*3 ; i++ )
1140       {
1141          osg::swapBytes((char *)&(ptr[i]),DOUBLESIZE) ;
1142       }
1143    }
1144    return a.release();
1145}
1146
1147osg::Vec4dArray* DataInputStream::readVec4dArray(){
1148    int size = readInt();
1149    if (size == 0)
1150        return NULL;
1151
1152    osg::ref_ptr<osg::Vec4dArray> a = new osg::Vec4dArray(size);
1153
1154    _istream->read((char*)&((*a)[0]), DOUBLESIZE*4*size);
1155
1156    if (_istream->rdstate() & _istream->failbit)
1157    {
1158        throwException("DataInputStream::readVec4dArray(): Failed to read Vec4d array.");
1159        return 0;
1160    }
1161
1162    if (_verboseOutput) std::cout<<"read/writeVec4dArray() ["<<size<<"]"<<std::endl;
1163
1164    if (_byteswap) {
1165       double *ptr = (double*)&((*a)[0]) ;
1166       for (int i = 0 ; i < size*4 ; i++ ) {
1167          osg::swapBytes((char *)&(ptr[i]),DOUBLESIZE) ;
1168       }
1169    }
1170    return a.release();
1171}
1172
1173osg::Matrixf DataInputStream::readMatrixf()
1174{
1175    osg::Matrixf mat;
1176    for(int r=0;r<4;r++)
1177    {
1178        for(int c=0;c<4;c++)
1179        {
1180            mat(r,c) = readFloat();
1181        }
1182    }
1183
1184    if (_istream->rdstate() & _istream->failbit)
1185    {
1186        throwException("DataInputStream::readMatrix(): Failed to read Matrix array.");
1187        return osg::Matrixf();
1188    }
1189
1190    if (_verboseOutput) std::cout<<"read/writeMatrix() ["<<mat<<"]"<<std::endl;
1191
1192
1193    return mat;
1194}
1195
1196osg::Matrixd DataInputStream::readMatrixd()
1197{
1198    osg::Matrixd mat;
1199    for(int r=0;r<4;r++)
1200    {
1201        for(int c=0;c<4;c++)
1202        {
1203            mat(r,c) = readDouble();
1204        }
1205    }
1206
1207    if (_istream->rdstate() & _istream->failbit)
1208    {
1209        throwException("DataInputStream::readMatrix(): Failed to read Matrix array.");
1210        return osg::Matrixd();
1211    }
1212
1213    if (_verboseOutput) std::cout<<"read/writeMatrix() ["<<mat<<"]"<<std::endl;
1214
1215
1216    return mat;
1217}
1218
1219osg::Image* DataInputStream::readImage(std::string filename)
1220{
1221    // If image is already read and in list
1222    // then just return pointer to this.
1223    ImageMap::iterator mitr=_imageMap.find(filename);
1224    if (mitr!=_imageMap.end()) return mitr->second.get();
1225
1226    // Image is not in list.
1227    // Read it from disk,
1228    osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile(filename.c_str(),_options.get());
1229
1230    // add it to the imageList,
1231    _imageMap[filename] = image;
1232    // and return image pointer.
1233
1234    if (_verboseOutput) std::cout<<"read/writeImage() ["<<image<<"]"<<std::endl;
1235
1236    return image.release();
1237}
1238
1239osg::Image* DataInputStream::readImage()
1240{
1241    if ( getVersion() >= VERSION_0029 )
1242    {
1243        int id = peekInt();
1244        if(id == IVEIMAGESEQUENCE)
1245        {
1246            osg::ImageSequence* image = new osg::ImageSequence();
1247            ((ive::ImageSequence*)image)->read(this);
1248            return image;
1249        }
1250        else
1251        {
1252            readInt();
1253            IncludeImageMode includeImg = (IncludeImageMode)readChar();
1254            return readImage(includeImg);
1255        }
1256    }
1257    else
1258    {
1259        IncludeImageMode includeImg = (IncludeImageMode)readChar();
1260        return readImage(includeImg);
1261    }
1262}
1263
1264osg::Image* DataInputStream::readImage(IncludeImageMode mode)
1265{
1266    switch(mode) {
1267        case IMAGE_INCLUDE_DATA:
1268            // Read image data from stream
1269            if(readBool())
1270            {
1271                osg::Image* image = new osg::Image();
1272                ((ive::Image*)image)->read(this);
1273                return image;
1274            }
1275            break;
1276        case IMAGE_REFERENCE_FILE:
1277            // Only read image name from stream.
1278            {
1279                std::string filename = readString();
1280                if(!filename.empty()){
1281                    return readImage(filename);
1282                }
1283            }
1284            break;
1285        case IMAGE_INCLUDE_FILE:
1286        case IMAGE_COMPRESS_DATA:
1287            // Read image file from stream
1288            {
1289                std::string filename = readString();
1290                int size = readInt();
1291                if(filename.compare("")!=0 && size > 0){
1292
1293                    //Read in file
1294                    char *buffer = new char[size];
1295                    readCharArray(buffer,size);
1296
1297                    //Get ReaderWriter from file extension
1298                    std::string ext = osgDB::getFileExtension(filename);
1299                    osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension(ext);
1300
1301                    osgDB::ReaderWriter::ReadResult rr;
1302                    if(reader) {
1303                        //Convert data to istream
1304                        std::stringstream inputStream;
1305                        inputStream.write(buffer,size);
1306
1307                        //Attempt to read the image
1308                        rr = reader->readImage(inputStream,_options.get());
1309                    }
1310
1311                    //Delete buffer
1312                    delete [] buffer;
1313
1314                    //Return result
1315                    if(rr.validImage()) {
1316                        return rr.takeImage();
1317                    }
1318                }
1319            }
1320            break;
1321        default:
1322            throwException("DataInputStream::readImage(): Invalid IncludeImageMode value.");
1323            break;
1324    }
1325    return 0;
1326}
1327
1328osg::StateSet* DataInputStream::readStateSet()
1329{
1330    // Read statesets unique ID.
1331    int id = readInt();
1332    // See if stateset is already in the list.
1333    StateSetMap::iterator itr= _statesetMap.find(id);
1334    if (itr!=_statesetMap.end()) return itr->second.get();
1335
1336    // StateSet is not in list.
1337    // Create a new stateset,
1338    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
1339
1340    // read its properties from stream
1341    ((ive::StateSet*)(stateset.get()))->read(this);
1342
1343    // exit early if an exception has been set.
1344    if (getException()) return 0;
1345
1346    // and add it to the stateset map,
1347    _statesetMap[id] = stateset;
1348
1349
1350    if (_verboseOutput) std::cout<<"read/writeStateSet() ["<<id<<"]"<<std::endl;
1351
1352    return stateset.get();
1353}
1354
1355osg::StateAttribute* DataInputStream::readStateAttribute()
1356{
1357    // Read stateattributes unique ID.
1358    int id = readInt();
1359    // See if stateattribute is already in the list.
1360    StateAttributeMap::iterator itr= _stateAttributeMap.find(id);
1361    if (itr!=_stateAttributeMap.end()) return itr->second.get();
1362
1363    // stateattribute is not in list.
1364    // Create a new stateattribute,
1365
1366
1367    osg::ref_ptr<osg::StateAttribute> attribute;
1368    int attributeID = peekInt();
1369    if(attributeID == IVEALPHAFUNC){
1370        attribute = new osg::AlphaFunc();
1371        ((ive::AlphaFunc*)(attribute.get()))->read(this);
1372    }
1373    else if(attributeID == IVEBLENDCOLOR){
1374        attribute = new osg::BlendColor();
1375        ((ive::BlendColor*)(attribute.get()))->read(this);
1376    }
1377    else if(attributeID == IVEBLENDFUNC ||
1378            attributeID == IVEBLENDFUNCSEPARATE){
1379        attribute = new osg::BlendFunc();
1380        ((ive::BlendFunc*)(attribute.get()))->read(this);
1381    }
1382    else if(attributeID == IVEBLENDEQUATION){
1383        attribute = new osg::BlendEquation();
1384        ((ive::BlendEquation*)(attribute.get()))->read(this);
1385    }
1386    else if(attributeID == IVEDEPTH){
1387        attribute = new osg::Depth();
1388        ((ive::Depth*)(attribute.get()))->read(this);
1389    }
1390    else if(attributeID == IVEVIEWPORT){
1391        attribute = new osg::Viewport();
1392        ((ive::Viewport*)(attribute.get()))->read(this);
1393    }
1394    else if(attributeID == IVESCISSOR){
1395        attribute = new osg::Scissor();
1396        ((ive::Scissor*)(attribute.get()))->read(this);
1397    }
1398    else if(attributeID == IVEMATERIAL){
1399        attribute = new osg::Material();
1400        ((ive::Material*)(attribute.get()))->read(this);
1401    }
1402    else if(attributeID == IVECULLFACE){
1403        attribute = new osg::CullFace();
1404        ((ive::CullFace*)(attribute.get()))->read(this);
1405    }
1406    else if(attributeID == IVECOLORMASK){
1407        attribute = new osg::ColorMask();
1408        ((ive::ColorMask*)(attribute.get()))->read(this);
1409    }
1410    else if(attributeID == IVECLIPPLANE){
1411        attribute = new osg::ClipPlane();
1412        ((ive::ClipPlane*)(attribute.get()))->read(this);
1413    }
1414    else if(attributeID == IVEPOLYGONOFFSET){
1415        attribute = new osg::PolygonOffset();
1416        ((ive::PolygonOffset*)(attribute.get()))->read(this);
1417    }
1418    else if(attributeID == IVEPOLYGONMODE){
1419        attribute = new osg::PolygonMode();
1420        ((ive::PolygonMode*)(attribute.get()))->read(this);
1421    }
1422    else if(attributeID == IVESHADEMODEL){
1423        attribute = new osg::ShadeModel();
1424        ((ive::ShadeModel*)(attribute.get()))->read(this);
1425    }
1426    else if(attributeID == IVEPOINT){
1427        attribute = new osg::Point();
1428        ((ive::Point*)(attribute.get()))->read(this);
1429    }
1430    else if(attributeID == IVELINEWIDTH){
1431        attribute = new osg::LineWidth();
1432        ((ive::LineWidth*)(attribute.get()))->read(this);
1433    }
1434    else if(attributeID == IVETEXTURE1D){
1435        attribute = new osg::Texture1D();
1436        ((ive::Texture1D*)(attribute.get()))->read(this);
1437    }
1438    else if(attributeID == IVETEXTURE2D){
1439        attribute = new osg::Texture2D();
1440        ((ive::Texture2D*)(attribute.get()))->read(this);
1441    }
1442    else if(attributeID == IVETEXTURE2DARRAY){
1443        attribute = new osg::Texture2DArray();
1444        ((ive::Texture2DArray*)(attribute.get()))->read(this);
1445    }
1446    else if(attributeID == IVETEXTURE3D){
1447        attribute = new osg::Texture3D();
1448        ((ive::Texture3D*)(attribute.get()))->read(this);
1449    }
1450    else if(attributeID == IVETEXTURECUBEMAP){
1451        attribute = new osg::TextureCubeMap();
1452        ((ive::TextureCubeMap*)(attribute.get()))->read(this);
1453    }
1454    else if(attributeID == IVETEXTURERECTANGLE){
1455        attribute = new osg::TextureRectangle();
1456        ((ive::TextureRectangle*)(attribute.get()))->read(this);
1457    }
1458    else if(attributeID == IVETEXENV){
1459        attribute = new osg::TexEnv();
1460        ((ive::TexEnv*)(attribute.get()))->read(this);
1461    }
1462    else if(attributeID == IVETEXENVCOMBINE){
1463        attribute = new osg::TexEnvCombine();
1464        ((ive::TexEnvCombine*)(attribute.get()))->read(this);
1465    }
1466    else if(attributeID == IVETEXGEN){
1467        attribute = new osg::TexGen();
1468        ((ive::TexGen*)(attribute.get()))->read(this);
1469    }
1470    else if(attributeID == IVETEXMAT){
1471        attribute = new osg::TexMat();
1472        ((ive::TexMat*)(attribute.get()))->read(this);
1473    }
1474    else if(attributeID == IVEFRAGMENTPROGRAM){
1475        attribute = new osg::FragmentProgram();
1476        ((ive::FragmentProgram*)(attribute.get()))->read(this);
1477    }
1478    else if(attributeID == IVEVERTEXPROGRAM){
1479        attribute = new osg::VertexProgram();
1480        ((ive::VertexProgram*)(attribute.get()))->read(this);
1481    }
1482    else if(attributeID == IVELIGHTMODEL){
1483        attribute = new osg::LightModel();
1484        ((ive::LightModel*)(attribute.get()))->read(this);
1485    }
1486    else if(attributeID == IVEFRONTFACE){
1487        attribute = new osg::FrontFace();
1488        ((ive::FrontFace*)(attribute.get()))->read(this);
1489    }
1490    else if(attributeID == IVEPROGRAM){
1491        attribute = new osg::Program();
1492        ((ive::Program*)(attribute.get()))->read(this);
1493    }
1494    else if(attributeID == IVEPOINTSPRITE){
1495        attribute = new osg::PointSprite();
1496        ((ive::PointSprite*)(attribute.get()))->read(this);
1497    }
1498    else if(attributeID == IVEMULTISAMPLE){
1499        attribute = new osg::Multisample();
1500        ((ive::Multisample*)(attribute.get()))->read(this);
1501    }
1502    else if(attributeID == IVELINESTIPPLE){
1503        attribute = new osg::LineStipple();
1504        ((ive::LineStipple*)(attribute.get()))->read(this);
1505    }
1506    else if(attributeID == IVESTENCIL){
1507        attribute = new osg::Stencil();
1508        ((ive::Stencil*)(attribute.get()))->read(this);
1509    }
1510    else if(attributeID == IVESTENCILTWOSIDED){
1511        attribute = new osg::StencilTwoSided();
1512        ((ive::StencilTwoSided*)(attribute.get()))->read(this);
1513    }
1514    else if(attributeID == IVEFOG){
1515        attribute = new osg::Fog();
1516        ((ive::Fog*)(attribute.get()))->read(this);
1517    }
1518    else if(attributeID == IVELIGHT){
1519        attribute = new osg::Light();
1520        ((ive::Light*)(attribute.get()))->read(this);
1521    }
1522    else if(attributeID == IVEPOLYGONSTIPPLE){
1523        attribute = new osg::PolygonStipple();
1524        ((ive::PolygonStipple*)(attribute.get()))->read(this);
1525    }
1526    else{
1527        throwException("Unknown StateAttribute in StateSet::read()");
1528        return 0;
1529    }
1530
1531    // exit early if an exception has been set.
1532    if (getException()) return 0;
1533
1534    // and add it to the stateattribute map,
1535    _stateAttributeMap[id] = attribute;
1536
1537
1538    if (_verboseOutput) std::cout<<"read/writeStateAttribute() ["<<id<<"]"<<std::endl;
1539
1540    return attribute.get();
1541}
1542
1543osg::Uniform* DataInputStream::readUniform()
1544{
1545    // Read uniforms unique ID.
1546    int id = readInt();
1547    // See if uniform is already in the list.
1548    UniformMap::iterator itr= _uniformMap.find(id);
1549    if (itr!=_uniformMap.end()) return itr->second.get();
1550
1551    // Uniform is not in list.
1552    // Create a new uniform,
1553    osg::ref_ptr<osg::Uniform> uniform = new osg::Uniform();
1554
1555    // read its properties from stream
1556    ((ive::Uniform*)(uniform.get()))->read(this);
1557
1558    // exit early if an exception has been set.
1559    if (getException()) return 0;
1560
1561    // and add it to the uniform map,
1562    _uniformMap[id] = uniform;
1563
1564
1565    if (_verboseOutput) std::cout<<"read/writeUniform() ["<<id<<"]"<<std::endl;
1566
1567    return uniform.get();
1568}
1569
1570
1571osg::Shader* DataInputStream::readShader()
1572{
1573    // Read shaders unique ID.
1574    int id = readInt();
1575    // See if shader is already in the list.
1576    ShaderMap::iterator itr= _shaderMap.find(id);
1577    if (itr!=_shaderMap.end()) return itr->second.get();
1578
1579    // Shader is not in list.
1580    // Create a new shader,
1581    osg::ref_ptr<osg::Shader> shader = new osg::Shader();
1582
1583    // read its properties from stream
1584    ((ive::Shader*)(shader.get()))->read(this);
1585
1586    // exit early if an exception has been set.
1587    if (getException()) return 0;
1588
1589    // and add it to the shader map,
1590    _shaderMap[id] = shader;
1591
1592
1593    if (_verboseOutput) std::cout<<"read/writeShader() ["<<id<<"]"<<std::endl;
1594
1595    return shader.get();
1596}
1597
1598osg::Drawable* DataInputStream::readDrawable()
1599{
1600    // Read stateattributes unique ID.
1601    int id = readInt();
1602    // See if stateattribute is already in the list.
1603    DrawableMap::iterator itr= _drawableMap.find(id);
1604    if (itr!=_drawableMap.end()) return itr->second.get();
1605
1606    // stateattribute is not in list.
1607    // Create a new stateattribute,
1608
1609    int drawableTypeID = peekInt();
1610    osg::ref_ptr<osg::Drawable> drawable;
1611    if(drawableTypeID == IVEGEOMETRY)
1612    {
1613        drawable = new osg::Geometry();
1614        ((Geometry*)(drawable.get()))->read(this);
1615    }
1616    else if(drawableTypeID == IVESHAPEDRAWABLE)
1617    {
1618        drawable = new osg::ShapeDrawable();
1619        ((ShapeDrawable*)(drawable.get()))->read(this);
1620    }
1621    else if(drawableTypeID == IVETEXT){
1622        drawable = new osgText::Text();
1623        ((Text*)(drawable.get()))->read(this);
1624    }
1625    else if(drawableTypeID == IVEFADETEXT){
1626        drawable = new osgText::FadeText();
1627        ((FadeText*)(drawable.get()))->read(this);
1628    }
1629    else if(drawableTypeID == IVETEXT3D){
1630        drawable = new osgText::Text3D();
1631        ((Text3D*)(drawable.get()))->read(this);
1632    }
1633    else
1634        throwException("Unknown drawable drawableTypeIDentification in Geode::read()");
1635
1636    // exit early if an exception has been set.
1637    if (getException()) return 0;
1638
1639
1640    // and add it to the stateattribute map,
1641    _drawableMap[id] = drawable;
1642
1643
1644    if (_verboseOutput) std::cout<<"read/writeDrawable() ["<<id<<"]"<<std::endl;
1645
1646    return drawable.get();
1647}
1648
1649osg::Shape* DataInputStream::readShape()
1650{
1651    // Read stateattributes unique ID.
1652    int id = readInt();
1653    // See if stateattribute is already in the list.
1654    ShapeMap::iterator itr= _shapeMap.find(id);
1655    if (itr!=_shapeMap.end()) return itr->second.get();
1656
1657    // stateattribute is not in list.
1658    // Create a new stateattribute,
1659
1660    int shapeTypeID = peekInt();
1661    osg::ref_ptr<osg::Shape> shape;
1662    if(shapeTypeID == IVESPHERE)
1663    {
1664        shape = new osg::Sphere();
1665        ((Sphere*)(shape.get()))->read(this);
1666    }
1667    else if(shapeTypeID == IVEBOX)
1668    {
1669        shape = new osg::Box();
1670        ((Box*)(shape.get()))->read(this);
1671    }
1672    else if(shapeTypeID == IVECONE)
1673    {
1674        shape = new osg::Cone();
1675        ((Cone*)(shape.get()))->read(this);
1676    }
1677    else if(shapeTypeID == IVECYLINDER)
1678    {
1679        shape = new osg::Cylinder();
1680        ((Cylinder*)(shape.get()))->read(this);
1681    }
1682    else if(shapeTypeID == IVECAPSULE)
1683    {
1684        shape = new osg::Capsule();
1685        ((Capsule*)(shape.get()))->read(this);
1686    }
1687    else if(shapeTypeID == IVEHEIGHTFIELD)
1688    {
1689        shape = new osg::HeightField();
1690        ((HeightField*)(shape.get()))->read(this);
1691    }
1692    else
1693        throwException("Unknown shape shapeTypeIDentification in Shape::read()");
1694
1695    // exit early if an exception has been set.
1696    if (getException()) return 0;
1697
1698    // and add it to the stateattribute map,
1699    _shapeMap[id] = shape;
1700
1701
1702    if (_verboseOutput) std::cout<<"read/writeShape() ["<<id<<"]"<<std::endl;
1703
1704    return shape.get();
1705}
1706
1707osg::Node* DataInputStream::readNode()
1708{
1709    // Read node unique ID.
1710    int id = readInt();
1711    // See if node is already in the list.
1712    NodeMap::iterator itr= _nodeMap.find(id);
1713    if (itr!=_nodeMap.end()) return itr->second.get();
1714
1715    // stateattribute is not in list.
1716    // Create a new node,
1717
1718    osg::ref_ptr<osg::Node> node;
1719    int nodeTypeID= peekInt();
1720
1721    if(nodeTypeID== IVEMATRIXTRANSFORM){
1722        node = new osg::MatrixTransform();
1723        ((ive::MatrixTransform*)(node.get()))->read(this);
1724    }
1725    else if(nodeTypeID== IVECAMERA){
1726        node = new osg::Camera();
1727        ((ive::Camera*)(node.get()))->read(this);
1728    }
1729    else if(nodeTypeID== IVECAMERAVIEW){
1730        node = new osg::CameraView();
1731        ((ive::CameraView*)(node.get()))->read(this);
1732    }
1733    else if(nodeTypeID== IVEPOSITIONATTITUDETRANSFORM){
1734        node = new osg::PositionAttitudeTransform();
1735        ((ive::PositionAttitudeTransform*)(node.get()))->read(this);
1736    }
1737    else if(nodeTypeID== IVEAUTOTRANSFORM){
1738        node = new osg::AutoTransform();
1739        ((ive::AutoTransform*)(node.get()))->read(this);
1740    }
1741    else if(nodeTypeID== IVEDOFTRANSFORM){
1742        node = new osgSim::DOFTransform();
1743        ((ive::DOFTransform*)(node.get()))->read(this);
1744    }
1745    else if(nodeTypeID== IVETRANSFORM){
1746        node = new osg::Transform();
1747        ((ive::Transform*)(node.get()))->read(this);
1748    }
1749    else if(nodeTypeID== IVELIGHTSOURCE){
1750        node = new osg::LightSource();
1751        ((ive::LightSource*)(node.get()))->read(this);
1752    }
1753    else if(nodeTypeID== IVETEXGENNODE){
1754        node = new osg::TexGenNode();
1755        ((ive::TexGenNode*)(node.get()))->read(this);
1756    }
1757    else if(nodeTypeID== IVECLIPNODE){
1758        node = new osg::ClipNode();
1759        ((ive::ClipNode*)(node.get()))->read(this);
1760    }
1761    else if(nodeTypeID== IVESEQUENCE){
1762        node = new osg::Sequence();
1763        ((ive::Sequence*)(node.get()))->read(this);
1764    }
1765    else if(nodeTypeID== IVELOD){
1766        node = new osg::LOD();
1767        ((ive::LOD*)(node.get()))->read(this);
1768    }
1769    else if(nodeTypeID== IVEPAGEDLOD){
1770        node = new osg::PagedLOD();
1771        ((ive::PagedLOD*)(node.get()))->read(this);
1772    }
1773    else if(nodeTypeID== IVECOORDINATESYSTEMNODE){
1774        node = new osg::CoordinateSystemNode();
1775        ((ive::CoordinateSystemNode*)(node.get()))->read(this);
1776    }
1777    else if(nodeTypeID== IVESWITCH){
1778        node = new osg::Switch();
1779        ((ive::Switch*)(node.get()))->read(this);
1780    }
1781    else if(nodeTypeID== IVEMULTISWITCH){
1782        node = new osgSim::MultiSwitch();
1783        ((ive::MultiSwitch*)(node.get()))->read(this);
1784    }
1785    else if(nodeTypeID== IVEIMPOSTOR){
1786        node = new osgSim::Impostor();
1787        ((ive::Impostor*)(node.get()))->read(this);
1788    }
1789    else if(nodeTypeID== IVEOCCLUDERNODE){
1790        node = new osg::OccluderNode();
1791        ((ive::OccluderNode*)(node.get()))->read(this);
1792    }
1793    else if(nodeTypeID== IVEOCCLUSIONQUERYNODE){
1794        node = new osg::OcclusionQueryNode();
1795        ((ive::OcclusionQueryNode*)(node.get()))->read(this);
1796    }
1797    else if(nodeTypeID== IVEVISIBILITYGROUP){
1798        node = new osgSim::VisibilityGroup();
1799        ((ive::VisibilityGroup*)(node.get()))->read(this);
1800    }
1801    else if(nodeTypeID== IVEPROXYNODE){
1802        node = new osg::ProxyNode();
1803        ((ive::ProxyNode*)(node.get()))->read(this);
1804    }
1805    else if(nodeTypeID== IVEGROUP){
1806        node = new osg::Group();
1807        ((ive::Group*)(node.get()))->read(this);
1808    }
1809    else if(nodeTypeID== IVEBILLBOARD){
1810        node = new osg::Billboard();
1811        ((ive::Billboard*)(node.get()))->read(this);
1812    }
1813    else if(nodeTypeID== IVEGEODE){
1814        node = new osg::Geode();
1815        ((ive::Geode*)(node.get()))->read(this);
1816    }
1817    else if(nodeTypeID== IVELIGHTPOINTNODE){
1818        node = new osgSim::LightPointNode();
1819        ((ive::LightPointNode*)(node.get()))->read(this);
1820    }
1821    else if(nodeTypeID== IVEMULTITEXTURECONTROL){
1822        node = new osgFX::MultiTextureControl();
1823        ((ive::MultiTextureControl*)(node.get()))->read(this);
1824    }
1825
1826    else if(nodeTypeID== IVEANISOTROPICLIGHTING){
1827        node = new osgFX::AnisotropicLighting();
1828        ((ive::AnisotropicLighting*)(node.get()))->read(this);
1829    }
1830    else if(nodeTypeID== IVEBUMPMAPPING){
1831        node = new osgFX::BumpMapping();
1832        ((ive::BumpMapping*)(node.get()))->read(this);
1833    }
1834    else if(nodeTypeID== IVECARTOON){
1835        node = new osgFX::Cartoon();
1836        ((ive::Cartoon*)(node.get()))->read(this);
1837    }
1838    else if(nodeTypeID== IVESCRIBE){
1839        node = new osgFX::Scribe();
1840        ((ive::Scribe*)(node.get()))->read(this);
1841    }
1842    else if(nodeTypeID== IVESPECULARHIGHLIGHTS){
1843        node = new osgFX::SpecularHighlights();
1844        ((ive::SpecularHighlights*)(node.get()))->read(this);
1845    }
1846    else if(nodeTypeID== IVETERRAINTILE){
1847        node = new osgTerrain::TerrainTile();
1848        ((ive::TerrainTile*)(node.get()))->read(this);
1849    }
1850    else if(nodeTypeID== IVETERRAIN){
1851        node = new osgTerrain::Terrain();
1852        ((ive::Terrain*)(node.get()))->read(this);
1853    }
1854    else if(nodeTypeID== IVEVOLUME){
1855        node = new osgVolume::Volume();
1856        ((ive::Volume*)(node.get()))->read(this);
1857    }
1858    else if(nodeTypeID== IVEVOLUMETILE){
1859        node = new osgVolume::VolumeTile();
1860        ((ive::VolumeTile*)(node.get()))->read(this);
1861    }
1862    else if(nodeTypeID== IVENODE){
1863        node = new osg::Node();
1864        ((ive::Node*)(node.get()))->read(this);
1865    }
1866    else{
1867        throwException("Unknown node identification in DataInputStream::readNode()");
1868    }
1869
1870    // exit early if an exception has been set.
1871    if (getException()) return 0;
1872
1873    // and add it to the node map,
1874    _nodeMap[id] = node;
1875
1876
1877    if (_verboseOutput) std::cout<<"read/writeNode() ["<<id<<"]"<<std::endl;
1878
1879    return node.get();
1880}
1881
1882osgTerrain::Layer* DataInputStream::readLayer()
1883{
1884    // Read node unique ID.
1885    int id = readInt();
1886    if (id<0) return 0;
1887
1888    // See if layer is already in the list.
1889    LayerMap::iterator itr= _layerMap.find(id);
1890    if (itr!=_layerMap.end()) return itr->second.get();
1891
1892    // Layer is not in list.
1893    // Create a new Layer,
1894
1895    osg::ref_ptr<osgTerrain::Layer> layer = 0;
1896    int layerid = peekInt();
1897
1898    if (layerid==IVEHEIGHTFIELDLAYER)
1899    {
1900        layer = new osgTerrain::HeightFieldLayer;
1901        ((ive::HeightFieldLayer*)(layer.get()))->read(this);
1902    }
1903    else if (layerid==IVEIMAGELAYER)
1904    {
1905        layer = new osgTerrain::ImageLayer;
1906        ((ive::ImageLayer*)(layer.get()))->read(this);
1907    }
1908    else if (layerid==IVESWITCHLAYER)
1909    {
1910        layer = new osgTerrain::SwitchLayer;
1911        ((ive::SwitchLayer*)(layer.get()))->read(this);
1912    }
1913    else if (layerid==IVECOMPOSITELAYER)
1914    {
1915        layer = new osgTerrain::CompositeLayer;
1916        ((ive::CompositeLayer*)(layer.get()))->read(this);
1917    }
1918    else if (layerid==IVEPROXYLAYER)
1919    {
1920        std::string filename = readString();
1921        osg::ref_ptr<osg::Object> object = osgDB::readObjectFile(filename+".gdal");
1922        osgTerrain::ProxyLayer* proxyLayer = dynamic_cast<osgTerrain::ProxyLayer*>(object.get());
1923
1924        osg::ref_ptr<osgTerrain::Locator> locator = readLocator();
1925        unsigned int minLevel = readUInt();
1926        unsigned int maxLevel = readUInt();
1927
1928        if (proxyLayer)
1929        {
1930            if (locator.valid()) proxyLayer->setLocator(locator.get());
1931
1932            proxyLayer->setMinLevel(minLevel);
1933            proxyLayer->setMaxLevel(maxLevel);
1934        }
1935
1936        layer = proxyLayer;
1937    }
1938    else{
1939        throwException("Unknown layer identification in DataInputStream::readLayer()");
1940    }
1941
1942    // exit early if an exception has been set.
1943    if (getException()) return 0;
1944
1945    // and add it to the node map,
1946    _layerMap[id] = layer;
1947
1948
1949    if (_verboseOutput) std::cout<<"read/writeLayer() ["<<id<<"]"<<std::endl;
1950
1951    return layer.get();
1952}
1953
1954osgTerrain::Locator* DataInputStream::readLocator()
1955{
1956    // Read locator unique ID.
1957    int id = readInt();
1958    if (id<0) return 0;
1959
1960    // See if stateset is already in the list.
1961    LocatorMap::iterator itr= _locatorMap.find(id);
1962    if (itr!=_locatorMap.end()) return itr->second.get();
1963
1964    // Locator is not in list.
1965    // Create a new locator,
1966    osg::ref_ptr<osgTerrain::Locator> locator = new osgTerrain::Locator();
1967
1968    // read its properties from stream
1969    ((ive::Locator*)(locator.get()))->read(this);
1970
1971    // exit early if an exception has been set.
1972    if (getException()) return 0;
1973
1974    // and add it to the locator map,
1975    _locatorMap[id] = locator;
1976
1977    if (_verboseOutput) std::cout<<"read/writeLocator() ["<<id<<"]"<<std::endl;
1978
1979    return locator.get();
1980}
1981
1982
1983osgVolume::Layer* DataInputStream::readVolumeLayer()
1984{
1985    // Read node unique ID.
1986    int id = readInt();
1987    if (id<0) return 0;
1988
1989    // See if layer is already in the list.
1990    VolumeLayerMap::iterator itr= _volumeLayerMap.find(id);
1991    if (itr!=_volumeLayerMap.end()) return itr->second.get();
1992
1993    // Layer is not in list.
1994    // Create a new Layer,
1995
1996    osg::ref_ptr<osgVolume::Layer> layer = 0;
1997    int layerid = peekInt();
1998
1999    if (layerid==IVEVOLUMEIMAGELAYER)
2000    {
2001        layer = new osgVolume::ImageLayer;
2002        ((ive::VolumeImageLayer*)(layer.get()))->read(this);
2003    }
2004    else if (layerid==IVEVOLUMECOMPOSITELAYER)
2005    {
2006        layer = new osgVolume::CompositeLayer;
2007        ((ive::VolumeCompositeLayer*)(layer.get()))->read(this);
2008    }
2009    else{
2010        throwException("Unknown layer identification in DataInputStream::readLayer()");
2011    }
2012
2013    // exit early if an exception has been set.
2014    if (getException()) return 0;
2015
2016    // and add it to the node map,
2017    _volumeLayerMap[id] = layer;
2018
2019
2020    if (_verboseOutput) std::cout<<"read/writeVolumeLayer() ["<<id<<"]"<<std::endl;
2021
2022    return layer.get();
2023}
2024
2025osgVolume::Locator* DataInputStream::readVolumeLocator()
2026{
2027    // Read locator unique ID.
2028    int id = readInt();
2029    if (id<0) return 0;
2030
2031    // See if stateset is already in the list.
2032    VolumeLocatorMap::iterator itr= _volumeLocatorMap.find(id);
2033    if (itr!=_volumeLocatorMap.end()) return itr->second.get();
2034
2035    // Locator is not in list.
2036    // Create a new locator,
2037    osg::ref_ptr<osgVolume::Locator> locator = new osgVolume::Locator();
2038
2039    // read its properties from stream
2040    ((ive::VolumeLocator*)(locator.get()))->read(this);
2041
2042    // exit early if an exception has been set.
2043    if (getException()) return 0;
2044
2045    // and add it to the locator map,
2046    _volumeLocatorMap[id] = locator;
2047
2048    if (_verboseOutput) std::cout<<"read/writeVolumeLocator() ["<<id<<"]"<<std::endl;
2049
2050    return locator.get();
2051}
2052
2053osgVolume::Property* DataInputStream::readVolumeProperty()
2054{
2055    // Read property unique ID.
2056    int id = readInt();
2057    if (id<0) return 0;
2058
2059    // See if stateset is already in the list.
2060    VolumePropertyMap::iterator itr= _volumePropertyMap.find(id);
2061    if (itr!=_volumePropertyMap.end()) return itr->second.get();
2062
2063    int layerid = peekInt();
2064    osg::ref_ptr<osgVolume::Property> property = 0;
2065
2066    if (layerid==IVEVOLUMECOMPOSITEPROPERTY)
2067    {
2068        property = new osgVolume::CompositeProperty;
2069        ((ive::VolumeCompositeProperty*)(property.get()))->read(this);
2070    }
2071    else if (layerid==IVEVOLUMESWITCHPROPERTY)
2072    {
2073        property = new osgVolume::SwitchProperty;
2074        ((ive::VolumeSwitchProperty*)(property.get()))->read(this);
2075    }
2076    else if (layerid==IVEVOLUMETRANSFERFUNCTIONPROPERTY)
2077    {
2078        property = new osgVolume::TransferFunctionProperty;
2079        ((ive::VolumeTransferFunctionProperty*)(property.get()))->read(this);
2080    }
2081    else if (layerid==IVEVOLUMEMAXIMUMINTENSITYPROPERTY)
2082    {
2083        property = new osgVolume::MaximumIntensityProjectionProperty;
2084        readInt();
2085    }
2086    else if (layerid==IVEVOLUMELIGHTINGPROPERTY)
2087    {
2088        property = new osgVolume::LightingProperty;
2089        readInt();
2090    }
2091    else if (layerid==IVEVOLUMEISOSURFACEPROPERTY)
2092    {
2093        property = new osgVolume::IsoSurfaceProperty;
2094        readInt();
2095        ((ive::VolumeScalarProperty*)(property.get()))->read(this);
2096    }
2097    else if (layerid==IVEVOLUMEALPHAFUNCPROPERTY)
2098    {
2099        property = new osgVolume::AlphaFuncProperty;
2100        readInt();
2101        ((ive::VolumeScalarProperty*)(property.get()))->read(this);
2102    }
2103    else if (layerid==IVEVOLUMESAMPLEDENSITYPROPERTY)
2104    {
2105        property = new osgVolume::SampleDensityProperty;
2106        readInt();
2107        ((ive::VolumeScalarProperty*)(property.get()))->read(this);
2108    }
2109    else if (layerid==IVEVOLUMETRANSPARENCYPROPERTY)
2110    {
2111        property = new osgVolume::TransparencyProperty;
2112        readInt();
2113        ((ive::VolumeScalarProperty*)(property.get()))->read(this);
2114    }
2115    else{
2116        throwException("Unknown layer identification in DataInputStream::readVolumeProperty()");
2117    }
2118
2119    // exit early if an exception has been set.
2120    if (getException()) return 0;
2121
2122    // and add it to the locator map,
2123    _volumePropertyMap[id] = property;
2124
2125    if (_verboseOutput) std::cout<<"read/writeVolumeProperty() ["<<id<<"]"<<std::endl;
2126
2127    return property.get();
2128}
2129
2130osg::Object* DataInputStream::readObject()
2131{
2132    int id = readInt();
2133    if (id<0) return 0;
2134
2135    if (id==IVENODE)
2136    {
2137        return readNode();
2138    }
2139    else if (id==IVESTATESET)
2140    {
2141        return readStateSet();
2142    }
2143    else if (id==IVESTATEATTRIBUTE)
2144    {
2145        return readStateAttribute();
2146    }
2147    else if (id==IVEDRAWABLE)
2148    {
2149        return readDrawable();
2150    }
2151    else if (id==IVESHAPEATTRIBUTELIST)
2152    {
2153        osg::ref_ptr<osgSim::ShapeAttributeList> sal = new osgSim::ShapeAttributeList;
2154        ((ive::ShapeAttributeList*)sal.get())->read(this);
2155
2156        // exit early if an exception has been set.
2157        if (getException()) return 0;
2158
2159        return sal.release();
2160    }
2161
2162    return 0;
2163}
2164
Note: See TracBrowser for help on using the browser.