musrfit 1.10.0
mud.c
Go to the documentation of this file.
1/*
2 * mud.c -- most of the utilities for reading/writing MUD format files
3 * procedures for MUD_FMT_ALL sections
4 *
5 * Copyright (C) 1994-2009 TRIUMF (Vancouver, Canada)
6 *
7 * Authors: T. Whidden, D. Arseneau, S. Daviel
8 *
9 * Released under the GNU LGPL - see http://www.gnu.org/licenses
10 *
11 * This program is free software; you can distribute it and/or modify it under
12 * the terms of the Lesser GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or any later version.
14 * Accordingly, this program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public License
17 * for more details.
18 *
19 * Revision history:
20 * v1.0 26-Jan-1994 [T. Whidden] Initial version
21 * v1.1 17-Feb-1994 [T. Whidden] Groups with member index
22 * v1.1a 14-Apr-1994 [T. Whidden] Fixes to MUD_read, MUD_search
23 * v1.2 08-Oct-2000 [D. Arseneau] Add MUD_setSizes
24 * v1.3 22-Apr-2003 [D. Arseneau] Add MUD_openInOut
25 * 25-Nov-2009 [D. Arseneau] Handle larger size_t
26 * 04-May-2016 [D. Arseneau] Edits for C++ use
27 */
28
29
30#include "mud.h"
31
32#ifdef NO_STDARG
33#include <varargs.h>
34#else
35#include <stdarg.h>
36#endif /* NO_STDARG */
37
38/* #define DEBUG 1 */ /* un-comment for debug */
39
40FILE*
41MUD_openInput( char* inFile )
42{
43 FILE* fin;
44
45 fin = fopen( inFile, "rb" );
46 if( fin == NULL )
47 {
48 return( NULL );
49 }
50 return( fin );
51}
52
53/* This is the same as MUD_openInput except for access mode */
54FILE*
55MUD_openInOut( char* inFile )
56{
57 FILE* fin;
58
59 fin = fopen( inFile, "r+b" );
60 if( fin == NULL )
61 {
62 return( NULL );
63 }
64 return( fin );
65}
66
67
68FILE*
69MUD_openOutput( char* outFile )
70{
71 FILE* fout;
72
73 fout = fopen( outFile, "wb" );
74 if( fout == NULL )
75 {
76 return( NULL );
77 }
78 return( fout );
79}
80
81
82void
83MUD_free( void* pMUD )
84{
85 if( pMUD != NULL ) MUD_free( ((MUD_SEC*)pMUD)->core.pNext );
86 else return;
87
88#ifdef DEBUG
89 printf( " MUD_free: freeing:" );
90 MUD_CORE_proc( MUD_SHOW, NULL, pMUD );
91#endif /* DEBUG */
92
93 (*((MUD_SEC*)pMUD)->core.proc)( MUD_FREE, NULL, (void*)pMUD );
94 free( pMUD );
95 pMUD = NULL;
96}
97
98
99BOOL
100MUD_encode( BUF* pBuf, void* pMUD, MUD_IO_OPT io_opt )
101{
102 if( pMUD == NULL ) return( TRUE );
103
104 ((MUD_SEC*)pMUD)->core.size = MUD_getSize( pMUD );
105
106#ifdef DEBUG
107 MUD_show( pMUD, MUD_ONE );
108#endif /* DEBUG */
109
110 if( pBuf->buf == NULL )
111 {
112 pBuf->buf = (char*)zalloc( MUD_size( pMUD ) );
113 }
114 else
115 {
116 pBuf->buf = (char*)realloc( pBuf->buf, pBuf->size + MUD_size( pMUD ) );
117 }
118
119 if( pBuf->buf == NULL ) return( FALSE );
120
121#ifdef DEBUG
122 printf( "MUD_encode: buf.size = %d\n", pBuf->size + MUD_size( pMUD ) );
123 printf( "MUD_encode: buf.buf = %08X\n", pBuf->buf );
124#endif /* DEBUG */
125
126 MUD_CORE_proc( MUD_ENCODE, pBuf, (MUD_SEC*)pMUD );
127 (*((MUD_SEC*)pMUD)->core.proc)( MUD_ENCODE, pBuf, (void*)pMUD );
128
129 if( ( MUD_secID( pMUD ) == MUD_SEC_GRP_ID ) &&
130 ( io_opt == MUD_ALL ) )
131 {
132 if( !MUD_encode( pBuf, ((MUD_SEC_GRP*)pMUD)->pMem, io_opt ) )
133 {
134 return( FALSE );
135 }
136 }
137
138 if( io_opt == MUD_ALL )
139 {
140 if( !MUD_encode( pBuf, ((MUD_SEC*)pMUD)->core.pNext, io_opt ) )
141 {
142 return( FALSE );
143 }
144 }
145
146 return( TRUE );
147}
148
149
150void*
152{
153 MUD_SEC* pMUD;
154 MUD_SEC mud;
155 int pos;
156
157 pos = pBuf->pos;
158
159#ifdef DEBUG
160 printf( "MUD_decode: decoding the core...\n" );
161#endif /* DEBUG */
162
163 /*
164 * Decode the core part
165 */
166 MUD_CORE_proc( MUD_DECODE, pBuf, &mud );
167
168 pMUD = (MUD_SEC*)MUD_new( mud.core.secID, mud.core.instanceID );
169 if( pMUD == NULL ) return( NULL );
170
171 MUD_assignCore( &mud, pMUD );
172
173#ifdef DEBUG
174 printf( "MUD_decode: done \n" );
175 printf( " decoding the section-specific...\n" );
176#endif /* DEBUG */
177
178 /*
179 * Decode the section-specific part
180 */
181 (*pMUD->core.proc)( MUD_DECODE, pBuf, (void*)pMUD );
182
183#ifdef DEBUG
184 printf( "MUD_decode: done\n" );
185#endif /* DEBUG */
186
187 pBuf->pos = pos + MUD_size( pMUD );
188
189 return( pMUD );
190}
191
192
193int
194MUD_getSize( void* pMUD )
195{
196 return( MUD_CORE_proc( MUD_GET_SIZE, NULL, (MUD_SEC*)pMUD ) +
197 (*((MUD_SEC*)pMUD)->core.proc)( MUD_GET_SIZE, NULL, pMUD ) );
198}
199
200
201void
202MUD_show( void* pMUD, MUD_IO_OPT io_opt )
203{
204 if( pMUD == NULL ) return;
205
207 (*((MUD_SEC*)pMUD)->core.proc)( MUD_SHOW, NULL, pMUD );
208
209 printf( "\n" );
210
211 if( ( MUD_secID( pMUD ) == MUD_SEC_GRP_ID ) &&
212 ( io_opt == MUD_ALL ) )
213 {
214 MUD_show( ((MUD_SEC_GRP*)pMUD)->pMem, io_opt );
215 }
216
217 if( ( MUD_secID( pMUD ) != MUD_SEC_EOF_ID ) &&
218 ( io_opt == MUD_ALL ) )
219 {
220 MUD_show( ((MUD_SEC*)pMUD)->core.pNext, io_opt );
221 }
222}
223
224void
225MUD_heads( void* pMUD, MUD_IO_OPT io_opt )
226{
227 if( pMUD == NULL ) return;
228
230 (*((MUD_SEC*)pMUD)->core.proc)( MUD_HEADS, NULL, pMUD );
231
232 if( ( MUD_secID( pMUD ) == MUD_SEC_GRP_ID ) &&
233 ( io_opt == MUD_ALL ) )
234 {
235 MUD_heads( ((MUD_SEC_GRP*)pMUD)->pMem, io_opt );
236 }
237
238 if( ( MUD_secID( pMUD ) != MUD_SEC_EOF_ID ) &&
239 ( io_opt == MUD_ALL ) )
240 {
241 MUD_heads( ((MUD_SEC*)pMUD)->core.pNext, io_opt );
242 }
243}
244
245
246/*
247 * MUD_writeEnd() - called after all writes to file
248 */
249BOOL
250MUD_writeEnd( FILE* fout )
251{
252 MUD_SEC_EOF* pMUD_eof;
253
254 if( ( pMUD_eof = (MUD_SEC_EOF*)MUD_new( MUD_SEC_EOF_ID, 1 ) ) == NULL )
255 {
256 return( FALSE );
257 }
258
259 if( !MUD_write( fout, pMUD_eof, MUD_ONE ) ) return( FALSE );
260
261 MUD_free( pMUD_eof );
262
263 return( TRUE );
264}
265
266
267/*
268 * MUD_writeFile() - use for completely assembled groups/sections
269 */
270BOOL
271MUD_writeFile( FILE* fout, void* pMUD_head )
272{
273 rewind( fout );
274 if( !MUD_write( fout, pMUD_head, MUD_ALL ) ) return( FALSE );
275 return( MUD_writeEnd( fout ) );
276}
277
278
279/*
280 * MUD_write() - use for completely assembled groups/sections
281 */
282BOOL
283MUD_write( FILE* fout, void* pMUD, MUD_IO_OPT io_opt )
284{
285 BUF buf;
286
287 if( pMUD == NULL ) return( TRUE );
288
289 bzero( &buf, sizeof( BUF ) );
290
291 if( !MUD_encode( &buf, pMUD, io_opt ) ) return( FALSE );
292
293 fwrite( buf.buf, buf.size, 1, fout );
294
295 _free( buf.buf );
296
297 return( TRUE );
298}
299
300
301/*
302 * MUD_writeGrpStart() - use for writes of unassembled groups
303 *
304 * Sequence :
305 * MUD_writeGrpStart()
306 * [ calls to MUD_writeGrpMem()
307 * or further blocks of MUD_writeGrpStart()-MUD_writeGrpEnd() ]
308 * MUD_writeGrpEnd()
309 * MUD_writeEnd()
310 */
311BOOL
312MUD_writeGrpStart( FILE* fout, MUD_SEC_GRP* pMUD_parentGrp,
313 MUD_SEC_GRP* pMUD_grp, int numMems )
314{
315 pMUD_grp->pParent = pMUD_parentGrp;
316
317 pMUD_grp->pos = ftell( fout );
318 pMUD_grp->memSize = 0;
319 MUD_INDEX_proc( MUD_FREE, NULL, pMUD_grp->pMemIndex );
320 MUD_free( pMUD_grp->pMem );
321
322 pMUD_grp->num = numMems;
323 pMUD_grp->core.size = MUD_getSize( (MUD_SEC*)pMUD_grp );
324 fseek( fout, pMUD_grp->core.size, 1 );
325 pMUD_grp->num = 0;
326
327 return( TRUE );
328}
329
330
331void
332addIndex( MUD_SEC_GRP* pMUD_grp, void* pMUD )
333{
334 MUD_INDEX** ppMUD_index;
335
336 for( ppMUD_index = &pMUD_grp->pMemIndex;
337 *ppMUD_index != NULL;
338 ppMUD_index = &(*ppMUD_index)->pNext ) ;
339
340 *ppMUD_index = (MUD_INDEX*)zalloc( sizeof( MUD_INDEX ) );
341 (*ppMUD_index)->offset = pMUD_grp->memSize;
342 (*ppMUD_index)->secID = MUD_secID( pMUD );
343 (*ppMUD_index)->instanceID = MUD_instanceID( pMUD );
344}
345
346
347/*
348 * MUD_writeGrpMem() - use for writes of unassembled groups
349 */
350BOOL
351MUD_writeGrpMem( FILE* fout, MUD_SEC_GRP* pMUD_grp, void* pMUD )
352{
353 ((MUD_SEC*)pMUD)->core.size = MUD_getSize( pMUD );
354
355 addIndex( pMUD_grp, pMUD );
356 pMUD_grp->num++;
357 pMUD_grp->memSize += MUD_totSize( pMUD );
358
359 if( MUD_secID( pMUD ) == MUD_SEC_GRP_ID )
360 {
361 if( !MUD_write( fout, pMUD, MUD_GRP ) ) return( FALSE );
362 }
363 else
364 {
365 if( !MUD_write( fout, pMUD, MUD_ONE ) ) return( FALSE );
366 }
367
368 return( TRUE );
369}
370
371
372/*
373 * MUD_writeGrpEnd() - use for writes of unassembled groups
374 */
375BOOL
376MUD_writeGrpEnd( FILE* fout, MUD_SEC_GRP* pMUD_grp )
377{
378 int pos;
379
380 pos = ftell( fout );
381
382 fseek( fout, pMUD_grp->pos, 0 );
383 if( !MUD_write( fout, pMUD_grp, MUD_ONE ) ) return( FALSE );
384 fseek( fout, pos, 0 );
385
386 if( pMUD_grp->pParent != NULL )
387 {
388 addIndex( pMUD_grp->pParent, pMUD_grp );
389 pMUD_grp->pParent->num++;
390 pMUD_grp->pParent->memSize += MUD_totSize( pMUD_grp );
391 }
392
393 return( TRUE );
394}
395
396
397void*
398MUD_readFile( FILE* fin )
399{
400 rewind( fin );
401
402 return( MUD_read( fin, MUD_ALL ) );
403}
404
405
406void*
407MUD_read( FILE* fin, MUD_IO_OPT io_opt )
408{
409 BUF buf;
410 MUD_SEC* pMUD_new;
411 MUD_SEC* pMUD_next;
412 int i;
413 UINT32 size;
414 int pos;
415
416#ifdef DEBUG
417 printf( "MUD_read: reading the section size...\n" );
418#endif /* DEBUG */
419
420 /*
421 * Read the section into a buffer
422 */
423 if( ( pos = ftell( fin ) ) == EOF ) return( NULL );
424 if( fread( &size, 4, 1, fin ) == 0 ) return( NULL );
425 bdecode_4( &size, &size ); /* byte ordering !!! */
426 if( fseek( fin, pos, 0 ) == EOF ) return( NULL );
427
428#ifdef DEBUG
429 printf( "MUD_read: got %lu\n", (unsigned long)(size) );
430 printf( " pos = %d\n", pos );
431 printf( " reading the section ...\n" );
432#endif /* DEBUG */
433
434 bzero( &buf, sizeof( BUF ) );
435 buf.buf = (char*)zalloc( (size_t)size );
436 if( fread( buf.buf, (size_t)size, 1, fin ) == 0 )
437 {
438 _free( buf.buf );
439 return( NULL );
440 }
441
442#ifdef DEBUG
443 printf( "MUD_read: done\n" );
444 printf( " decoding the section...\n" );
445#endif /* DEBUG */
446
447 /*
448 * Decode the buffer into a structure
449 */
450 pMUD_new = (MUD_SEC*)MUD_decode( &buf );
451 if( pMUD_new == NULL )
452 {
453 _free( buf.buf );
454 return( NULL );
455 }
456
457 _free( buf.buf );
458
459#ifdef DEBUG
460 printf( "MUD_read: done\n" );
461 MUD_show( pMUD_new, MUD_ONE );
462#endif /* DEBUG */
463
464 if( ( pMUD_new->core.secID == MUD_SEC_GRP_ID ) &&
465 ( ( io_opt == MUD_ALL ) || ( io_opt == MUD_GRP ) ) )
466 {
467 /*
468 * Read the group members
469 */
470 for( i = 0; i < ((MUD_SEC_GRP*)pMUD_new)->num; i++ )
471 {
472 pMUD_next = (MUD_SEC*)MUD_read( fin, MUD_GRP );
473 if( pMUD_next == NULL )
474 {
475 return( pMUD_new );
476 }
477 else if( pMUD_next->core.secID != MUD_SEC_EOF_ID )
478 {
479 MUD_add( (void**)&((MUD_SEC_GRP*)pMUD_new)->pMem, pMUD_next );
480 }
481 else
482 {
483 MUD_free( pMUD_next );
484 return( pMUD_new );
485 }
486 }
487
488#ifdef DEBUG
489 printf( "MUD_read: Group after reading members:\n" );
490 MUD_show( pMUD_new, MUD_ONE );
491#endif
492 }
493
494 if( ( MUD_secID( pMUD_new ) != MUD_SEC_EOF_ID ) &&
495 ( io_opt == MUD_ALL ) )
496 {
497 /*
498 * Read the next section
499 */
500 pMUD_next = (MUD_SEC*)MUD_read( fin, io_opt );
501 if( pMUD_next == NULL )
502 {
503 return( pMUD_new );
504 }
505 else if( MUD_secID( pMUD_next ) != MUD_SEC_EOF_ID )
506 {
507 MUD_add( (void**)&pMUD_new->core.pNext, pMUD_next );
508 }
509 else
510 {
511 MUD_free( pMUD_next );
512 return( pMUD_new );
513 }
514 }
515
516 return( pMUD_new );
517}
518
519/*
520 * UINT32 MUD_setSizes( void* pMUD )
521 *
522 * Modification history:
523 * 08-Oct-2000 DJA Created
524 *
525 * Description:
526 * Go through the mud structure *pMUD recursively measuring sizes and
527 * assigning memSize and index.offset values. This is used in the
528 * MUD-friendly routine MUD_closeWrite() before writing the file; the
529 * other friendly routines omit the picky bookkeeping needed to maintain
530 * accurate sizes and offsets.
531 *
532 * Parameter:
533 * A pointer to the root mud section to be measured (which is
534 * normally the entire mud structure for a run).
535 *
536 * Return value:
537 * When pMUD points to a group, return the memSize for the group;
538 * otherwise return 0.
539 */
540
541UINT32
542MUD_setSizes( void* pMUD )
543{
544 MUD_SEC* pMember;
545 MUD_INDEX* pGrpIndex;
546 UINT32 offset = 0;
547
548 /*
549 * Do nothing (return 0) if mud section is not a group.
550 */
551 if( MUD_secID( pMUD ) != MUD_SEC_GRP_ID )
552 {
553 return( 0 );
554 }
555 /*
556 * Loop over members of group
557 */
558 for( pMember = ((MUD_SEC_GRP*)pMUD)->pMem;
559 pMember != NULL;
560 pMember = pMember->core.pNext )
561 {
562 /*
563 * Look for corresponding index entry and set its offset. If index
564 * table is bad, just quit.
565 */
566 for( pGrpIndex = (MUD_INDEX*)(((MUD_SEC_GRP*)pMUD)->pMemIndex);
567 pGrpIndex->instanceID != MUD_instanceID( pMember ) ||
568 pGrpIndex->secID != MUD_secID( pMember ) ;
569 pGrpIndex = pGrpIndex->pNext )
570 {
571 if( pGrpIndex == NULL ) return( offset );
572 }
573 pGrpIndex->offset = offset;
574
575 /*
576 * If member is itself a group, recurse, measuring size.
577 */
578 if( MUD_secID( pMember ) == MUD_SEC_GRP_ID )
579 {
580 offset += MUD_setSizes( pMember );
581 }
582 offset += MUD_getSize( pMember );
583 }
584
585 ((MUD_SEC_GRP*)pMUD)->memSize = offset;
586
587 return( offset );
588}
589
590
591
592MUD_SEC*
593MUD_peekCore( FILE* fin )
594{
595 static MUD_SEC mud;
596 int pos;
597 BUF buf;
598 int size;
599
600 if( ( pos = ftell( fin ) ) == EOF ) return( NULL );
601
602 bzero( &mud, sizeof( MUD_SEC ) );
603 bzero( &buf, sizeof( BUF ) );
604
605 size = MUD_CORE_proc( MUD_GET_SIZE, 0, 0 );
606
607 buf.buf = (char*)zalloc( size );
608 if( buf.buf == NULL ) return( NULL );
609
610 if( fread( buf.buf, size, 1, fin ) == 0 )
611 {
612 free( buf.buf );
613 return( NULL );
614 }
615
616 fseek( fin, pos, 0 );
617
618 MUD_CORE_proc( MUD_DECODE, &buf, &mud );
619
620 free( buf.buf );
621
622 return( &mud );
623}
624
625
626#ifdef NO_STDARG
627void*
628MUD_search( va_alist )
629va_dcl
630#else
631void*
632MUD_search( void* pMUD_head, ... )
633#endif /* NO_STDARG */
634{
635 va_list args;
636#ifdef NO_STDARG
637 void* pMUD_head;
638#endif /* NO_STDARG */
639 MUD_SEC* pMUD;
640 MUD_SEC* pMUD_start;
641 UINT32 secID;
642 UINT32 instanceID;
643 SEEK_ENTRY* pSeekList = NULL;
644 SEEK_ENTRY** ppSeekEntry;
645 SEEK_ENTRY* pSeekEntry;
646
647 /*
648 * Assemble seek list from varargs
649 */
650#ifdef NO_STDARG
651 va_start( args );
652 pMUD_head = va_arg( args, void* );
653#else
654 va_start( args, pMUD_head );
655#endif /* NO_STDARG */
656 pSeekList = NULL;
657 ppSeekEntry = &pSeekList;
658 while( ( ( secID = va_arg( args, UINT32 ) ) != 0 ) &&
659 ( ( instanceID = va_arg( args, UINT32 ) ) != 0 ) )
660 {
661 *ppSeekEntry = (SEEK_ENTRY*)zalloc( sizeof( SEEK_ENTRY ) );
662 (*ppSeekEntry)->secID = secID;
663 (*ppSeekEntry)->instanceID = instanceID;
664 ppSeekEntry = &(*ppSeekEntry)->pNext;
665 }
666 va_end( args );
667
668 pMUD_start = (MUD_SEC*)pMUD_head;
669 pMUD = NULL;
670
671 for( pSeekEntry = pSeekList;
672 pSeekEntry != NULL;
673 pSeekEntry = pSeekEntry->pNext )
674 {
675 /*
676 * Search this level for the entry
677 */
678 for( pMUD = pMUD_start; pMUD != NULL; pMUD = pMUD->core.pNext )
679 if( ( MUD_secID( pMUD ) == pSeekEntry->secID ) &&
680 ( MUD_instanceID( pMUD ) == pSeekEntry->instanceID ) )
681 break;
682
683 if( pMUD == NULL )
684 {
685 /*
686 * Didn't find anything at this level - search failed
687 */
688 break;
689 }
690 else if( pSeekEntry->pNext == NULL )
691 {
692 /*
693 * Found section, search is finished
694 */
695 break;
696 }
697 else
698 {
699 /*
700 * Found section, search not finished
701 */
702 if( MUD_secID( pMUD ) == MUD_SEC_GRP_ID )
703 {
704 /*
705 * Search this group
706 */
707 pMUD_start = ((MUD_SEC_GRP*)pMUD)->pMem;
708 }
709 else
710 {
711 /*
712 * Section is not a group - search failed
713 */
714 pMUD = NULL;
715 break;
716 }
717 }
718 }
719
720 return( pMUD );
721}
722
723
724#ifdef NO_STDARG
725int
726MUD_fseek( va_alist )
727va_dcl
728#else
729int
730MUD_fseek( FILE* fio, ... )
731#endif /* NO_STDARG */
732{
733 va_list args;
734#ifdef NO_STDARG
735 FILE* fio;
736#endif /* NO_STDARG */
737 SEEK_ENTRY* pSeekList;
738 SEEK_ENTRY** ppSeekEntry;
739 SEEK_ENTRY* pSeekEntry;
740 MUD_SEC* pMUD;
741 MUD_SEC_GRP* pMUD_parent = NULL;
742 UINT32 secID;
743 UINT32 instanceID;
744 BOOL ateof = FALSE;
745
746 /*
747 * Assemble seek list from varargs
748 */
749#ifdef NO_STDARG
750 va_start( args );
751 fio = va_arg( args, FILE* );
752#else
753 va_start( args, fio );
754#endif /* NO_STDARG */
755
756 ppSeekEntry = &pSeekList;
757 while( ( ( secID = va_arg( args, UINT32 ) ) != 0 ) &&
758 ( ( instanceID = va_arg( args, UINT32 ) ) != 0 ) )
759 {
760 *ppSeekEntry = (SEEK_ENTRY*)zalloc( sizeof( SEEK_ENTRY ) );
761 (*ppSeekEntry)->secID = secID;
762 (*ppSeekEntry)->instanceID = instanceID;
763 ppSeekEntry = &(*ppSeekEntry)->pNext;
764 }
765 va_end( args );
766
767 for( pSeekEntry = pSeekList;
768 pSeekEntry != NULL;
769 pSeekEntry = pSeekEntry->pNext )
770 {
771 /*
772 * Search this level for the entry
773 */
774 pMUD = fseekNext( fio, pMUD_parent,
775 pSeekEntry->secID, pSeekEntry->instanceID );
776
777 MUD_free( (MUD_SEC*)pMUD_parent );
778
779 if( pMUD == NULL )
780 {
781 /*
782 * Didn't find anything at this level - search failed
783 */
784 break;
785 }
786 else if( pSeekEntry->pNext != NULL )
787 {
788 if( MUD_secID( pMUD ) == MUD_SEC_GRP_ID )
789 {
790 pMUD_parent = (MUD_SEC_GRP*)MUD_read( fio, MUD_ONE );
791 }
792 else if( MUD_secID( pMUD ) == MUD_SEC_EOF_ID )
793 {
794 ateof = TRUE;
795 break;
796 }
797 else
798 {
799 if( fseek( fio, MUD_size( pMUD ), 1 ) == EOF )
800 {
801 ateof = TRUE;
802 break;
803 }
804 }
805 }
806 }
807
808 if( ateof || ( pSeekEntry != NULL ) ) return( EOF );
809
810 return( ftell( fio ) );
811}
812
813
814MUD_SEC*
815fseekNext( FILE* fio, MUD_SEC_GRP* pMUD_parent,
816 UINT32 secID, UINT32 instanceID )
817{
818 MUD_SEC* pMUD;
819 MUD_INDEX* pMUD_index;
820 BOOL found = FALSE;
821 BOOL ateof = FALSE;
822
823 if( pMUD_parent != NULL )
824 {
825 for( pMUD_index = pMUD_parent->pMemIndex;
826 pMUD_index != NULL;
827 pMUD_index = pMUD_index->pNext )
828 {
829 if( ( pMUD_index->secID == secID ) &&
830 ( pMUD_index->instanceID == instanceID ) )
831 {
832 if( fseek( fio, pMUD_index->offset, 1 ) == EOF )
833 {
834 ateof = TRUE;
835 break;
836 }
837
838 pMUD = MUD_peekCore( fio );
839 if( pMUD == NULL )
840 {
841 ateof = TRUE;
842 break;
843 }
844 if( ( MUD_secID( pMUD ) == secID ) &&
845 ( MUD_instanceID( pMUD ) == instanceID ) )
846 found = TRUE;
847
848 break;
849 }
850 }
851 }
852 else
853 {
854 while( !found && !ateof )
855 {
856 pMUD = MUD_peekCore( fio );
857 if( pMUD == NULL )
858 {
859 ateof = TRUE;
860 break;
861 }
862 if( pMUD->core.secID == secID &&
863 pMUD->core.instanceID == instanceID )
864 {
865 found = TRUE;
866 }
867 else
868 {
869 if( ( MUD_secID( pMUD ) == MUD_SEC_EOF_ID ) || feof( fio ) )
870 ateof = TRUE;
871 else
872 if( fseek( fio, MUD_size( pMUD ), 1 ) == EOF )
873 ateof = TRUE;
874 }
875 }
876 }
877
878 if( ateof || !found ) return( NULL );
879 return( pMUD );
880}
881
882
883int
884MUD_fseekFirst( FILE* fio )
885{
886 int size;
887
888 size = MUD_CORE_proc( MUD_GET_SIZE, NULL, NULL ) +
890
891 if( fseek( fio, size, 0 ) == EOF ) return( EOF );
892
893 return( ftell( fio ) );
894}
895
896
897void
898MUD_add( void** ppMUD_head, void* pMUD_new )
899{
900 MUD_SEC** ppMUD;
901
902 if( pMUD_new == NULL ) return;
903
904 for( ppMUD = (MUD_SEC**)ppMUD_head;
905 *ppMUD != NULL;
906 ppMUD = &(*ppMUD)->core.pNext ) ;
907
908 *ppMUD = (MUD_SEC*)pMUD_new;
909}
910
911
912int
913MUD_totSize( void* pMUD )
914{
915 return( ( MUD_secID( pMUD ) == MUD_SEC_GRP_ID ) ?
916 MUD_size( pMUD ) + ((MUD_SEC_GRP*)pMUD)->memSize :
917 MUD_size( pMUD ) );
918}
919
920
921void
922MUD_addToGroup( MUD_SEC_GRP* pMUD_grp, void* pMUD )
923{
924 MUD_SEC** ppMUD;
925
926 if( pMUD == NULL ) return;
927
928 /* possible addition: ((MUD_SEC*)pMUD)->core.pNext = NULL; */
929 ((MUD_SEC*)pMUD)->core.size = MUD_getSize( pMUD );
930
931 for( ppMUD = &pMUD_grp->pMem;
932 *ppMUD != NULL;
933 ppMUD = &(*ppMUD)->core.pNext ) ;
934
935 *ppMUD = (MUD_SEC*)pMUD;
936
937 addIndex( pMUD_grp, pMUD );
938 pMUD_grp->num++;
939 pMUD_grp->memSize += MUD_totSize( pMUD );
940}
941
942
943void
945{
946 bcopy( &pMUD1->core.size, &pMUD2->core.size,
948}
949
950
951int
952MUD_CORE_proc( MUD_OPT op, BUF* pBuf, MUD_SEC* pMUD )
953{
954 int size;
955
956 switch( op )
957 {
958 case MUD_FREE:
959 break;
960 case MUD_DECODE:
961 decode_4( pBuf, &pMUD->core.size );
962 decode_4( pBuf, &pMUD->core.secID );
963 decode_4( pBuf, &pMUD->core.instanceID );
964 break;
965 case MUD_ENCODE:
966 encode_4( pBuf, &pMUD->core.size );
967 encode_4( pBuf, &pMUD->core.secID );
968 encode_4( pBuf, &pMUD->core.instanceID );
969 break;
970 case MUD_GET_SIZE:
971 size = 3*sizeof(UINT32);
972#ifdef DEBUG
973 printf("MUD_CORE_proc: MUD_GET_SIZE returns size=%d\n",size);
974#endif /* DEBUG */
975 return( size );
976 case MUD_SHOW:
977 printf( " CORE: size=[%lu], secID=[0x%08lX], instanceID=[0x%08lX]\n",
978 (unsigned long)(pMUD->core.size), (unsigned long)(pMUD->core.secID),
979 (unsigned long)(pMUD->core.instanceID) );
980 break;
981 case MUD_HEADS:
982 break;
983 }
984 return( 1 );
985}
986
987
988int
990{
991 int size;
992
993 switch( op )
994 {
995 case MUD_FREE:
996 if( pMUD != NULL )
997 {
998 if( pMUD->pNext != NULL )
1000 free( pMUD );
1001 }
1002 break;
1003 case MUD_DECODE:
1004 decode_4( pBuf, &pMUD->offset );
1005 decode_4( pBuf, &pMUD->secID );
1006 decode_4( pBuf, &pMUD->instanceID );
1007 break;
1008 case MUD_ENCODE:
1009 encode_4( pBuf, &pMUD->offset );
1010 encode_4( pBuf, &pMUD->secID );
1011 encode_4( pBuf, &pMUD->instanceID );
1012 break;
1013 case MUD_GET_SIZE:
1014 size = 3*sizeof(UINT32);
1015 return( size );
1016 case MUD_SHOW:
1017 printf( " INDEX: offset=[%lu], secID=[0x%08lX], instanceID=[0x%08lX]\n",
1018 (unsigned long)(pMUD->offset), (unsigned long)(pMUD->secID),
1019 (unsigned long)(pMUD->instanceID) );
1020 break;
1021 case MUD_HEADS:
1022 break;
1023 }
1024 return( 1 );
1025}
1026
1027
void * MUD_read(FILE *fin, MUD_IO_OPT io_opt)
Definition mud.c:407
int MUD_getSize(void *pMUD)
Definition mud.c:194
int MUD_CORE_proc(MUD_OPT op, BUF *pBuf, MUD_SEC *pMUD)
Definition mud.c:952
void MUD_show(void *pMUD, MUD_IO_OPT io_opt)
Definition mud.c:202
void * MUD_readFile(FILE *fin)
Definition mud.c:398
BOOL MUD_writeGrpMem(FILE *fout, MUD_SEC_GRP *pMUD_grp, void *pMUD)
Definition mud.c:351
BOOL MUD_writeGrpStart(FILE *fout, MUD_SEC_GRP *pMUD_parentGrp, MUD_SEC_GRP *pMUD_grp, int numMems)
Definition mud.c:312
int MUD_totSize(void *pMUD)
Definition mud.c:913
BOOL MUD_encode(BUF *pBuf, void *pMUD, MUD_IO_OPT io_opt)
Definition mud.c:100
void MUD_assignCore(MUD_SEC *pMUD1, MUD_SEC *pMUD2)
Definition mud.c:944
int MUD_INDEX_proc(MUD_OPT op, BUF *pBuf, MUD_INDEX *pMUD)
Definition mud.c:989
FILE * MUD_openInput(char *inFile)
Definition mud.c:41
MUD_SEC * fseekNext(FILE *fio, MUD_SEC_GRP *pMUD_parent, UINT32 secID, UINT32 instanceID)
Definition mud.c:815
BOOL MUD_write(FILE *fout, void *pMUD, MUD_IO_OPT io_opt)
Definition mud.c:283
int MUD_fseekFirst(FILE *fio)
Definition mud.c:884
FILE * MUD_openOutput(char *outFile)
Definition mud.c:69
void MUD_addToGroup(MUD_SEC_GRP *pMUD_grp, void *pMUD)
Definition mud.c:922
FILE * MUD_openInOut(char *inFile)
Definition mud.c:55
int MUD_fseek(va_alist)
Definition mud.c:726
void MUD_heads(void *pMUD, MUD_IO_OPT io_opt)
Definition mud.c:225
BOOL MUD_writeGrpEnd(FILE *fout, MUD_SEC_GRP *pMUD_grp)
Definition mud.c:376
BOOL MUD_writeEnd(FILE *fout)
Definition mud.c:250
MUD_SEC * MUD_peekCore(FILE *fin)
Definition mud.c:593
void MUD_add(void **ppMUD_head, void *pMUD_new)
Definition mud.c:898
UINT32 MUD_setSizes(void *pMUD)
Definition mud.c:542
void * MUD_decode(BUF *pBuf)
Definition mud.c:151
void MUD_free(void *pMUD)
Definition mud.c:83
void addIndex(MUD_SEC_GRP *pMUD_grp, void *pMUD)
Definition mud.c:332
void * MUD_search(va_alist)
Definition mud.c:628
BOOL MUD_writeFile(FILE *fout, void *pMUD_head)
Definition mud.c:271
#define NULL
Definition mud.h:167
unsigned long UINT32
Definition mud.h:146
struct _SEEK_ENTRY SEEK_ENTRY
#define MUD_secID(pM)
Definition mud.h:426
#define zalloc(n)
Definition mud.h:201
#define MUD_size(pM)
Definition mud.h:425
MUD_OPT
Definition mud.h:207
@ MUD_FREE
Definition mud.h:210
@ MUD_ENCODE
Definition mud.h:208
@ MUD_HEADS
Definition mud.h:213
@ MUD_SHOW
Definition mud.h:212
@ MUD_GET_SIZE
Definition mud.h:211
@ MUD_DECODE
Definition mud.h:209
struct _MUD_SEC_GRP MUD_SEC_GRP
struct _MUD_SEC MUD_SEC
#define MUD_SEC_GRP_ID
Definition mud.h:65
#define encode_4(b, p)
Definition mud.h:456
#define MUD_SEC_EOF_ID
Definition mud.h:66
#define _free(objp)
Definition mud.h:198
#define decode_4(b, p)
Definition mud.h:454
struct _MUD_INDEX MUD_INDEX
#define TRUE
Definition mud.h:164
#define FALSE
Definition mud.h:161
UINT32 BOOL
Definition mud.h:157
MUD_IO_OPT
Definition mud.h:218
@ MUD_ALL
Definition mud.h:220
@ MUD_GRP
Definition mud.h:221
@ MUD_ONE
Definition mud.h:219
#define MUD_instanceID(pM)
Definition mud.h:427
int MUD_SEC_FIXED_proc(MUD_OPT op, BUF *pBuf, MUD_SEC_FIXED *pMUD)
Definition mud_all.c:76
void bdecode_4(void *b, void *p)
Definition mud_encode.c:60
MUD_SEC * MUD_new(UINT32 secID, UINT32 instanceID)
Definition mud_new.c:34
Definition mud.h:253
unsigned int size
Definition mud.h:256
int pos
Definition mud.h:255
caddr_t buf
Definition mud.h:254
struct _MUD_SEC * pNext
Definition mud.h:226
UINT32 secID
Definition mud.h:228
UINT32 instanceID
Definition mud.h:229
UINT32 size
Definition mud.h:227
MUD_PROC proc
Definition mud.h:231
struct _MUD_INDEX * pNext
Definition mud.h:236
UINT32 secID
Definition mud.h:238
UINT32 instanceID
Definition mud.h:239
UINT32 offset
Definition mud.h:237
MUD_SEC * pMem
Definition mud.h:286
INT32 pos
Definition mud.h:287
MUD_CORE core
Definition mud.h:281
MUD_INDEX * pMemIndex
Definition mud.h:285
UINT32 num
Definition mud.h:283
struct _MUD_SEC_GRP * pParent
Definition mud.h:288
UINT32 memSize
Definition mud.h:284
MUD_CORE core
Definition mud.h:261
UINT32 secID
Definition mud.h:245
struct _SEEK_ENTRY * pNext
Definition mud.h:244
UINT32 instanceID
Definition mud.h:246