]> git.saurik.com Git - wxWidgets.git/blame - utils/framelayout/src/objstore.cpp
1 - Moved settingsdlg.[h,cpp] and wxinfo.[h,cpp] to demo where they belong
[wxWidgets.git] / utils / framelayout / src / objstore.cpp
CommitLineData
bd9396d5
HH
1/////////////////////////////////////////////////////////////////////////////
2// Name: No names yet.
3// Purpose: Contrib. demo
4// Author: Aleksandras Gluchovas
5// Modified by:
6// Created: 26/10/98
7// RCS-ID: $Id$
8// Copyright: (c) Aleksandras Gluchovas
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "objstore.h"
14// #pragma interface
15#endif
16
17// For compilers that support precompilation, includes "wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
21#pragma hdrstop
22#endif
23
24#ifndef WX_PRECOMP
25#include "wx/wx.h"
26#endif
27
28#include <fstream.h>
29#include "objstore.h"
30#include <string.h>
31
32// FIXME::
33// BUG?:: somehow assertion statements with oritinal wxASSERT do not get compiled in
34
35//#undef wxASSERT
36//#define wxASSERT(x) if ( !(x) ) throw;
37
38/***** Implementation for class wxSerializerInfo *****/
39
40bool wxSerializerInfo::alreadyInitialized = FALSE;
41wxSerializerInfo *wxSerializerInfo::first = NULL;
42wxHashTable wxSerializerInfo::serInfoHash;
43
44wxSerializerInfo::wxSerializerInfo( char* theClassName,
45 wxObjectSerializationFn serializationFun,
46 wxObjectInitializationFn initializationFun,
47 char* classVersionName
48 )
49 : classInfo ( NULL ),
50 next ( NULL ),
51 nextByVersion( NULL ),
52 className ( theClassName ),
53 serFn ( serializationFun ),
54 initFn ( initializationFun ),
55 classVersion ( classVersionName )
56{
57 next = first;
58
59 first = this;
60}
61
62int serializer_ver_cmp_fun( const void* arg1, const void* arg2 )
63{
64 // "no-version" is considered being the highest version
65
66 if ( ((wxSerializerInfo*)arg1)->classVersion == NO_CLASS_VER )
67 {
68 // DBG:: two serializers for the same version of the class should not be present!
69 wxASSERT( ((wxSerializerInfo*)arg1)->classVersion != NO_CLASS_VER );
70
71 return -1; // (inverted already)
72 }
73
74 if ( ((wxSerializerInfo*)arg2)->classVersion == NO_CLASS_VER )
75 {
76 // DBG:: two serializers for the same version of the class should not be present!
77 wxASSERT( ((wxSerializerInfo*)arg1)->classVersion != NO_CLASS_VER );
78
79 return 1; // (inverted already)
80 }
81
82 // versions are compared lexicographically ignoring the char-case
83
84 wxString v1( ((wxSerializerInfo*)arg1)->classVersion );
85 wxString v2( ((wxSerializerInfo*)arg2)->classVersion );
86
87 bool result = v1.CompareTo( v2, wxString::ignoreCase );
88
89 // DBG:: two serializers for the same version of the class should not be present!
90 wxASSERT( result == FALSE );
91
92 // invert the sense of "greater than" for storting in decreasing order
93
94 return ( result > 0 ) ? -1 : 1;
95}
96
97void wxSerializerInfo::InitializeSerializers(void)
98{
99 if ( alreadyInitialized ) return;
100
101 alreadyInitialized = TRUE;
102
103 wxSerializerInfo* pCur = first;
104
105 // first resolve references to class information structures
106
107 while( pCur )
108 {
109 pCur->classInfo = wxClassInfo::FindClass( pCur->className );
110
111 wxASSERT( pCur->classInfo ); // DBG:: class info should already be present somewhere!
112
113 // check if serializer for the class is already present,
114
115 wxSerializerInfo* pFound = (wxSerializerInfo*)serInfoHash.Get( (long)pCur->classInfo );
116
117 if ( pFound )
118 {
119 // if present, then it must be serializer for the certain version of that class,
120 // put it at the end of the chain of versioned serializers for that class
121
122 // go to the end of chain
123
124 while( pFound->nextByVersion ) pFound = pFound->nextByVersion;
125
126 // append it
127
128 pFound->nextByVersion = pCur;
129
130 pCur->next = (wxSerializerInfo*)(-1); // label it as member of local chain
131 // of "versioned" serializers
132
133 pCur->nextByVersion = NULL;
134 }
135 else
136 {
137 // otherwise, serializer for the class found for the first time -
138 // hash it
139
140 serInfoHash.Put( (long)pCur->classInfo, (wxObject*)pCur );
141
142 // and include it to the list of serializers for the highest-versions
143 pCur = pCur->next;
144 }
145 }
146
147 // sort chains of "versioned" serializers in the order of decreasing version
148 //
149 // (since, when loading, the newest version of an object
150 // is expected first, rather then the older one)
151
152 wxSerializerInfo* pPrev = NULL;
153 pCur = first;
154
155 while ( pCur )
156 {
157 // chain present?
158
159 if ( pCur->nextByVersion )
160 {
161 // sort it
162
163 wxSerializerInfo* pStart = pCur;
164 wxSerializerInfo* pNext = pCur->next;
165
166 // let wxList do the sorting, we're too lazy :)
167
168 wxList sorted;
169
170 while( pCur )
171 {
172 sorted.Append( (wxObject*) pCur );
173
174 pCur = pCur->nextByVersion;
175 }
176
177 sorted.Sort( serializer_ver_cmp_fun );
178
179 wxNode* pNode = sorted.First();
180
181 while( pNode )
182 {
183 wxSerializerInfo* pInfo = (wxSerializerInfo*)pNode->Data();
184
185 if ( pNode == sorted.First() )
186 {
187 // make node with the highest version, a member of the global
188 // list of serializers
189
190 if ( pPrev ) pPrev->next = pInfo;
191 else first = pInfo;
192
193 pInfo->next = pNext;
194 }
195 else
196 pInfo->next = (wxSerializerInfo*)(-1); // otherwise label it as a member of local
197 // chain of "versioned" serializers
198
199 if ( pNode->Next() )
200 {
201 pInfo->nextByVersion = (wxSerializerInfo*)( pNode->Next()->Data() );
202 }
203 else
204 pInfo->nextByVersion = 0;
205
206 pNode = pNode->Next();
207 }
208
209 } // end of if ( nextByVersion )
210
211 pPrev = pCur;
212 pCur = pCur->next;
213
214 } // end of while(...)
215}
216
217wxSerializerInfo* wxSerializerInfo::FindSerializer( char* className )
218{
219 wxSerializerInfo::InitializeSerializers();
220
221 wxSerializerInfo* pInfo = (wxSerializerInfo*)
222
223 serInfoHash.Get( (long)wxClassInfo::FindClass( className ) );
224
225 return pInfo;
226}
227
228static void invoke_for_inherited( wxObject* pObj, wxClassInfo* pCInfo, wxObjectStorage* pStore, bool invokeSerFn )
229{
230 wxSerializerInfo* pSrzInfo = (wxSerializerInfo*)
231
232 wxSerializerInfo::serInfoHash.Get( (long)wxClassInfo::FindClass( pCInfo->GetClassName() ) );
233
234 if ( pSrzInfo )
235 {
236 // if found, serialize/initialize and don't go "any higher"
237
238 if ( invokeSerFn )
239
240 (*pSrzInfo->serFn) ( pObj, *pStore );
241 else
242 (*pSrzInfo->initFn)( pObj );
243
244 }
245 else
246 {
247 // go up the hierarchy, if no serializer present for the current class
248
249 if ( pCInfo->GetBaseClass1() )
250
251 invoke_for_inherited( pObj, pCInfo->GetBaseClass1(), pStore, invokeSerFn );
252
253 if ( pCInfo->GetBaseClass2() )
254
255 invoke_for_inherited( pObj, pCInfo->GetBaseClass2(), pStore, invokeSerFn );
256 }
257}
258
259void wxSerializerInfo::SerializeInherited( wxObject* pObj, wxObjectStorage& store )
260{
261 // search recursivelly up the hierarchy for serializers of base
262 // classes, and invoke serialization function for the given object
263
264 if ( classInfo->GetBaseClass1() )
265
266 invoke_for_inherited( pObj, classInfo->GetBaseClass1(), &store, TRUE );
267
268 if ( classInfo->GetBaseClass2() )
269
270 invoke_for_inherited( pObj, classInfo->GetBaseClass2(), &store, TRUE );
271}
272
273void wxSerializerInfo::InitializeInherited( wxObject* pObj )
274{
275 // search recursivelly up the hierarchy for serializers of base
276 // classes, and invoke initialization function for the given object
277
278 if ( classInfo->GetBaseClass1() )
279
280 invoke_for_inherited( pObj, classInfo->GetBaseClass1(), NULL, FALSE );
281
282 if ( classInfo->GetBaseClass2() )
283
284 invoke_for_inherited( pObj, classInfo->GetBaseClass2(), NULL, FALSE );
285}
286
287/***** Implementation for class wxDataStreamBase *****/
288
289IMPLEMENT_ABSTRACT_CLASS( wxDataStreamBase, wxObject )
290
291/***** Implementation for class wxObjectStorage *****/
292
293// codes, used as tokens written/read from the stream
294
295enum STORED_OBJ_TYPES
296{
297 SOT_NULL_POINTER = 'N',
298 SOT_POINTER_TO_OBJ = 'P',
299 SOT_INITIAL_REF = 'I',
300 SOT_OBJ_DATA = 'D'
301};
302
303// veraion-encoding in object-name string fromat defaults:
304
305char wxObjectStorage::mVerSepartorCh = '#';
306char wxObjectStorage::mMinorMajorSepartorCh = '-';
307
308IMPLEMENT_DYNAMIC_CLASS( wxObjectStorage, wxObject )
309
310wxObjectStorage::wxObjectStorage()
311 : mpStm ( 0 ),
312 mIsLoading ( TRUE ),
313 mInitialRefsCnt ( 0 ),
314 mFinalizePending( FALSE )
315{}
316
317wxObjectStorage::wxObjectStorage( wxDataStreamBase& stm )
318 : mpStm ( &stm ),
319 mIsLoading ( stm.IsForInput() ),
320 mInitialRefsCnt ( 0 ),
321 mFinalizePending( FALSE )
322{
323 wxSerializerInfo::InitializeSerializers();
324
325 mFinalizePending = TRUE; // stream object was given - store/load is
326 // started
327}
328
329wxObjectStorage::~wxObjectStorage()
330{
331 if ( mFinalizePending )
332
333 Finalize(); // <- do it now, if "user" forgot about it
334}
335
336/*** protected members ***/
337
338void wxObjectStorage::ClearHashesAndLists()
339{
340 mNewObjs.Clear();
341 mSerializersForNewObjs.Clear();
342 mRefHash.Clear();
343}
344
345/*** public members ***/
346
347void wxObjectStorage::SetDataStream( wxDataStreamBase& stm )
348{
349 if ( mFinalizePending )
350
351 Finalize();
352
353 wxSerializerInfo::InitializeSerializers();
354
355 ClearHashesAndLists();
356
357 mpStm = &stm;
358
359 mIsLoading = stm.IsForInput();
360
361 mFinalizePending = TRUE;
362}
363
364void wxObjectStorage::Finalize()
365{
366 wxASSERT( mpStm ); // DBG:: finalize should called be after loading/storing has proceeded
367
368 mFinalizePending = FALSE;
369
370 if ( mIsLoading )
371 {
372 // initializaiton is performed after all objects successfully
373 // loaded, and references among them are established
374
375 wxNode* pObjNode = mNewObjs.First();
376 wxNode* pSrzNode = mSerializersForNewObjs.First();
377
378 while( pObjNode )
379 {
380 wxSerializerInfo* pSrzInfo = (wxSerializerInfo*)(pSrzNode->Data());
381
382 if ( pSrzInfo->HasInitializer() )
383
384 (*pSrzInfo->initFn)( pObjNode->Data() );
385
386 pObjNode = pObjNode->Next();
387 pSrzNode = pSrzNode->Next();
388 }
389 }
390 else
391 // otherwise, nothing's need to be done after storing of objects is proceeded
392 mpStm->Flush();
393}
394
395// storage methods for basic types
396
397void wxObjectStorage::XchgChar( char& chObj )
398{
399 if ( mIsLoading ) mpStm->LoadChar( &chObj );
400 else mpStm->StoreChar( chObj );
401}
402
403void wxObjectStorage::XchgInt( int& intObj )
404{
405 if ( mIsLoading ) mpStm->LoadInt( &intObj );
406 else mpStm->StoreInt( intObj );
407}
408
409void wxObjectStorage::XchgSizeType( size_t& szObj )
410{
411 int i = int(szObj);
412
413 if ( mIsLoading )
414 {
415 mpStm->LoadInt( &i );
416 szObj = (size_t)i;
417 }
418 else
419 mpStm->StoreInt( i );
420}
421
422void wxObjectStorage::XchgLong( long& longObj )
423{
424 if ( mIsLoading ) mpStm->LoadLong( &longObj );
425 else mpStm->StoreLong( longObj );
426}
427
428void wxObjectStorage::XchgBool( bool& boolObj )
429{
430 // bools are stored as ints
431
432 if ( mIsLoading )
433 {
434 int bVal = (int)boolObj;
435 mpStm->LoadInt( &bVal );
436 boolObj = bVal;
437 }
438 else
439 mpStm->StoreInt( (int)boolObj );
440}
441
442void wxObjectStorage::XchgUInt ( unsigned int& uI )
443{
444 if ( mIsLoading )
445 {
446 int uiVal = (int)uI;
447 mpStm->LoadInt( &uiVal );
448 uI = (unsigned int)uiVal;
449 }
450 else
451 mpStm->StoreInt( (int)uI );
452}
453
454void wxObjectStorage::XchgObjList( wxList& objList )
455{
456 int count = 0;
457
458 if ( mIsLoading )
459 {
460 XchgInt( count );
461
462 if ( count == 0 ) return;
463
464 objList.Clear();
465 }
466 else
467 {
468 count = objList.GetCount();
469
470 XchgInt( count );
471 }
472
473 // work-around for assessing operator[] which is protected in wxArrayBase
474
475 if ( mIsLoading )
476
477 for( int i = 0; i != count; ++i )
478 {
479 wxObject* pObj = NULL;
480
481 XchgObjPtr( &pObj );
482
483 objList.Append( pObj );
484 }
485 else
486 {
487 wxNode* pNode = objList.First();
488
489 while( pNode )
490 {
491 wxObject* pObj = pNode->Data();
492
493 XchgObjPtr( &pObj );
494
495 pNode = pNode->Next();
496 }
497 }
498}
499
500void wxObjectStorage::XchgObjArray ( wxBaseArray& objArr )
501{
502 int count = 0;
503
504 if ( mIsLoading )
505 {
506 XchgInt( count );
507
508 if ( count == 0 ) return;
509
510 objArr.Clear();
511 objArr.Alloc( count );
512 }
513 else
514 {
515 count = objArr.GetCount();
516
517 XchgInt( count );
518 }
519
520 // work-around for assessing operator[] which is protected in wxArrayBase
521
522 wxArrayLong& longArr = *( (wxArrayLong*) (&objArr) );
523
524 if ( mIsLoading )
525
526 for( int i = 0; i != count; ++i )
527 {
528 wxObject* pObj = NULL;
529
530 XchgObjPtr( &pObj );
531
532 longArr.Add( (long) pObj );
533 }
534 else
535 for( int i = 0; i != count; ++i )
536 {
537 wxObject* pObj = (wxObject*)longArr[i];
538
539 XchgObjPtr( &pObj );
540 }
541}
542
543void wxObjectStorage::XchgLongArray( wxBaseArray& longArr )
544{
545 int count = 0;
546
547 if ( mIsLoading )
548 {
549 XchgInt( count );
550
551 if ( count == 0 ) return;
552
553 longArr.Clear();
554 longArr.Alloc( count );
555 }
556 else
557 {
558 count = longArr.GetCount();
559
560 XchgInt( count );
561 }
562
563 // work-around for assessing operator[] which is protected in wxArrayBase
564
565 wxArrayLong& realLongArr = *( (wxArrayLong*) (&longArr) );
566
567 if ( mIsLoading )
568
569 for( int i = 0; i != count; ++i )
570 {
571 long l = 0;
572 XchgLong( l );
573
574 realLongArr.Add( l );
575 }
576 else
577 for( int i = 0; i != count; ++i )
578
579 XchgLong( realLongArr[i] );
580}
581
582void wxObjectStorage::XchgDouble( double& doubleObj )
583{
584 if ( mIsLoading ) mpStm->LoadDouble( &doubleObj );
585 else mpStm->StoreDouble( doubleObj );
586}
587
588void wxObjectStorage::XchgCStr( char* pCStrObj )
589{
590 if ( mIsLoading )
591 {
592 int len;
593 mpStm->LoadInt( &len );
594 mpStm->LoadBytes( pCStrObj, len );
595 }
596 else
597 {
598 int len = strlen( pCStrObj ) + 1; // include terminating zero
599 mpStm->StoreInt( len );
600 mpStm->StoreBytes( pCStrObj, len );
601 }
602}
603
604wxSerializerInfo* wxObjectStorage::FindSrzInfoForClass( wxClassInfo* pInfo )
605{
606 wxSerializerInfo* pSrz = (wxSerializerInfo*)
607
608 wxSerializerInfo::serInfoHash.Get( (long)pInfo );
609
610 if ( !pSrz )
611 {
612 // look up recursivelly for serializers for of the base classes
613
614 if ( pInfo->GetBaseClass1() )
615
616 return FindSrzInfoForClass( pInfo->GetBaseClass1() );
617 else
618 if ( pInfo->GetBaseClass2() )
619
620 return FindSrzInfoForClass( pInfo->GetBaseClass2() );
621 else
622 {
623 wxASSERT(0); // DBG:: no serializers present for the given class,
624 // serialization cannot proceed
625 return 0;
626 }
627 }
628 else
629 return pSrz;
630}
631
632bool wxObjectStorage::VersionsMatch( char* v1, char* v2 )
633{
634 while( *v1 && *v2 )
635 {
636 if ( *v1 == mMinorMajorSepartorCh ||
637 *v2 == mMinorMajorSepartorCh )
638
639 // minor versions are ignored
640
641 return TRUE;
642
643 if ( wxToUpper(*v1) != wxToUpper(*v2) )
644
645 return FALSE;
646
647 ++v1; ++v2;
648 }
649
650 return ( *v1 == '\0' && *v2 == '\0' );
651}
652
653bool wxObjectStorage::ExchangeObjectInfo( wxClassInfo** ppCInfo, wxSerializerInfo** ppSrz )
654{
655 char objInfoStr[512]; // FOR NOW:: fixed?
656
657 if ( mIsLoading == FALSE )
658 {
659 strcpy( objInfoStr, (*ppCInfo)->GetClassName() );
660
661 if ( (*ppSrz)->HasVersion() )
662 {
663 char separator[2];
664 separator[2] = mVerSepartorCh;
665 separator[1] = '\0';
666
667 strcat( objInfoStr, separator );
668
669 strcat( objInfoStr, (*ppSrz)->classVersion );
670 }
671
672 XchgCStr( objInfoStr );
673
674 return TRUE;
675 }
676
677 // otherwise if loading...
678
679 XchgCStr( objInfoStr ); // read string
680
681 (*ppCInfo) = NULL;
682 (*ppSrz) = NULL;
683
684 // formal description of objInfoStr format is following (if '#' and '-' are set
685 // as version and minor/major separators):
686 //
687 // object objInfoStr = { class_name_str , [version] }
688 //
689 // version = { '#', simple_version_str | major_and_minor_version_str }
690 //
691 // simple_version_str = any_literal
692 //
693 // major_and_minro_version_str = { major_version_str, '-', minro_version_str }
694 //
695 // major_version_str = any_literal
696 //
697 // inor_version_str = any_literal
698 //
699 // any_literal = "any string not containing '#' and '-' characters"
700 //
701
702 char* cur = objInfoStr;
703
704 while( *cur && *cur != mVerSepartorCh ) ++cur;
705
706 char last = *cur;
707
708 if ( last == mVerSepartorCh )
709
710 *cur = '\0';
711
712 (*ppCInfo) = wxClassInfo::FindClass( objInfoStr );
713
714 if ( !(*ppCInfo) ) return FALSE;
715
716 // get the bigining of the chain of serializers for (*ppCInfo)
717
718 wxSerializerInfo* pSrz = FindSrzInfoForClass( (*ppCInfo ) );
719
720 if ( last == mVerSepartorCh ) *cur = last; // restore from temprary "termination"
721
722 // find serializer which matches the version, or the serializer
723 // with no version, if version is not attached to the objInfoStr
724
725 if ( *cur == '\0' )
726 {
727 // there's no version trailing, the "not-versioned"
728 // serializer can be present only at the begining of
729 // the chain
730
731 if ( pSrz->HasVersion() == FALSE )
732 {
733 (*ppSrz) = pSrz;
734
735 return TRUE;
736 }
737 else
738 return FALSE;
739 }
740
741 ++cur; // skip className<->version separator
742
743 // version present, search for matching serializer down the chain
744
745 if ( pSrz->HasVersion() == FALSE ) pSrz = pSrz->nextByVersion;
746
747 while( pSrz )
748 {
749 if ( VersionsMatch( pSrz->classVersion, cur ) )
750 {
751 (*ppSrz) = pSrz;
752
753 return TRUE;
754 }
755
756 pSrz = pSrz->nextByVersion;
757 }
758
759 return FALSE; // no serializers matching given version found
760}
761
762wxSerializerInfo* wxObjectStorage::GetLatestSrzForObj( wxObject* pWxObj )
763{
764 wxClassInfo* pCInfo = pWxObj->GetClassInfo();
765
766 wxASSERT( pCInfo ); // DBG:: object's class should be dynamic
767
768 // find first serializer for (*pCInfo) in the chain
769
770 wxSerializerInfo* pSrz = FindSrzInfoForClass( pCInfo );
771
772 wxASSERT( pSrz ); // DBG:: there should be at least one serializer of
773 // the object's class, at least for it's base classes
774
775 // skip not-versioned serializer at the beginng of the chain if present
776
777 if ( !pSrz->HasVersion() && pSrz->nextByVersion )
778
779 pSrz = pSrz->nextByVersion; // the reminding ones are "vesioned",
780 // starting from the highest version
781
782 return pSrz;
783}
784
785void wxObjectStorage::DoExchangeObject( wxObject* pInstance, wxSerializerInfo& srzInfo )
786{
787 if ( mIsLoading )
788
789 // put info about already (partially) loaded object (stream-offset <=> object-ptr )
790
791 mRefHash.Put( (long)mpStm->GetStreamPos(), (wxObject*)pInstance );
792 else
793 // put info about already (partially) stored object (object-ptr <=> stream-offset)
794
795 mRefHash.Put( (long)(pInstance), (wxObject*)mpStm->GetStreamPos() );
796
797 if ( mIsLoading )
798 {
799 mNewObjs.Append( pInstance );
800 mSerializersForNewObjs.Append( (wxObject*)&srzInfo );
801 }
802
803 // now, perform actual serialization of the object
804
805 (srzInfo.serFn)( pInstance, *this );
806}
807
808// storage methods for objects and object-references
809
810void wxObjectStorage::XchgObj( wxObject* pWxObj )
811{
812 wxClassInfo* pCInfo = pWxObj->GetClassInfo();
813
814 wxASSERT( pCInfo ); // DBG:: if this fails, the object which is passed to
815 // XchgObj(..) has not it's class information
816 // i.e. is not a wxWindows dynamic class
817
818 wxSerializerInfo* pSrz = ( mIsLoading == FALSE ) ? GetLatestSrzForObj( pWxObj )
819 : NULL;
820
821 bool success = ExchangeObjectInfo( &pCInfo, &pSrz );
822
823 wxASSERT( success ); // DBG:: all info about object should be present i.e. class
824 // info, serializer which matches the object's version
825 // (see source of ExchangeObjectInfo() for more info)
826
827 DoExchangeObject( pWxObj, *pSrz );
828}
829
830void wxObjectStorage::XchgObjPtr( wxObject** ppWxObj )
831{
832 if ( mIsLoading )
833 {
834 char token;
835 mpStm->LoadChar( &token );
836
837 if ( token == (char)SOT_NULL_POINTER )
838
839 (*ppWxObj) = NULL;
840 else
841 if ( token == (char)SOT_POINTER_TO_OBJ )
842 {
843 long ofs; // stream-offset
844
845 mpStm->LoadLong( &ofs );
846
847 wxObject* pObj = (wxObject*) mRefHash.Get( ofs );
848
849 wxASSERT( pObj ); // DBG:: object (at the given stream-offset)
850 // must be already loaded
851
852 (*ppWxObj) = pObj;
853 }
854 else
855 if ( token == (char)SOT_INITIAL_REF )
856 {
857 long refNo;
858
859 mpStm->LoadLong( &refNo );
860
861 wxASSERT( mInitialRefsCnt >= refNo ); // DBG:: inital refernce should be already added
862
863 // refNo is 1-based
864 (*ppWxObj) = mInitialRefs.Nth( refNo-1 )->Data();
865 }
866 else
867 {
868 wxASSERT( token == (char)SOT_OBJ_DATA );// DBG:: other types of tokens are
869 // bogous! If this happens you're
870 // probably trying to load the data
871 // which was stored by defferent.
872 // perhaps out-dated serializers
873 //
874 // Use versioning mechanizm to
875 // privide backwards compatiblity
876 // option, among different versions
877 // stored data-format
878
879
880 int stmPos = mpStm->GetStreamPos();
881
882 wxClassInfo* pCInfo = 0;
883 wxSerializerInfo* pSrz = 0;
884
885 bool success = ExchangeObjectInfo( &pCInfo, &pSrz );
886
887 wxASSERT( success ); // DBG:: all info about object should be present
888 // i.e. class info, serializer which matches the object's
889 // version (see source of ExchangeObjectInfo() for more info)
890
891 (*ppWxObj) = pCInfo->CreateObject();
892
893 DoExchangeObject( (*ppWxObj), *pSrz );
894 }
895 }
896 else
897 {
898 // otherwise if storing the pointer to an object
899
900 // first, check if it's an initial reference
901
902 long refNo = (long)mInitialRefsHash.Get( (long)(*ppWxObj) );
903
904 if ( refNo != 0 )
905 {
906 mpStm->StoreChar( (char)SOT_INITIAL_REF );
907 mpStm->StoreLong( refNo );
908
909 return;
910 }
911
912 long streamPos = (long) mRefHash.Get( (long)(*ppWxObj) );
913
914 // check if object is already stored
915 if ( streamPos != 0 )
916 {
917 // store only reference to the object (in the form of stream-offset)
918
919 mpStm->StoreChar( (char)SOT_POINTER_TO_OBJ );
920 mpStm->StoreLong( streamPos );
921 }
922 else
923 {
924 // otherwise store the entire referenced object
925
926 if ( (*ppWxObj) == NULL )
927 {
928 mpStm->StoreChar( (char)SOT_NULL_POINTER ); // token
929 return;
930 }
931
932 mpStm->StoreChar( (char)SOT_OBJ_DATA ); // token
933
934 // store object's info and data
935 XchgObj( *ppWxObj );
936 }
937 }
938}
939
940// storage methods for common wxWindows objects
941
942void wxObjectStorage::XchgWxStr( wxString& str )
943{
944 if ( mIsLoading )
945 {
946 long len = 0;
947 mpStm->LoadLong( &len );
948
949 str = "";
950 str.Append( (char)1, len );
951
952 mpStm->LoadBytes( (char*)str.c_str(), len );
953 }
954 else
955 XchgCStr( (char*)str.c_str() );
956}
957
958void wxObjectStorage::XchgWxSize( wxSize& size )
959{
960 XchgLong( size.x );
961 XchgLong( size.y );
962}
963
964void wxObjectStorage::XchgWxPoint( wxPoint& point )
965{
966 XchgLong( point.x );
967 XchgLong( point.y );
968}
969
970void wxObjectStorage::XchgWxRect( wxRect& rect )
971{
972 XchgLong( rect.x );
973 XchgLong( rect.y );
974 XchgLong( rect.width );
975 XchgLong( rect.height );
976}
977
978void wxObjectStorage::AddInitialRef( wxObject* pObjRef )
979{
980 // duplicates are not accepted
981
982 if ( mInitialRefsHash.Get( (long)pObjRef ) != NULL )
983
984 return;
985
986 ++mInitialRefsCnt;
987
988 // NOTE:: reference number is 1-based (zero is "reserved" by wxHashTable)
989
990 mInitialRefs.Append( pObjRef );
991 mInitialRefsHash.Put( (long)pObjRef, (wxObject*)mInitialRefsCnt );
992}
993
994void wxObjectStorage::ClearInitalRefs()
995{
996 mInitialRefsCnt = 0;
997
998 mInitialRefsHash.Clear();
999 mInitialRefsHash.Clear();
1000}
1001
1002/***** Implementation for class wxColourSerializer *****/
1003
1004IMPLEMENT_SERIALIZER_CLASS( wxColour,
1005 wxColourSerializer,
1006 wxColourSerializer::Serialize,
1007 NO_CLASS_INIT )
1008
1009void wxColourSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1010{
1011 wxColour* pCol = (wxColour*)pObj;
1012
1013 // slightly optimized
1014
1015 if ( store.IsLoading() )
1016 {
1017 long rgb;
1018 store.XchgLong( rgb );
1019
1020 *pCol = wxColour( rgb & 0xFF,
1021 ( rgb >> 8 ) & 0xFF,
1022 ( rgb >> 16 ) & 0xFF );
1023
1024 }
1025 else
1026 {
1027 long rgb = 0;
1028
1029 unsigned char r = pCol->Red(),g = pCol->Green(), b = pCol->Blue();
1030
1031 rgb = ( long(r) & 0x0000FF ) |
1032 ( ( long(g) << 8 ) & 0x00FF00 ) |
1033 ( ( long(b) << 16 ) & 0xFF0000 );
1034
1035 store.XchgLong( rgb );
1036 }
1037}
1038
1039/***** Implementation for class wxPenSerializer *****/
1040
1041IMPLEMENT_SERIALIZER_CLASS( wxPen,
1042 wxPenSerializer,
1043 wxPenSerializer::Serialize,
1044 NO_CLASS_INIT )
1045
1046void wxPenSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1047{
1048 wxPen* pPen = (wxPen*)pObj;
1049
1050 int cap;
1051 wxColour col;
1052 int join;
1053 int style;
1054 int width;
1055
1056 if ( store.IsLoading() == FALSE )
1057 {
1058 cap = pPen->GetCap();
1059 col = pPen->GetColour();
1060 join = pPen->GetJoin();
1061 style = pPen->GetStyle();
1062 width = pPen->GetWidth();
1063 }
1064
1065 store.XchgInt( cap );
1066 store.XchgObj( (wxObject*) &col );
1067 store.XchgInt( join );
1068 store.XchgInt( style );
1069 store.XchgInt( width );
1070
1071 if ( store.IsLoading() )
1072 {
1073 pPen->SetCap ( cap );
1074 pPen->SetColour( col );
1075 pPen->SetJoin ( join );
1076 pPen->SetStyle ( style );
1077 pPen->SetWidth ( width );
1078 }
1079}
1080
1081/***** Implementation for class wxBrushSerializer *****/
1082
1083IMPLEMENT_SERIALIZER_CLASS( wxBrush,
1084 wxBrushSerializer,
1085 wxBrushSerializer::Serialize,
1086 NO_CLASS_INIT )
1087
1088void wxBrushSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1089{
1090 wxBrush* pBrush = (wxBrush*)pObj;
1091
1092 wxColour col;
1093 int style;
1094
1095 if ( store.IsLoading() == FALSE )
1096 {
1097 col = pBrush->GetColour();
1098 style = pBrush->GetStyle();
1099 }
1100
1101 store.XchgObj( (wxObject*) &col );
1102 store.XchgInt( style );
1103
1104 if ( store.IsLoading() )
1105 {
1106 pBrush->SetColour( col );
1107 pBrush->SetStyle ( style );
1108 }
1109}
1110
1111/***** Implementation for class wxEvtHandlerSerializer *****/
1112
1113IMPLEMENT_SERIALIZER_CLASS( wxEvtHandler,
1114 wxEvtHandlerSerializer,
1115 wxEvtHandlerSerializer::Serialize,
1116 wxEvtHandlerSerializer::Initialize )
1117
1118void wxEvtHandlerSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1119{
1120 wxEvtHandler* pHnd = ( wxEvtHandler*) pObj;
1121
1122 wxEvtHandler* pPrevHnd;
1123 wxEvtHandler* pNextHnd;
1124
1125 if ( store.IsLoading() == FALSE )
1126 {
1127 // extract properties when storing
1128
1129 pPrevHnd = pHnd->GetPreviousHandler();
1130 pNextHnd = pHnd->GetNextHandler();
1131 }
1132
1133 // serialize properties
1134
1135 store.XchgObjPtr( (wxObject**) &pPrevHnd );
1136 store.XchgObjPtr( (wxObject**) &pNextHnd );
1137
1138 if ( store.IsLoading() )
1139 {
1140 // set properties when loading
1141
1142 pHnd->SetPreviousHandler( pPrevHnd );
1143 pHnd->SetNextHandler ( pNextHnd );
1144 }
1145}
1146
1147void wxEvtHandlerSerializer::Initialize( wxObject* pObj )
1148{
1149 wxEvtHandler* pHnd = ( wxEvtHandler*) pObj;
1150
1151 // if we're on top
1152 if ( pHnd->GetPreviousHandler() == NULL )
1153 {
1154 // then check if we're in the chain which is
1155 // attached to wxWindow object
1156
1157 wxEvtHandler* pCur = pHnd->GetNextHandler();
1158
1159 while( pCur )
1160 {
1161 if ( pCur->IsKindOf( CLASSINFO(wxWindow) ) )
1162 {
1163 // since we are the the right-most event handler
1164 // in the chain, then we must be the first
1165 // receiver of events sent to the window obj. -
1166 // therefore "make it happen":
1167
1168 ((wxWindow*)pCur)->SetEventHandler( pHnd );
1169
1170 // but if wxWindow is persistant, then why
1171 // we're setting "manually" the property
1172 // which is serialized anyway?
1173 //
1174 // The *PROBLEM* is that, it's not always good idea
1175 // to serialize a window (e.g. main frame), instead
1176 // they could be referred by "inital-refernces". To
1177 // handle the later case, we additionally make sure
1178 // that serialized evt. handlers are "glued" to the
1179 // window correctly,even if the window is transient
1180 // itself
1181
1182 return;
1183 }
1184
1185 // keep on searching for wxWindows down the chain
1186
1187 pCur = pCur->GetNextHandler();
1188 }
1189 }
1190}
1191
1192/***** Implementation for class wxWindowSerializer *****/
1193
1194IMPLEMENT_SERIALIZER_CLASS( wxWindow,
1195 wxWindowSerializer,
1196 wxWindowSerializer::Serialize,
1197 NO_CLASS_INIT )
1198
1199void wxWindowSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1200{
1201 DoSerialize( pObj, store, (wndCreationFn)wxWindowSerializer::CreateWindowFn );
1202}
1203
1204void wxWindowSerializer::DoSerialize( wxObject* pObj, wxObjectStorage& store,
1205 wndCreationFn creationFn, bool refreshNow )
1206{
1207 // wxWindow is a kind of wxEvtHandler - peform serialization of
1208 // the base class first
1209
1210 info.SerializeInherited( pObj, store );
1211
1212 wxWindow* pWnd = (wxWindow*)pObj;
1213
1214 long id;
1215 long style;
1216 wxString name;
1217 wxPoint pos;
1218 wxSize size;
1219 wxColour bkCol;
1220 wxWindow* pParent;
1221 wxList* pCldLst;
1222 wxEvtHandler* pEvtHandler;
1223
1224 wxList tmpCldLst;
1225
1226 if ( store.IsLoading() == FALSE )
1227 {
1228 // extract properties from window object
1229
1230 name = pWnd->GetName();
1231 id = pWnd->GetId();
1232 style = pWnd->GetWindowStyleFlag();
1233
1234 // workaround for long/int inconsitency of wxWin2.0a
1235 int x,y,w,h;
1236 pWnd->GetPosition( &x, &y );
1237 pWnd->GetSize ( &w, &h );
1238 bkCol = pWnd->GetBackgroundColour();
1239
1240 pos.x = x; pos.y = y;
1241 size.x = w; size.y = h;
1242
1243 pEvtHandler = pWnd->GetEventHandler();
1244 pParent = pWnd->GetParent();
1245
1246#ifdef __HACK_MY_MSDEV40__
1247 pCldLst = pWnd->GetChildren();
1248#else
1249 pCldLst = &pWnd->GetChildren();
1250#endif
1251
1252 }
1253
1254 // serialize properties
1255
1256 store.XchgWxStr ( name );
1257 store.XchgLong ( id );
1258 store.XchgLong ( style );
1259 store.XchgLong ( pos.x );
1260 store.XchgLong ( pos.y );
1261 store.XchgLong ( size.x );
1262 store.XchgLong ( size.y );
1263 store.XchgObj ( (wxObject* ) &bkCol );
1264 store.XchgObjPtr( (wxObject**) &pParent );
1265 store.XchgObjPtr( (wxObject**) &pEvtHandler );
1266
1267 if ( store.IsLoading() )
1268 {
1269
1270 // serialize to on-stack list object, since children will
1271 // automatically add themselves to parent's list
1272
1273 pCldLst = &tmpCldLst;
1274
1275 // first create window (when loading), then serialize it's children
1276
1277 (*creationFn)( pWnd, pParent, id, pos, size, style, name );
1278
1279 //pWnd->SetBackgroundColour( bkCol );
1280
1281 //pWnd->SetBackgroundColour( bkCol );
1282
1283 if ( refreshNow && 0 ) pWnd->Refresh();
1284 }
1285
1286 store.XchgObjList( *pCldLst );
1287}
1288
1289void wxWindowSerializer::CreateWindowFn( wxWindow* wnd, wxWindow* parent, const wxWindowID id,
1290 const wxPoint& pos, const wxSize& size, long style ,
1291 const wxString& name )
1292{
1293 wnd->Create( parent, id, pos, size, style, name );
1294}
1295
1296/***** Implementation for class wxTextCtrlSerializer *****/
1297
1298IMPLEMENT_SERIALIZER_CLASS( wxTextCtrl,
1299 wxTextCtrlSerializer,
1300 wxTextCtrlSerializer::Serialize,
1301 NO_CLASS_INIT )
1302
1303void wxTextCtrlSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1304{
1305 wxTextCtrl* pCtrl = (wxTextCtrl*)pObj;
1306
1307 wxWindowSerializer::DoSerialize( pObj, store,
1308 (wndCreationFn)wxTextCtrlSerializer::CreateTextCtrlWindowFn );
1309
1310 wxString text;
1311
1312 if ( store.IsLoading() == FALSE )
1313
1314 text = pCtrl->GetValue();
1315
1316 store.XchgWxStr( text );
1317
1318 if ( store.IsLoading() )
1319
1320 pCtrl->SetValue( text );
1321}
1322
1323void wxTextCtrlSerializer::CreateTextCtrlWindowFn( wxTextCtrl* wnd, wxWindow* parent, const wxWindowID id,
1324 const wxPoint& pos, const wxSize& size, long style ,
1325 const wxString& name )
1326{
1327 wnd->Create( parent, id, "", pos, size, style );
1328
1329 // FIXME:: quick-hack
1330 wnd->SetBackgroundColour( wxColour(255,255,255) );
1331}
1332
1333/***** Implementation for class wxButtonSerializer *****/
1334
1335IMPLEMENT_SERIALIZER_CLASS( wxButton,
1336 wxButtonSerializer,
1337 wxButtonSerializer::Serialize,
1338 NO_CLASS_INIT )
1339
1340void wxButtonSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1341{
1342 wxButton* pBtn = (wxButton*)pObj;
1343
1344 wxWindowSerializer::DoSerialize( pObj, store,
1345 (wndCreationFn)wxButtonSerializer::CreateButtonWindowFn );
1346
1347 wxString label;
1348
1349 if ( store.IsLoading() == FALSE )
1350
1351 label = pBtn->GetLabel();
1352
1353 store.XchgWxStr( label );
1354
1355 if ( store.IsLoading() )
1356
1357 pBtn->SetLabel( label );
1358}
1359
1360void wxButtonSerializer::CreateButtonWindowFn( wxButton* btn, wxWindow* parent, const wxWindowID id,
1361 const wxPoint& pos, const wxSize& size, long style ,
1362 const wxString& name )
1363{
1364 btn->Create( parent, id, "", pos, size, style );
1365}
1366
1367/***** Implementation for class wxStaticTextSerializer *****/
1368
1369IMPLEMENT_SERIALIZER_CLASS( wxStaticText,
1370 wxStaticTextSerializer,
1371 wxStaticTextSerializer::Serialize,
1372 NO_CLASS_INIT )
1373
1374void wxStaticTextSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1375{
1376 wxStaticText* pSTxt = (wxStaticText*)pObj;
1377
1378 wxWindowSerializer::DoSerialize( pObj, store,
1379 (wndCreationFn)wxStaticTextSerializer::CreateSTextWindowFn );
1380
1381 wxString label;
1382
1383 if ( store.IsLoading() == FALSE )
1384
1385 label = pSTxt->GetLabel();
1386
1387 store.XchgWxStr( label );
1388
1389 if ( store.IsLoading() )
1390
1391 pSTxt->SetLabel( label );
1392}
1393
1394void wxStaticTextSerializer::CreateSTextWindowFn( wxStaticText* pSTxt, wxWindow* parent, const wxWindowID id,
1395 const wxPoint& pos, const wxSize& size, long style ,
1396 const wxString& name )
1397{
1398 pSTxt->Create( parent, id, "", pos, size, style );
1399}
1400
1401/***** Implementation for class wxScrollBarSerializer *****/
1402
1403IMPLEMENT_SERIALIZER_CLASS( wxScrollBar,
1404 wxScrollBarSerializer,
1405 wxScrollBarSerializer::Serialize,
1406 NO_CLASS_INIT )
1407
1408void wxScrollBarSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1409{
1410 wxWindowSerializer::DoSerialize( pObj, store,
1411 (wndCreationFn)wxScrollBarSerializer::CreateScollBarWindowFn );
1412}
1413
1414void wxScrollBarSerializer::CreateScollBarWindowFn( wxScrollBar* sbar, wxWindow* parent, const wxWindowID id,
1415 const wxPoint& pos, const wxSize& size, long style ,
1416 const wxString& name )
1417{
1418 sbar->Create( parent, id, pos, size, style );
1419}
1420
1421// FIXME:: serialization of tree control causes bunch of assertions on wxGtk
1422
1423#if 0
1424
1425/***** Implementation for class wxTreeCtrlSerializer *****/
1426
1427IMPLEMENT_SERIALIZER_CLASS( wxTreeCtrl,
1428 wxTreeCtrlSerializer,
1429 wxTreeCtrlSerializer::Serialize,
1430 NO_CLASS_INIT )
1431
1432static bool get_child_count( wxTreeItemId itemId, wxTreeCtrl* pTree )
1433{
1434 long cookie;
1435
1436 if ( !pTree->ItemHasChildren( itemId ) ) return 0;
1437
1438 wxTreeItemId curId = pTree->GetFirstChild( itemId, cookie );
1439
1440 int cnt = 0;
1441
1442 do
1443 {
1444 ++cnt;
1445
1446 curId = pTree->GetNextChild( itemId, cookie );
1447
1448 } while( curId );
1449
1450 return cnt;
1451}
1452
1453void wxTreeCtrlSerializer::SerializeBranch( wxTreeItemId parentId, wxTreeCtrl* pTree,
1454 wxObjectStorage& store, wxTreeItemId nextVisId,
1455 int depth )
1456{
1457 wxString text;
1458 int childCnt;
1459 int img;
1460 bool isExpanded;
1461 bool isVisible;
1462
1463 if ( store.IsLoading() )
1464 {
1465 store.XchgWxStr( text );
1466 store.XchgInt ( childCnt );
1467 store.XchgInt ( img );
1468 store.XchgBool ( isExpanded );
1469 store.XchgBool ( isVisible );
1470
1471 wxTreeItemId subBranchId =
1472 ( depth == 0 )
1473 ? pTree->AddRoot( text, img )
1474 : pTree->AppendItem( parentId, text, img);
1475
1476 // check if the item was labeled as first-visible
1477
1478 if ( isVisible )
1479
1480 nextVisId = subBranchId;
1481
1482 while ( childCnt-- )
1483
1484 SerializeBranch( subBranchId, pTree, store, nextVisId, depth+1 );
1485
1486 if ( isExpanded ) pTree->Expand( subBranchId );
1487 else pTree->Collapse( subBranchId );
1488
1489 }
1490 else
1491 {
1492 // otherwise storing children of the branch
1493
1494 text = pTree->GetItemText( parentId );
1495 childCnt = get_child_count( parentId, pTree );
1496 img = pTree->GetItemImage( parentId );
1497 isExpanded = pTree->IsExpanded( parentId );
1498
1499 if ( parentId == nextVisId )
1500
1501 isVisible = TRUE;
1502 else
1503 isVisible = FALSE;
1504
1505 store.XchgWxStr( text );
1506 store.XchgInt ( childCnt );
1507 store.XchgInt ( img );
1508 store.XchgBool ( isExpanded );
1509 store.XchgBool ( isVisible );
1510
1511 long cookie;
1512
1513 wxTreeItemId curId = pTree->GetFirstChild( parentId, cookie );
1514
1515 while ( childCnt-- )
1516 {
1517 SerializeBranch( curId, pTree, store, nextVisId, -1 );
1518
1519 curId = pTree->GetNextChild( parentId, cookie );
1520 }
1521 }
1522}
1523
1524void wxTreeCtrlSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1525{
1526 // FOR NOW::image id's and image list are not serialized!
1527 // it should be provided as a initial reference (IR)
1528 // if it presents. Currently only normal image list
1529 // for normal items-states is set up
1530
1531 wxTreeCtrl* pTree = (wxTreeCtrl*)pObj;
1532
1533 wxWindowSerializer::DoSerialize( pObj, store,
1534 (wndCreationFn)wxTreeCtrlSerializer::CreateTreeCtrlWindowFn );
1535
1536 wxTreeItemId nextVisId = (long)0;
1537 int indent = 0;
1538 int childCnt;
1539 wxImageList* pILst;
1540
1541 if ( store.IsLoading() )
1542 {
1543 store.XchgInt( indent );
1544
1545 store.XchgObjPtr( (wxObject**) &(pILst) );
1546
1547 if ( pILst )
1548
1549 pTree->SetImageList( pILst );
1550
1551 store.XchgInt( childCnt );
1552
1553 while ( childCnt-- )
1554
1555 SerializeBranch( pTree->GetRootItem() , pTree, store, nextVisId, 0 );
1556
1557 // FIXME:: somehow this is no longer inmplemented in latest wxWin-2.0
1558 // pTree->ScrollTo( nextVisId );
1559
1560 pTree->SetIndent( indent );
1561 }
1562 else
1563 {
1564 indent = pTree->GetIndent();
1565
1566 // FIXME:: somehow this is no longer inmplemented in latest wxWin-2.0
1567 // nextVisId = pTree->GetFirstVisibleItem();
1568
1569 nextVisId = pTree->GetRootItem();
1570
1571 pILst = pTree->GetImageList();
1572
1573 store.XchgInt( indent );
1574
1575 store.XchgObjPtr( (wxObject**) &(pILst) );
1576
1577 // otherwise storing children of the branch
1578
1579 childCnt = get_child_count( pTree->GetRootItem(), pTree );
1580
1581 store.XchgInt( childCnt );
1582
1583 long cookie;
1584 wxTreeItemId parent = pTree->GetRootItem();
1585 wxTreeItemId curId = pTree->GetFirstChild( parent, cookie );
1586
1587 while ( childCnt-- )
1588 {
1589 SerializeBranch( curId, pTree, store, nextVisId, -1 );
1590
1591 curId = pTree->GetNextChild( parent, cookie );
1592 }
1593 }
1594}
1595
1596void wxTreeCtrlSerializer::CreateTreeCtrlWindowFn( wxTreeCtrl* tree, wxWindow* parent, const wxWindowID id,
1597 const wxPoint& pos, const wxSize& size, long style ,
1598 const wxString& name )
1599{
1600 tree->Create( parent, id, pos, size, style );
1601}
1602
1603#endif
1604
1605/***** Implementation for class wxIOStreamWrapper *****/
1606
1607IMPLEMENT_DYNAMIC_CLASS( wxIOStreamWrapper, wxDataStreamBase )
1608
1609void wxIOStreamWrapper::Close()
1610{
1611 // close previous stream if any
1612 if ( mpStm )
1613 {
1614 mpStm->flush();
1615
1616 if ( mOwnsStmObject )
1617
1618 delete mpStm;
1619
1620 mOwnsStmObject = FALSE;
1621
1622 mpStm = NULL;
1623 }
1624
1625 mStreamPos = 0;
1626}
1627
1628wxIOStreamWrapper::wxIOStreamWrapper()
1629 : mpStm( NULL ),
1630 mOwnsStmObject( FALSE ),
1631 mStreamPos(0)
1632{
1633 mIsForInput = TRUE; // just a defaul
1634}
1635
1636bool wxIOStreamWrapper::Create( const char* fileName, bool forInput )
1637{
1638 Close();
1639
1640 // FIXME:: if using default value of the last arg, linking breaks complaining
1641 // about duplicated symbols
1642
1643#ifdef __WXMSW__
1644 mpStm = new fstream( fileName,
1645 ( ( forInput == FALSE ) ? ios::out : ios::in ) | ios::binary,
1646 0
1647 );
1648#else
1649 mpStm = new fstream( fileName,
1650 ( ( forInput == FALSE ) ? ios::out : ios::in ) | ios::binary
1651 );
1652#endif
1653
1654 //((fstream*)mpStm)->close();
1655
1656 //delete ((fstream*)mpStm);
1657
1658 mOwnsStmObject = TRUE;
1659
1660 if ( !Good() )
1661 {
1662 Close();
1663 return FALSE;
1664 }
1665
1666 mIsForInput = forInput;
1667
1668 return TRUE;
1669}
1670
1671wxIOStreamWrapper::wxIOStreamWrapper( iostream& stm, bool forInput )
1672 : mOwnsStmObject( FALSE )
1673{
1674 mpStm = &stm;
1675
1676 // FIXME:: what about actual stream postion of attached stream?
1677 mStreamPos = 0;
1678
1679 mIsForInput = forInput;
1680}
1681
1682void wxIOStreamWrapper::Attach( iostream& stm, bool forInput )
1683{
1684 Close();
1685
1686 mOwnsStmObject = FALSE;
1687
1688 mpStm = &stm;
1689
1690 // FIXME:: what about actual stream postion of attached stream?
1691 mStreamPos = 0;
1692
1693 mIsForInput = forInput;
1694}
1695
1696wxIOStreamWrapper::~wxIOStreamWrapper()
1697{
1698 Close();
1699}
1700
1701bool wxIOStreamWrapper::StoreChar( char ch )
1702{
1703 mpStm->write( &ch, sizeof(char) );
1704
1705 mStreamPos += sizeof(char);
1706
1707 return Good();
1708}
1709
1710bool wxIOStreamWrapper::StoreInt( int i )
1711{
1712 mpStm->write( (char*)&i, sizeof(int) );
1713
1714 mStreamPos += sizeof(int);
1715
1716 return Good();
1717}
1718
1719bool wxIOStreamWrapper::StoreLong( long l )
1720{
1721 mpStm->write( (char*)&l, sizeof(long) );
1722
1723 mStreamPos += sizeof(long);
1724
1725 return Good();
1726}
1727
1728bool wxIOStreamWrapper::StoreDouble( double d )
1729{
1730 mpStm->write( (char*)&d, sizeof(double) );
1731
1732 mStreamPos += sizeof(double);
1733
1734 return Good();
1735}
1736
1737bool wxIOStreamWrapper::StoreBytes( void* bytes, int count )
1738{
1739 mpStm->write( (char*)bytes, count );
1740
1741 mStreamPos += count;
1742
1743 return Good();
1744}
1745
1746bool wxIOStreamWrapper::LoadChar( char* pCh )
1747{
1748 mpStm->read( pCh, sizeof(char) );
1749
1750 mStreamPos += sizeof(char);
1751
1752 return Good();
1753}
1754
1755bool wxIOStreamWrapper::LoadInt( int* pI )
1756{
1757 mpStm->read( (char*)pI, sizeof(int) );
1758
1759 mStreamPos += sizeof(int);
1760
1761 return Good();
1762}
1763
1764bool wxIOStreamWrapper::LoadLong( long* pL )
1765{
1766 mpStm->read( (char*)pL, sizeof(long) );
1767
1768 mStreamPos += sizeof(long);
1769
1770 return Good();
1771}
1772
1773bool wxIOStreamWrapper::LoadDouble( double* pD )
1774{
1775 mpStm->read( (char*)pD, sizeof(double) );
1776
1777 mStreamPos += sizeof(double);
1778
1779 return Good();
1780}
1781
1782bool wxIOStreamWrapper::LoadBytes ( void* pBytes, int count )
1783{
1784 mpStm->read( (char*)pBytes, count );
1785
1786 mStreamPos += count;
1787
1788 return Good();
1789}
1790
1791bool wxIOStreamWrapper::Flush()
1792{
1793 mpStm->flush();
1794
1795 return Good();
1796}
1797
1798long wxIOStreamWrapper::GetStreamPos()
1799{
1800 return mStreamPos;
1801}
1802
1803bool wxIOStreamWrapper::Good()
1804{
1805 // FIXME FIXME:: somehow, when using ios::good/ios::bad, linking breaks complaining
1806 // about "ios::bad" already defined in this object file...
1807
1808 return TRUE;
1809}