]> git.saurik.com Git - wxWidgets.git/blob - utils/framelayout/src/objstore.cpp
changed removed wxToUpper to standard toupper
[wxWidgets.git] / utils / framelayout / src / objstore.cpp
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
40 bool wxSerializerInfo::alreadyInitialized = FALSE;
41 wxSerializerInfo *wxSerializerInfo::first = NULL;
42 wxHashTable wxSerializerInfo::serInfoHash;
43
44 wxSerializerInfo::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
62 int 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
97 void 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
217 wxSerializerInfo* 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
228 static 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
259 void 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
273 void 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
289 IMPLEMENT_ABSTRACT_CLASS( wxDataStreamBase, wxObject )
290
291 /***** Implementation for class wxObjectStorage *****/
292
293 // codes, used as tokens written/read from the stream
294
295 enum 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
305 char wxObjectStorage::mVerSepartorCh = '#';
306 char wxObjectStorage::mMinorMajorSepartorCh = '-';
307
308 IMPLEMENT_DYNAMIC_CLASS( wxObjectStorage, wxObject )
309
310 wxObjectStorage::wxObjectStorage()
311 : mpStm ( 0 ),
312 mIsLoading ( TRUE ),
313 mInitialRefsCnt ( 0 ),
314 mFinalizePending( FALSE )
315 {}
316
317 wxObjectStorage::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
329 wxObjectStorage::~wxObjectStorage()
330 {
331 if ( mFinalizePending )
332
333 Finalize(); // <- do it now, if "user" forgot about it
334 }
335
336 /*** protected members ***/
337
338 void wxObjectStorage::ClearHashesAndLists()
339 {
340 mNewObjs.Clear();
341 mSerializersForNewObjs.Clear();
342 mRefHash.Clear();
343 }
344
345 /*** public members ***/
346
347 void 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
364 void 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
397 void wxObjectStorage::XchgChar( char& chObj )
398 {
399 if ( mIsLoading ) mpStm->LoadChar( &chObj );
400 else mpStm->StoreChar( chObj );
401 }
402
403 void wxObjectStorage::XchgInt( int& intObj )
404 {
405 if ( mIsLoading ) mpStm->LoadInt( &intObj );
406 else mpStm->StoreInt( intObj );
407 }
408
409 void 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
422 void wxObjectStorage::XchgLong( long& longObj )
423 {
424 if ( mIsLoading ) mpStm->LoadLong( &longObj );
425 else mpStm->StoreLong( longObj );
426 }
427
428 void 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
442 void 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
454 void 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
500 void 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
543 void 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
582 void wxObjectStorage::XchgDouble( double& doubleObj )
583 {
584 if ( mIsLoading ) mpStm->LoadDouble( &doubleObj );
585 else mpStm->StoreDouble( doubleObj );
586 }
587
588 void 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
604 wxSerializerInfo* 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
632 bool 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 ( toupper(*v1) != toupper(*v2) )
644
645 return FALSE;
646
647 ++v1; ++v2;
648 }
649
650 return ( *v1 == '\0' && *v2 == '\0' );
651 }
652
653 bool 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
762 wxSerializerInfo* 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
785 void 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
810 void 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
830 void 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
942 void 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
958 void wxObjectStorage::XchgWxSize( wxSize& size )
959 {
960 XchgLong( size.x );
961 XchgLong( size.y );
962 }
963
964 void wxObjectStorage::XchgWxPoint( wxPoint& point )
965 {
966 XchgLong( point.x );
967 XchgLong( point.y );
968 }
969
970 void wxObjectStorage::XchgWxRect( wxRect& rect )
971 {
972 XchgLong( rect.x );
973 XchgLong( rect.y );
974 XchgLong( rect.width );
975 XchgLong( rect.height );
976 }
977
978 void 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
994 void wxObjectStorage::ClearInitalRefs()
995 {
996 mInitialRefsCnt = 0;
997
998 mInitialRefsHash.Clear();
999 mInitialRefsHash.Clear();
1000 }
1001
1002 /***** Implementation for class wxColourSerializer *****/
1003
1004 IMPLEMENT_SERIALIZER_CLASS( wxColour,
1005 wxColourSerializer,
1006 wxColourSerializer::Serialize,
1007 NO_CLASS_INIT )
1008
1009 void 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
1041 IMPLEMENT_SERIALIZER_CLASS( wxPen,
1042 wxPenSerializer,
1043 wxPenSerializer::Serialize,
1044 NO_CLASS_INIT )
1045
1046 void 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
1083 IMPLEMENT_SERIALIZER_CLASS( wxBrush,
1084 wxBrushSerializer,
1085 wxBrushSerializer::Serialize,
1086 NO_CLASS_INIT )
1087
1088 void 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
1113 IMPLEMENT_SERIALIZER_CLASS( wxEvtHandler,
1114 wxEvtHandlerSerializer,
1115 wxEvtHandlerSerializer::Serialize,
1116 wxEvtHandlerSerializer::Initialize )
1117
1118 void 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
1147 void 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
1194 IMPLEMENT_SERIALIZER_CLASS( wxWindow,
1195 wxWindowSerializer,
1196 wxWindowSerializer::Serialize,
1197 NO_CLASS_INIT )
1198
1199 void wxWindowSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1200 {
1201 DoSerialize( pObj, store, (wndCreationFn)wxWindowSerializer::CreateWindowFn );
1202 }
1203
1204 void 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
1289 void 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
1298 IMPLEMENT_SERIALIZER_CLASS( wxTextCtrl,
1299 wxTextCtrlSerializer,
1300 wxTextCtrlSerializer::Serialize,
1301 NO_CLASS_INIT )
1302
1303 void 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
1323 void 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
1335 IMPLEMENT_SERIALIZER_CLASS( wxButton,
1336 wxButtonSerializer,
1337 wxButtonSerializer::Serialize,
1338 NO_CLASS_INIT )
1339
1340 void 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
1360 void 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
1369 IMPLEMENT_SERIALIZER_CLASS( wxStaticText,
1370 wxStaticTextSerializer,
1371 wxStaticTextSerializer::Serialize,
1372 NO_CLASS_INIT )
1373
1374 void 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
1394 void 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
1403 IMPLEMENT_SERIALIZER_CLASS( wxScrollBar,
1404 wxScrollBarSerializer,
1405 wxScrollBarSerializer::Serialize,
1406 NO_CLASS_INIT )
1407
1408 void wxScrollBarSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
1409 {
1410 wxWindowSerializer::DoSerialize( pObj, store,
1411 (wndCreationFn)wxScrollBarSerializer::CreateScollBarWindowFn );
1412 }
1413
1414 void 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
1427 IMPLEMENT_SERIALIZER_CLASS( wxTreeCtrl,
1428 wxTreeCtrlSerializer,
1429 wxTreeCtrlSerializer::Serialize,
1430 NO_CLASS_INIT )
1431
1432 static 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
1453 void 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
1524 void 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
1596 void 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
1607 IMPLEMENT_DYNAMIC_CLASS( wxIOStreamWrapper, wxDataStreamBase )
1608
1609 void 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
1628 wxIOStreamWrapper::wxIOStreamWrapper()
1629 : mpStm( NULL ),
1630 mOwnsStmObject( FALSE ),
1631 mStreamPos(0)
1632 {
1633 mIsForInput = TRUE; // just a defaul
1634 }
1635
1636 bool 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
1671 wxIOStreamWrapper::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
1682 void 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
1696 wxIOStreamWrapper::~wxIOStreamWrapper()
1697 {
1698 Close();
1699 }
1700
1701 bool wxIOStreamWrapper::StoreChar( char ch )
1702 {
1703 mpStm->write( &ch, sizeof(char) );
1704
1705 mStreamPos += sizeof(char);
1706
1707 return Good();
1708 }
1709
1710 bool wxIOStreamWrapper::StoreInt( int i )
1711 {
1712 mpStm->write( (char*)&i, sizeof(int) );
1713
1714 mStreamPos += sizeof(int);
1715
1716 return Good();
1717 }
1718
1719 bool wxIOStreamWrapper::StoreLong( long l )
1720 {
1721 mpStm->write( (char*)&l, sizeof(long) );
1722
1723 mStreamPos += sizeof(long);
1724
1725 return Good();
1726 }
1727
1728 bool wxIOStreamWrapper::StoreDouble( double d )
1729 {
1730 mpStm->write( (char*)&d, sizeof(double) );
1731
1732 mStreamPos += sizeof(double);
1733
1734 return Good();
1735 }
1736
1737 bool wxIOStreamWrapper::StoreBytes( void* bytes, int count )
1738 {
1739 mpStm->write( (char*)bytes, count );
1740
1741 mStreamPos += count;
1742
1743 return Good();
1744 }
1745
1746 bool wxIOStreamWrapper::LoadChar( char* pCh )
1747 {
1748 mpStm->read( pCh, sizeof(char) );
1749
1750 mStreamPos += sizeof(char);
1751
1752 return Good();
1753 }
1754
1755 bool wxIOStreamWrapper::LoadInt( int* pI )
1756 {
1757 mpStm->read( (char*)pI, sizeof(int) );
1758
1759 mStreamPos += sizeof(int);
1760
1761 return Good();
1762 }
1763
1764 bool wxIOStreamWrapper::LoadLong( long* pL )
1765 {
1766 mpStm->read( (char*)pL, sizeof(long) );
1767
1768 mStreamPos += sizeof(long);
1769
1770 return Good();
1771 }
1772
1773 bool wxIOStreamWrapper::LoadDouble( double* pD )
1774 {
1775 mpStm->read( (char*)pD, sizeof(double) );
1776
1777 mStreamPos += sizeof(double);
1778
1779 return Good();
1780 }
1781
1782 bool wxIOStreamWrapper::LoadBytes ( void* pBytes, int count )
1783 {
1784 mpStm->read( (char*)pBytes, count );
1785
1786 mStreamPos += count;
1787
1788 return Good();
1789 }
1790
1791 bool wxIOStreamWrapper::Flush()
1792 {
1793 mpStm->flush();
1794
1795 return Good();
1796 }
1797
1798 long wxIOStreamWrapper::GetStreamPos()
1799 {
1800 return mStreamPos;
1801 }
1802
1803 bool 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 }