1 /******************************************************************
2 Copyright 1993, 1994 by Digital Equipment Corporation, Maynard, Massachusetts,
3
4 All Rights Reserved
5
6 Permission to use, copy, modify, and distribute this software and its
7 documentation for any purpose and without fee is hereby granted,
8 provided that the above copyright notice appear in all copies and that
9 both that copyright notice and this permission notice appear in
10 supporting documentation, and that the names of Digital or MIT not be
11 used in advertising or publicity pertaining to distribution of the
12 software without specific, written prior permission.
13
14 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20 SOFTWARE.
21
22 Author: Hiroyuki Miyamoto Digital Equipment Corporation
23 miyamoto@jrd.dec.com
24
25 This version tidied and debugged by Steve Underwood May 1999
26
27 ******************************************************************/
28
29 #include <X11/Xlibint.h>
30 #include <stdlib.h>
31 #include "FrameMgr.h"
32
33 /* Convenient macro */
34
35 #define _UNIT(n) ((int)(n) & 0xFF)
36 #define _NUMBER(n) (((int)(n) >> 8) & 0xFF)
37
38 /* For byte swapping */
39
40 #define Swap16(p, n) ((p)->byte_swap ? \
41 (((n) << 8 & 0xFF00) | \
42 ((n) >> 8 & 0xFF) \
43 ) : n)
44 #define Swap32(p, n) ((p)->byte_swap ? \
45 (((n) << 24 & 0xFF000000) | \
46 ((n) << 8 & 0xFF0000) | \
47 ((n) >> 8 & 0xFF00) | \
48 ((n) >> 24 & 0xFF) \
49 ) : n)
50 #define Swap64(p, n) ((p)->byte_swap ? \
51 (((n) << 56 & 0xFF00000000000000) | \
52 ((n) << 40 & 0xFF000000000000) | \
53 ((n) << 24 & 0xFF0000000000) | \
54 ((n) << 8 & 0xFF00000000) | \
55 ((n) >> 8 & 0xFF000000) | \
56 ((n) >> 24 & 0xFF0000) | \
57 ((n) >> 40 & 0xFF00) | \
58 ((n) >> 56 & 0xFF) \
59 ) : n)
60
61 /* Type definition */
62
63 typedef struct _Iter *Iter;
64
65 typedef struct _FrameInst *FrameInst;
66
67 typedef union
68 {
69 int num; /* For BARRAY */
70 FrameInst fi; /* For POINTER */
71 Iter iter; /* For ITER */
72 } ExtraDataRec, *ExtraData;
73
74 typedef struct _Chain
75 {
76 ExtraDataRec d;
77 int frame_no;
78 struct _Chain *next;
79 } ChainRec, *Chain;
80
81 typedef struct _ChainMgr
82 {
83 Chain top;
84 Chain tail;
85 } ChainMgrRec, *ChainMgr;
86
87 typedef struct _ChainIter
88 {
89 Chain cur;
90 } ChainIterRec, *ChainIter;
91
92 typedef struct _FrameIter
93 {
94 Iter iter;
95 Bool counting;
96 unsigned int counter;
97 int end;
98 struct _FrameIter* next;
99 } FrameIterRec, *FrameIter;
100
101 typedef struct _FrameInst
102 {
103 XimFrame template;
104 ChainMgrRec cm;
105 int cur_no;
106 } FrameInstRec;
107
108 typedef void (*IterStartWatchProc) (Iter it, void *client_data);
109
110 typedef struct _Iter
111 {
112 XimFrame template;
113 int max_count;
114 Bool allow_expansion;
115 ChainMgrRec cm;
116 int cur_no;
117 IterStartWatchProc start_watch_proc;
118 void *client_data;
119 Bool start_counter;
120 } IterRec;
121
122 typedef struct _FrameMgr
123 {
124 XimFrame frame;
125 FrameInst fi;
126 char *area;
127 int idx;
128 Bool byte_swap;
129 int total_size;
130 FrameIter iters;
131 } FrameMgrRec;
132
133 typedef union
134 {
135 int num; /* For BARRAY and PAD */
136 struct
137 { /* For COUNTER_* */
138 Iter iter;
139 Bool is_byte_len;
140 } counter;
141 } XimFrameTypeInfoRec, *XimFrameTypeInfo;
142
143 /* Special values */
144 #define NO_VALUE -1
145 #define NO_VALID_FIELD -2
146
147 static FrameInst FrameInstInit(XimFrame frame);
148 static void FrameInstFree(FrameInst fi);
149 static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info);
150 static XimFrameType FrameInstPeekNextType(FrameInst fi, XimFrameTypeInfo info);
151 static FmStatus FrameInstSetSize(FrameInst fi, int num);
152 static FmStatus FrameInstSetIterCount(FrameInst fi, int num);
153 static int FrameInstGetTotalSize(FrameInst fi);
154 static void FrameInstReset(FrameInst fi);
155
156 static Iter IterInit(XimFrame frame, int count);
157 static void IterFree(Iter it);
158 static int FrameInstGetSize(FrameInst fi);
159 static int IterGetSize(Iter it);
160 static XimFrameType IterGetNextType(Iter it, XimFrameTypeInfo info);
161 static XimFrameType IterPeekNextType(Iter it, XimFrameTypeInfo info);
162 static FmStatus IterSetSize(Iter it, int num);
163 static FmStatus IterSetIterCount(Iter it, int num);
164 static int IterGetTotalSize(Iter it);
165 static void IterReset(Iter it);
166 static Bool IterIsLoopEnd(Iter it, Bool* myself);
167 static void IterSetStartWatch(Iter it, IterStartWatchProc proc, void* client_data);
168 static void _IterStartWatch(Iter it, void* client_data);
169
170 static ExtraData ChainMgrGetExtraData(ChainMgr cm, int frame_no);
171 static ExtraData ChainMgrSetData(ChainMgr cm, int frame_no,
172 ExtraDataRec data);
173 static Bool ChainIterGetNext(ChainIter ci, int* frame_no, ExtraData d);
174 static int _FrameInstIncrement(XimFrame frame, int count);
175 static int _FrameInstDecrement(XimFrame frame, int count);
176 static int _FrameInstGetItemSize(FrameInst fi, int cur_no);
177 static Bool FrameInstIsIterLoopEnd(FrameInst fi);
178
179 static FrameIter _FrameMgrAppendIter(FrameMgr fm, Iter it, int end);
180 static FrameIter _FrameIterCounterIncr(FrameIter fitr, int i);
181 static void _FrameMgrRemoveIter(FrameMgr fm, FrameIter it);
182 static Bool _FrameMgrIsIterLoopEnd(FrameMgr fm);
183 static Bool _FrameMgrProcessPadding(FrameMgr fm, FmStatus* status);
184
185 #define IterGetIterCount(it) ((it)->allow_expansion ? \
186 NO_VALUE : (it)->max_count)
187
188 #define IterFixIteration(it) ((it)->allow_expansion = False)
189
190 #define IterSetStarter(it) ((it)->start_counter = True)
191
192 #define ChainMgrInit(cm) (cm)->top = (cm)->tail = NULL
193 #define ChainMgrFree(cm) \
194 { \
195 Chain tmp; \
196 Chain cur = (cm)->top; \
197 \
198 while (cur) \
199 { \
200 tmp = cur->next; \
201 Xfree (cur); \
202 cur = tmp; \
203 } \
204 }
205
206 #define ChainIterInit(ci, cm) \
207 { \
208 (ci)->cur = (cm)->top; \
209 }
210
211 /* ChainIterFree has nothing to do. */
212 #define ChainIterFree(ci)
213
214 #define FrameInstIsEnd(fi) ((fi)->template[(fi)->cur_no].type == EOL)
215
FrameMgrInit(XimFrame frame,char * area,Bool byte_swap)216 FrameMgr FrameMgrInit (XimFrame frame, char* area, Bool byte_swap)
217 {
218 FrameMgr fm;
219
220 fm = (FrameMgr) Xmalloc (sizeof (FrameMgrRec));
221
222 fm->frame = frame;
223 fm->fi = FrameInstInit (frame);
224 fm->area = (char *) area;
225 fm->idx = 0;
226 fm->byte_swap = byte_swap;
227 fm->total_size = NO_VALUE;
228 fm->iters = NULL;
229
230 return fm;
231 }
232
FrameMgrInitWithData(FrameMgr fm,XimFrame frame,void * area,Bool byte_swap)233 void FrameMgrInitWithData (FrameMgr fm,
234 XimFrame frame,
235 void * area,
236 Bool byte_swap)
237 {
238 fm->frame = frame;
239 fm->fi = FrameInstInit (frame);
240 fm->area = (char *) area;
241 fm->idx = 0;
242 fm->byte_swap = byte_swap;
243 fm->total_size = NO_VALUE;
244 }
245
FrameMgrFree(FrameMgr fm)246 void FrameMgrFree (FrameMgr fm)
247 {
248 FrameIter p, cur;
249
250 p = fm->iters;
251 cur = p;
252 while (p != NULL) {
253 p = p->next;
254 Xfree(cur);
255 cur = p;
256 }
257
258 FrameInstFree (fm->fi);
259 Xfree (fm);
260 }
261
FrameMgrSetBuffer(FrameMgr fm,void * area)262 FmStatus FrameMgrSetBuffer (FrameMgr fm, void* area)
263 {
264 if (fm->area)
265 return FmBufExist;
266 fm->area = (char *) area;
267 return FmSuccess;
268 }
269
_FrameMgrPutToken(FrameMgr fm,void * data,int data_size)270 FmStatus _FrameMgrPutToken (FrameMgr fm, void *data, int data_size)
271 {
272 XimFrameType type;
273 XimFrameTypeInfoRec info;
274
275 if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size)
276 return FmNoMoreData;
277 /*endif*/
278
279 type = FrameInstGetNextType(fm->fi, &info);
280
281 if (type & COUNTER_MASK)
282 {
283 unsigned long input_length;
284
285 if (info.counter.is_byte_len)
286 {
287 if ((input_length = IterGetTotalSize (info.counter.iter))
288 == NO_VALUE)
289 {
290 return FmCannotCalc;
291 }
292 /*endif*/
293 }
294 else
295 {
296 if ((input_length = IterGetIterCount (info.counter.iter))
297 == NO_VALUE)
298 {
299 return FmCannotCalc;
300 }
301 /*endif*/
302 }
303 /*endif*/
304 switch (type)
305 {
306 case COUNTER_BIT8:
307 *(CARD8 *) (fm->area + fm->idx) = input_length;
308 fm->idx++;
309 break;
310
311 case COUNTER_BIT16:
312 *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, input_length);
313 fm->idx += 2;
314 break;
315
316 case COUNTER_BIT32:
317 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, input_length);
318 fm->idx += 4;
319 break;
320
321 #if defined(_NEED64BIT)
322 case COUNTER_BIT64:
323 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, input_length);
324 fm->idx += 8;
325 break;
326 #endif
327 default:
328 break;
329 }
330 /*endswitch*/
331 _FrameMgrPutToken(fm, data, data_size);
332 return FmSuccess;
333 }
334 /*endif*/
335
336 switch (type)
337 {
338 case BIT8:
339 if (data_size == sizeof (unsigned char))
340 {
341 unsigned long num = *(unsigned char *) data;
342 *(CARD8 *) (fm->area + fm->idx) = num;
343 }
344 else if (data_size == sizeof (unsigned short))
345 {
346 unsigned long num = *(unsigned short *) data;
347 *(CARD8 *) (fm->area + fm->idx) = num;
348 }
349 else if (data_size == sizeof (unsigned int))
350 {
351 unsigned long num = *(unsigned int *) data;
352 *(CARD8 *) (fm->area + fm->idx) = num;
353 }
354 else if (data_size == sizeof (unsigned long))
355 {
356 unsigned long num = *(unsigned long *) data;
357 *(CARD8 *) (fm->area + fm->idx) = num;
358 }
359 else
360 {
361 ; /* Should never be reached */
362 }
363 /*endif*/
364 fm->idx++;
365 return FmSuccess;
366
367 case BIT16:
368 if (data_size == sizeof (unsigned char))
369 {
370 unsigned long num = *(unsigned char *) data;
371 *(CARD16*)(fm->area + fm->idx) = Swap16 (fm, num);
372 }
373 else if (data_size == sizeof (unsigned short))
374 {
375 unsigned long num = *(unsigned short *) data;
376 *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num);
377 }
378 else if (data_size == sizeof (unsigned int))
379 {
380 unsigned long num = *(unsigned int *) data;
381 *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num);
382 }
383 else if (data_size == sizeof (unsigned long))
384 {
385 unsigned long num = *(unsigned long *) data;
386 *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num);
387 }
388 else
389 {
390 ; /* Should never reached */
391 }
392 /*endif*/
393 fm->idx += 2;
394 return FmSuccess;
395
396 case BIT32:
397 if (data_size == sizeof (unsigned char))
398 {
399 unsigned long num = *(unsigned char *) data;
400 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num);
401 }
402 else if (data_size == sizeof (unsigned short))
403 {
404 unsigned long num = *(unsigned short *) data;
405 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num);
406 }
407 else if (data_size == sizeof (unsigned int))
408 {
409 unsigned long num = *(unsigned int *) data;
410 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num);
411 }
412 else if (data_size == sizeof (unsigned long))
413 {
414 unsigned long num = *(unsigned long *) data;
415 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num);
416 }
417 else
418 {
419 ; /* Should never reached */
420 }
421 /*endif*/
422 fm->idx += 4;
423 return FmSuccess;
424
425 #if defined(_NEED64BIT)
426 case BIT64:
427 if (data_size == sizeof (unsigned char))
428 {
429 unsigned long num = *(unsigned char *) data;
430 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num);
431 }
432 else if (data_size == sizeof (unsigned short))
433 {
434 unsigned long num = *(unsigned short *) data;
435 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num);
436 }
437 else if (data_size == sizeof (unsigned int))
438 {
439 unsigned long num = *(unsigned int *) data;
440 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num);
441 }
442 else if (data_size == sizeof (unsigned long))
443 {
444 unsigned long num = *(unsigned long *) data;
445 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num);
446 }
447 else
448 {
449 ; /* Should never reached */
450 }
451 /*endif*/
452 fm->idx += 4;
453 return FmSuccess;
454 #endif
455
456 case BARRAY:
457 if (info.num == NO_VALUE)
458 return FmInvalidCall;
459 /*endif*/
460 if (info.num > 0)
461 {
462 bcopy (*(char **) data, fm->area + fm->idx, info.num);
463 fm->idx += info.num;
464 }
465 /*endif*/
466 return FmSuccess;
467
468 case PADDING:
469 if (info.num == NO_VALUE)
470 return FmInvalidCall;
471 /*endif*/
472 fm->idx += info.num;
473 return _FrameMgrPutToken(fm, data, data_size);
474
475 case ITER:
476 return FmInvalidCall;
477
478 case EOL:
479 return FmEOD;
480 default:
481 break;
482 }
483 /*endswitch*/
484 return (FmStatus) NULL; /* Should never be reached */
485 }
486
_FrameMgrGetToken(FrameMgr fm,void * data,int data_size)487 FmStatus _FrameMgrGetToken (FrameMgr fm , void* data, int data_size)
488 {
489 XimFrameType type;
490 static XimFrameTypeInfoRec info; /* memory */
491 FrameIter fitr;
492
493 if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size)
494 return FmNoMoreData;
495 /*endif*/
496
497 type = FrameInstGetNextType(fm->fi, &info);
498
499 if (type & COUNTER_MASK)
500 {
501 int end=0;
502 FrameIter client_data;
503
504 type &= ~COUNTER_MASK;
505 switch (type)
506 {
507 case BIT8:
508 end = *(CARD8 *) (fm->area + fm->idx);
509 break;
510
511 case BIT16:
512 end = Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
513 break;
514
515 case BIT32:
516 end = Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
517 break;
518
519 #if defined(_NEED64BIT)
520 case BIT64:
521 end = Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
522 break;
523 #endif
524 default:
525 break;
526 }
527 /*endswitch*/
528
529 if ((client_data = _FrameMgrAppendIter (fm, info.counter.iter, end)))
530 {
531 IterSetStarter (info.counter.iter);
532 IterSetStartWatch (info.counter.iter,
533 _IterStartWatch,
534 (void *) client_data);
535 }
536 /*endif*/
537 }
538 /*endif*/
539
540 type &= ~COUNTER_MASK;
541 switch (type)
542 {
543 case BIT8:
544 if (data_size == sizeof (unsigned char))
545 {
546 *(unsigned char*) data = *(CARD8 *) (fm->area + fm->idx);
547 }
548 else if (data_size == sizeof (unsigned short))
549 {
550 *(unsigned short *) data = *(CARD8 *) (fm->area + fm->idx);
551 }
552 else if (data_size == sizeof (unsigned int))
553 {
554 *(unsigned int *) data = *(CARD8 *) (fm->area + fm->idx);
555 }
556 else if (data_size == sizeof (unsigned long))
557 {
558 *(unsigned long *) data = *(CARD8 *) (fm->area + fm->idx);
559 }
560 else
561 {
562 ; /* Should never reached */
563 }
564 /*endif*/
565 fm->idx++;
566 if ((fitr = _FrameIterCounterIncr (fm->iters, 1/*BIT8*/)))
567 _FrameMgrRemoveIter (fm, fitr);
568 /*endif*/
569 return FmSuccess;
570
571 case BIT16:
572 if (data_size == sizeof (unsigned char))
573 {
574 *(unsigned char *) data =
575 Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
576 }
577 else if (data_size == sizeof (unsigned short))
578 {
579 *(unsigned short *) data =
580 Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
581 }
582 else if (data_size == sizeof (unsigned int))
583 {
584 *(unsigned int *) data =
585 Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
586 }
587 else if (data_size == sizeof (unsigned long))
588 {
589 *(unsigned long *) data =
590 Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
591 }
592 else
593 {
594 ; /* Should never reached */
595 }
596 /*endif*/
597 fm->idx += 2;
598 if ((fitr = _FrameIterCounterIncr (fm->iters, 2/*BIT16*/)))
599 _FrameMgrRemoveIter(fm, fitr);
600 /*endif*/
601 return FmSuccess;
602
603 case BIT32:
604 if (data_size == sizeof (unsigned char))
605 {
606 *(unsigned char *) data =
607 Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
608 }
609 else if (data_size == sizeof (unsigned short))
610 {
611 *(unsigned short *) data =
612 Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
613 }
614 else if (data_size == sizeof (unsigned int))
615 {
616 *(unsigned int *) data =
617 Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
618 }
619 else if (data_size == sizeof (unsigned long))
620 {
621 *(unsigned long *) data =
622 Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
623 }
624 else
625 {
626 ; /* Should never reached */
627 }
628 /*endif*/
629 fm->idx += 4;
630 if ((fitr = _FrameIterCounterIncr (fm->iters, 4/*BIT32*/)))
631 _FrameMgrRemoveIter (fm, fitr);
632 /*endif*/
633 return FmSuccess;
634
635 #if defined(_NEED64BIT)
636 case BIT64:
637 if (data_size == sizeof (unsigned char))
638 {
639 *(unsigned char *) data =
640 Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
641 }
642 else if (data_size == sizeof (unsigned short))
643 {
644 *(unsigned short *) data =
645 Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
646 }
647 else if (data_size == sizeof (unsigned int))
648 {
649 *(unsigned int *) data =
650 Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
651 }
652 else if (data_size == sizeof (unsigned long))
653 {
654 *(unsigned long *) data =
655 Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
656 }
657 else
658 {
659 ; /* Should never reached */
660 }
661 /*endif*/
662 fm->idx += 8;
663 if ((fitr = _FrameIterCounterIncr (fm->iters, 8/*BIT64*/)))
664 _FrameMgrRemoveIter (fm, fitr);
665 /*endif*/
666 return FmSuccess;
667 #endif
668
669 case BARRAY:
670 if (info.num == NO_VALUE)
671 return FmInvalidCall;
672 /*endif*/
673 if (info.num > 0)
674 {
675 *(char **) data = fm->area + fm->idx;
676
677 fm->idx += info.num;
678 if ((fitr = _FrameIterCounterIncr (fm->iters, info.num)))
679 _FrameMgrRemoveIter (fm, fitr);
680 /*endif*/
681 }
682 else
683 {
684 *(char **) data = NULL;
685 }
686 /*endif*/
687 return FmSuccess;
688
689 case PADDING:
690 if (info.num == NO_VALUE)
691 return FmInvalidCall;
692 /*endif*/
693 fm->idx += info.num;
694 if ((fitr = _FrameIterCounterIncr (fm->iters, info.num)))
695 _FrameMgrRemoveIter (fm, fitr);
696 /*endif*/
697 return _FrameMgrGetToken (fm, data, data_size);
698
699 case ITER:
700 return FmInvalidCall; /* if comes here, it's a bug! */
701
702 case EOL:
703 return FmEOD;
704 default:
705 break;
706 }
707 /*endswitch*/
708 return (FmStatus) NULL; /* Should never be reached */
709 }
710
FrameMgrSetSize(FrameMgr fm,int barray_size)711 FmStatus FrameMgrSetSize (FrameMgr fm, int barray_size)
712 {
713 if (FrameInstSetSize (fm->fi, barray_size) == FmSuccess)
714 return FmSuccess;
715 /*endif*/
716 return FmNoMoreData;
717 }
718
FrameMgrSetIterCount(FrameMgr fm,int count)719 FmStatus FrameMgrSetIterCount (FrameMgr fm, int count)
720 {
721 if (FrameInstSetIterCount (fm->fi, count) == FmSuccess)
722 return FmSuccess;
723 /*endif*/
724 return FmNoMoreData;
725 }
726
FrameMgrSetTotalSize(FrameMgr fm,int total_size)727 FmStatus FrameMgrSetTotalSize (FrameMgr fm, int total_size)
728 {
729 fm->total_size = total_size;
730 return FmSuccess;
731 }
732
FrameMgrGetTotalSize(FrameMgr fm)733 int FrameMgrGetTotalSize (FrameMgr fm)
734 {
735 return FrameInstGetTotalSize (fm->fi);
736 }
737
FrameMgrGetSize(FrameMgr fm)738 int FrameMgrGetSize (FrameMgr fm)
739 {
740 register int ret_size;
741
742 ret_size = FrameInstGetSize (fm->fi);
743 if (ret_size == NO_VALID_FIELD)
744 return NO_VALUE;
745 /*endif*/
746 return ret_size;
747 }
748
FrameMgrSkipToken(FrameMgr fm,int skip_count)749 FmStatus FrameMgrSkipToken (FrameMgr fm, int skip_count)
750 {
751 XimFrameType type;
752 XimFrameTypeInfoRec info;
753 register int i;
754
755 if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size)
756 return FmNoMoreData;
757 /*endif*/
758 for (i = 0; i < skip_count; i++)
759 {
760 type = FrameInstGetNextType (fm->fi, &info);
761 type &= ~COUNTER_MASK;
762
763 switch (type)
764 {
765 case BIT8:
766 fm->idx++;
767 break;
768
769 case BIT16:
770 fm->idx += 2;
771 break;
772
773 case BIT32:
774 fm->idx += 4;
775 break;
776
777 case BIT64:
778 fm->idx += 8;
779 break;
780
781 case BARRAY:
782 if (info.num == NO_VALUE)
783 return FmInvalidCall;
784 /*endif*/
785 fm->idx += info.num;
786 break;
787
788 case PADDING:
789 if (info.num == NO_VALUE)
790 return FmInvalidCall;
791 /*endif*/
792 fm->idx += info.num;
793 return FrameMgrSkipToken (fm, skip_count);
794
795 case ITER:
796 return FmInvalidCall;
797
798 case EOL:
799 return FmEOD;
800 default:
801 break;
802 }
803 /*endswitch*/
804 }
805 /*endfor*/
806 return FmSuccess;
807 }
808
FrameMgrReset(FrameMgr fm)809 void FrameMgrReset (FrameMgr fm)
810 {
811 fm->idx = 0;
812 FrameInstReset (fm->fi);
813 }
814
FrameMgrIsIterLoopEnd(FrameMgr fm,FmStatus * status)815 Bool FrameMgrIsIterLoopEnd (FrameMgr fm, FmStatus* status)
816 {
817 do
818 {
819 if (_FrameMgrIsIterLoopEnd (fm))
820 return True;
821 /*endif*/
822 }
823 while (_FrameMgrProcessPadding (fm, status));
824
825 return False;
826 }
827
828
829 /* Internal routines */
830
_FrameMgrIsIterLoopEnd(FrameMgr fm)831 static Bool _FrameMgrIsIterLoopEnd (FrameMgr fm)
832 {
833 return FrameInstIsIterLoopEnd (fm->fi);
834 }
835
_FrameMgrProcessPadding(FrameMgr fm,FmStatus * status)836 static Bool _FrameMgrProcessPadding (FrameMgr fm, FmStatus* status)
837 {
838 XimFrameTypeInfoRec info;
839 XimFrameType next_type = FrameInstPeekNextType (fm->fi, &info);
840 FrameIter fitr;
841
842 if (next_type == PADDING)
843 {
844 if (info.num == NO_VALUE)
845 {
846 *status = FmInvalidCall;
847 return True;
848 }
849 /*endif*/
850 next_type = FrameInstGetNextType (fm->fi, &info);
851 fm->idx += info.num;
852 if ((fitr = _FrameIterCounterIncr (fm->iters, info.num)))
853 _FrameMgrRemoveIter (fm, fitr);
854 /*endif*/
855 *status = FmSuccess;
856 return True;
857 }
858 /*endif*/
859 *status = FmSuccess;
860 return False;
861 }
862
FrameInstInit(XimFrame frame)863 static FrameInst FrameInstInit (XimFrame frame)
864 {
865 FrameInst fi;
866
867 fi = (FrameInst) Xmalloc (sizeof (FrameInstRec));
868
869 fi->template = frame;
870 fi->cur_no = 0;
871 ChainMgrInit (&fi->cm);
872 return fi;
873 }
874
FrameInstFree(FrameInst fi)875 static void FrameInstFree (FrameInst fi)
876 {
877 ChainIterRec ci;
878 int frame_no;
879 ExtraDataRec d;
880
881 ChainIterInit (&ci, &fi->cm);
882
883 while (ChainIterGetNext (&ci, &frame_no, &d))
884 {
885 register XimFrameType type;
886 type = fi->template[frame_no].type;
887 if (type == ITER)
888 {
889 if (d.iter)
890 IterFree (d.iter);
891 /*endif*/
892 }
893 else if (type == POINTER)
894 {
895 if (d.fi)
896 FrameInstFree (d.fi);
897 /*endif*/
898 }
899 /*endif*/
900 }
901 /*endwhile*/
902 ChainIterFree (&ci);
903 ChainMgrFree (&fi->cm);
904 Xfree (fi);
905 }
906
FrameInstGetNextType(FrameInst fi,XimFrameTypeInfo info)907 static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info)
908 {
909 XimFrameType ret_type;
910
911 ret_type = fi->template[fi->cur_no].type;
912
913 switch (ret_type)
914 {
915 case BIT8:
916 case BIT16:
917 case BIT32:
918 case BIT64:
919 case EOL:
920 fi->cur_no = _FrameInstIncrement(fi->template, fi->cur_no);
921 break;
922
923 case COUNTER_BIT8:
924 case COUNTER_BIT16:
925 case COUNTER_BIT32:
926 case COUNTER_BIT64:
927 if (info)
928 {
929 register int offset, iter_idx;
930
931 info->counter.is_byte_len =
932 (((long) fi->template[fi->cur_no].data & 0xFF)) == FmCounterByte;
933 offset = ((long) fi->template[fi->cur_no].data) >> 8;
934 iter_idx = fi->cur_no + offset;
935 if (fi->template[iter_idx].type == ITER)
936 {
937 ExtraData d;
938 ExtraDataRec dr;
939
940 if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL)
941 {
942 dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE);
943 d = ChainMgrSetData (&fi->cm, iter_idx, dr);
944 }
945 /*endif*/
946 info->counter.iter = d->iter;
947 }
948 else
949 {
950 /* Should never reach here */
951 }
952 /*endif*/
953 }
954 /*endif*/
955 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
956 break;
957
958 case BARRAY:
959 if (info)
960 {
961 ExtraData d;
962
963 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
964 info->num = NO_VALUE;
965 else
966 info->num = d->num;
967 /*endif*/
968 }
969 /*endif*/
970 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
971 break;
972
973 case PADDING:
974 if (info)
975 {
976 register int unit;
977 register int number;
978 register int size;
979 register int i;
980
981 unit = _UNIT ((long) fi->template[fi->cur_no].data);
982 number = _NUMBER ((long) fi->template[fi->cur_no].data);
983
984 i = fi->cur_no;
985 size = 0;
986 while (number > 0)
987 {
988 i = _FrameInstDecrement (fi->template, i);
989 size += _FrameInstGetItemSize (fi, i);
990 number--;
991 }
992 /*endwhile*/
993 info->num = (unit - (size%unit))%unit;
994 }
995 /*endif*/
996 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
997 break;
998
999 case ITER:
1000 {
1001 ExtraData d;
1002 ExtraDataRec dr;
1003 XimFrameType sub_type;
1004
1005
1006 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1007 {
1008 dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE);
1009 d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
1010 }
1011 /*endif*/
1012 sub_type = IterGetNextType (d->iter, info);
1013 if (sub_type == EOL)
1014 {
1015 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
1016 ret_type = FrameInstGetNextType (fi, info);
1017 }
1018 else
1019 {
1020 ret_type = sub_type;
1021 }
1022 /*endif*/
1023 }
1024 break;
1025
1026 case POINTER:
1027 {
1028 ExtraData d;
1029 ExtraDataRec dr;
1030 XimFrameType sub_type;
1031
1032 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1033 {
1034 dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data);
1035 d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
1036 }
1037 /*endif*/
1038 sub_type = FrameInstGetNextType (d->fi, info);
1039 if (sub_type == EOL)
1040 {
1041 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
1042 ret_type = FrameInstGetNextType (fi, info);
1043 }
1044 else
1045 {
1046 ret_type = sub_type;
1047 }
1048 /*endif*/
1049 }
1050 break;
1051 default:
1052 break;
1053 }
1054 /*endswitch*/
1055 return ret_type;
1056 }
1057
FrameInstPeekNextType(FrameInst fi,XimFrameTypeInfo info)1058 static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info)
1059 {
1060 XimFrameType ret_type;
1061
1062 ret_type = fi->template[fi->cur_no].type;
1063
1064 switch (ret_type)
1065 {
1066 case BIT8:
1067 case BIT16:
1068 case BIT32:
1069 case BIT64:
1070 case EOL:
1071 break;
1072
1073 case COUNTER_BIT8:
1074 case COUNTER_BIT16:
1075 case COUNTER_BIT32:
1076 case COUNTER_BIT64:
1077 if (info)
1078 {
1079 register int offset;
1080 register int iter_idx;
1081
1082 info->counter.is_byte_len =
1083 (((long) fi->template[fi->cur_no].data) & 0xFF) == FmCounterByte;
1084 offset = ((long)fi->template[fi->cur_no].data) >> 8;
1085 iter_idx = fi->cur_no + offset;
1086 if (fi->template[iter_idx].type == ITER)
1087 {
1088 ExtraData d;
1089 ExtraDataRec dr;
1090
1091 if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL)
1092 {
1093 dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE);
1094 d = ChainMgrSetData (&fi->cm, iter_idx, dr);
1095 }
1096 /*endif*/
1097 info->counter.iter = d->iter;
1098 }
1099 else
1100 {
1101 /* Should not be reached here */
1102 }
1103 /*endif*/
1104 }
1105 /*endif*/
1106 break;
1107
1108 case BARRAY:
1109 if (info)
1110 {
1111 ExtraData d;
1112
1113 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1114 info->num = NO_VALUE;
1115 else
1116 info->num = d->num;
1117 /*endif*/
1118 }
1119 /*endif*/
1120 break;
1121
1122 case PADDING:
1123 if (info)
1124 {
1125 register int unit;
1126 register int number;
1127 register int size;
1128 register int i;
1129
1130 unit = _UNIT ((long) fi->template[fi->cur_no].data);
1131 number = _NUMBER ((long) fi->template[fi->cur_no].data);
1132
1133 i = fi->cur_no;
1134 size = 0;
1135 while (number > 0)
1136 {
1137 i = _FrameInstDecrement (fi->template, i);
1138 size += _FrameInstGetItemSize (fi, i);
1139 number--;
1140 }
1141 /*endwhile*/
1142 info->num = (unit - (size%unit))%unit;
1143 }
1144 /*endif*/
1145 break;
1146
1147 case ITER:
1148 {
1149 ExtraData d;
1150 ExtraDataRec dr;
1151 XimFrameType sub_type;
1152
1153 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1154 {
1155 dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE);
1156 d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
1157 }
1158 /*endif*/
1159 sub_type = IterPeekNextType (d->iter, info);
1160 if (sub_type == EOL)
1161 ret_type = FrameInstPeekNextType (fi, info);
1162 else
1163 ret_type = sub_type;
1164 /*endif*/
1165 }
1166 break;
1167
1168 case POINTER:
1169 {
1170 ExtraData d;
1171 ExtraDataRec dr;
1172 XimFrameType sub_type;
1173
1174 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1175 {
1176 dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data);
1177 d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
1178 }
1179 /*endif*/
1180 sub_type = FrameInstPeekNextType (d->fi, info);
1181 if (sub_type == EOL)
1182 ret_type = FrameInstPeekNextType (fi, info);
1183 else
1184 ret_type = sub_type;
1185 /*endif*/
1186 default:
1187 break;
1188 }
1189 break;
1190 }
1191 /*endswitch*/
1192 return ret_type;
1193 }
1194
FrameInstIsIterLoopEnd(FrameInst fi)1195 static Bool FrameInstIsIterLoopEnd (FrameInst fi)
1196 {
1197 Bool ret = False;
1198
1199 if (fi->template[fi->cur_no].type == ITER)
1200 {
1201 ExtraData d = ChainMgrGetExtraData (&fi->cm, fi->cur_no);
1202 Bool yourself;
1203
1204 if (d)
1205 {
1206 ret = IterIsLoopEnd (d->iter, &yourself);
1207 if (ret && yourself)
1208 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
1209 /*endif*/
1210 }
1211 /*endif*/
1212 }
1213 /*endif*/
1214 return (ret);
1215 }
1216
_FrameMgrAppendIter(FrameMgr fm,Iter it,int end)1217 static FrameIter _FrameMgrAppendIter (FrameMgr fm, Iter it, int end)
1218 {
1219 FrameIter p = fm->iters;
1220
1221 while (p && p->next)
1222 p = p->next;
1223 /*endwhile*/
1224
1225 if (!p)
1226 {
1227 fm->iters =
1228 p = (FrameIter) Xmalloc (sizeof (FrameIterRec));
1229 }
1230 else
1231 {
1232 p->next = (FrameIter) Xmalloc (sizeof (FrameIterRec));
1233 p = p->next;
1234 }
1235 /*endif*/
1236 if (p)
1237 {
1238 p->iter = it;
1239 p->counting = False;
1240 p->counter = 0;
1241 p->end = end;
1242 p->next = NULL;
1243 }
1244 /*endif*/
1245 return (p);
1246 }
1247
_FrameMgrRemoveIter(FrameMgr fm,FrameIter it)1248 static void _FrameMgrRemoveIter (FrameMgr fm, FrameIter it)
1249 {
1250 FrameIter prev;
1251 FrameIter p;
1252
1253 prev = NULL;
1254 p = fm->iters;
1255 while (p)
1256 {
1257 if (p == it)
1258 {
1259 if (prev)
1260 prev->next = p->next;
1261 else
1262 fm->iters = p->next;
1263 /*endif*/
1264 Xfree (p);
1265 break;
1266 }
1267 /*endif*/
1268 prev = p;
1269 p = p->next;
1270 }
1271 /*endwhile*/
1272 }
1273
_FrameIterCounterIncr(FrameIter fitr,int i)1274 static FrameIter _FrameIterCounterIncr (FrameIter fitr, int i)
1275 {
1276 FrameIter p = fitr;
1277
1278 while (p)
1279 {
1280 if (p->counting)
1281 {
1282 p->counter += i;
1283 if (p->counter >= p->end)
1284 {
1285 IterFixIteration (p->iter);
1286 return (p);
1287 }
1288 /*endif*/
1289 }
1290 /*endif*/
1291 p = p->next;
1292 }
1293 /*endwhile*/
1294 return (NULL);
1295 }
1296
_IterStartWatch(Iter it,void * client_data)1297 static void _IterStartWatch (Iter it, void *client_data)
1298 {
1299 FrameIter p = (FrameIter) client_data;
1300 p->counting = True;
1301 }
1302
FrameInstSetSize(FrameInst fi,int num)1303 static FmStatus FrameInstSetSize (FrameInst fi, int num)
1304 {
1305 ExtraData d;
1306 ExtraDataRec dr;
1307 XimFrameType type;
1308 register int i;
1309
1310 i = 0;
1311 while ((type = fi->template[i].type) != EOL)
1312 {
1313 switch (type)
1314 {
1315 case BARRAY:
1316 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1317 {
1318 dr.num = -1;
1319 d = ChainMgrSetData (&fi->cm, i, dr);
1320 }
1321 /*endif*/
1322 if (d->num == NO_VALUE)
1323 {
1324 d->num = num;
1325 return FmSuccess;
1326 }
1327 /*endif*/
1328 break;
1329 case ITER:
1330 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1331 {
1332 dr.iter = IterInit (&fi->template[i + 1], NO_VALUE);
1333 d = ChainMgrSetData (&fi->cm, i, dr);
1334 }
1335 /*endif*/
1336 if (IterSetSize (d->iter, num) == FmSuccess)
1337 return FmSuccess;
1338 /*endif*/
1339 break;
1340
1341 case POINTER:
1342 if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL)
1343 {
1344 dr.fi = FrameInstInit(fi->template[i + 1].data);
1345 d = ChainMgrSetData(&fi->cm, i, dr);
1346 }
1347 /*endif*/
1348 if (FrameInstSetSize(d->fi, num) == FmSuccess)
1349 return FmSuccess;
1350 /*endif*/
1351 break;
1352 default:
1353 break;
1354 }
1355 /*endswitch*/
1356 i = _FrameInstIncrement(fi->template, i);
1357 }
1358 /*endwhile*/
1359 return FmNoMoreData;
1360 }
1361
FrameInstGetSize(FrameInst fi)1362 static int FrameInstGetSize (FrameInst fi)
1363 {
1364 XimFrameType type;
1365 register int i;
1366 ExtraData d;
1367 ExtraDataRec dr;
1368 int ret_size;
1369
1370 i = fi->cur_no;
1371 while ((type = fi->template[i].type) != EOL)
1372 {
1373 switch (type)
1374 {
1375 case BARRAY:
1376 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1377 return NO_VALUE;
1378 /*endif*/
1379 return d->num;
1380
1381 case ITER:
1382 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1383 {
1384 dr.iter = IterInit (&fi->template[i + 1], NO_VALUE);
1385 d = ChainMgrSetData (&fi->cm, i, dr);
1386 }
1387 /*endif*/
1388 ret_size = IterGetSize(d->iter);
1389 if (ret_size != NO_VALID_FIELD)
1390 return ret_size;
1391 /*endif*/
1392 break;
1393
1394 case POINTER:
1395 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1396 {
1397 dr.fi = FrameInstInit (fi->template[i + 1].data);
1398 d = ChainMgrSetData (&fi->cm, i, dr);
1399 }
1400 /*endif*/
1401 ret_size = FrameInstGetSize (d->fi);
1402 if (ret_size != NO_VALID_FIELD)
1403 return ret_size;
1404 /*endif*/
1405 break;
1406 default:
1407 break;
1408 }
1409 /*endswitch*/
1410 i = _FrameInstIncrement (fi->template, i);
1411 }
1412 /*endwhile*/
1413 return NO_VALID_FIELD;
1414 }
1415
FrameInstSetIterCount(FrameInst fi,int num)1416 static FmStatus FrameInstSetIterCount (FrameInst fi, int num)
1417 {
1418 ExtraData d;
1419 ExtraDataRec dr;
1420 register int i;
1421 XimFrameType type;
1422
1423 i = 0;
1424 while ((type = fi->template[i].type) != EOL)
1425 {
1426 switch (type)
1427 {
1428 case ITER:
1429 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1430 {
1431 dr.iter = IterInit (&fi->template[i + 1], num);
1432 (void)ChainMgrSetData (&fi->cm, i, dr);
1433 return FmSuccess;
1434 }
1435 /*endif*/
1436 if (IterSetIterCount (d->iter, num) == FmSuccess)
1437 return FmSuccess;
1438 /*endif*/
1439 break;
1440
1441 case POINTER:
1442 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1443 {
1444 dr.fi = FrameInstInit (fi->template[i + 1].data);
1445 d = ChainMgrSetData (&fi->cm, i, dr);
1446 }
1447 /*endif*/
1448 if (FrameInstSetIterCount (d->fi, num) == FmSuccess)
1449 return FmSuccess;
1450 /*endif*/
1451 break;
1452
1453 default:
1454 break;
1455 }
1456 /*endswitch*/
1457 i = _FrameInstIncrement (fi->template, i);
1458 }
1459 /*endwhile*/
1460 return FmNoMoreData;
1461 }
1462
FrameInstGetTotalSize(FrameInst fi)1463 static int FrameInstGetTotalSize (FrameInst fi)
1464 {
1465 register int size;
1466 register int i;
1467
1468 size = 0;
1469 i = 0;
1470
1471 while (fi->template[i].type != EOL)
1472 {
1473 size += _FrameInstGetItemSize (fi, i);
1474 i = _FrameInstIncrement (fi->template, i);
1475 }
1476 /*endwhile*/
1477 return size;
1478 }
1479
FrameInstReset(FrameInst fi)1480 static void FrameInstReset (FrameInst fi)
1481 {
1482 ChainIterRec ci;
1483 int frame_no;
1484 ExtraDataRec d;
1485
1486 ChainIterInit (&ci, &fi->cm);
1487
1488 while (ChainIterGetNext (&ci, &frame_no, &d))
1489 {
1490 register XimFrameType type;
1491 type = fi->template[frame_no].type;
1492 if (type == ITER)
1493 {
1494 if (d.iter)
1495 IterReset (d.iter);
1496 /*endif*/
1497 }
1498 else if (type == POINTER)
1499 {
1500 if (d.fi)
1501 FrameInstReset (d.fi);
1502 /*endif*/
1503 }
1504 /*endif*/
1505 }
1506 /*endwhile*/
1507 ChainIterFree (&ci);
1508
1509 fi->cur_no = 0;
1510 }
1511
IterInit(XimFrame frame,int count)1512 static Iter IterInit (XimFrame frame, int count)
1513 {
1514 Iter it;
1515 register XimFrameType type;
1516
1517 it = (Iter) Xmalloc (sizeof (IterRec));
1518 it->template = frame;
1519 it->max_count = (count == NO_VALUE) ? 0 : count;
1520 it->allow_expansion = (count == NO_VALUE);
1521 it->cur_no = 0;
1522 it->start_watch_proc = NULL;
1523 it->client_data = NULL;
1524 it->start_counter = False;
1525
1526 type = frame->type;
1527 if (type & COUNTER_MASK)
1528 {
1529 /* COUNTER_XXX cannot be an item of a ITER */
1530 Xfree (it);
1531 return NULL;
1532 }
1533 /*endif*/
1534
1535 switch (type)
1536 {
1537 case BIT8:
1538 case BIT16:
1539 case BIT32:
1540 case BIT64:
1541 /* Do nothing */
1542 break;
1543
1544 case BARRAY:
1545 case ITER:
1546 case POINTER:
1547 ChainMgrInit (&it->cm);
1548 break;
1549
1550 default:
1551 Xfree (it);
1552 return NULL; /* This should never occur */
1553 }
1554 /*endswitch*/
1555 return it;
1556 }
1557
IterFree(Iter it)1558 static void IterFree (Iter it)
1559 {
1560 switch (it->template->type)
1561 {
1562 case BARRAY:
1563 ChainMgrFree (&it->cm);
1564 break;
1565
1566 case ITER:
1567 {
1568 ChainIterRec ci;
1569 int count;
1570 ExtraDataRec d;
1571
1572 ChainIterInit (&ci, &it->cm);
1573 while (ChainIterGetNext (&ci, &count, &d))
1574 IterFree (d.iter);
1575 /*endwhile*/
1576 ChainIterFree (&ci);
1577 ChainMgrFree (&it->cm);
1578 }
1579 break;
1580
1581 case POINTER:
1582 {
1583 ChainIterRec ci;
1584 int count;
1585 ExtraDataRec dr;
1586
1587 ChainIterInit (&ci, &it->cm);
1588 while (ChainIterGetNext (&ci, &count, &dr))
1589 FrameInstFree (dr.fi);
1590 /*endwhile*/
1591 ChainIterFree (&ci);
1592 ChainMgrFree (&it->cm);
1593 }
1594 break;
1595
1596 default:
1597 break;
1598 }
1599 /*endswitch*/
1600 Xfree (it);
1601 }
1602
IterIsLoopEnd(Iter it,Bool * myself)1603 static Bool IterIsLoopEnd (Iter it, Bool *myself)
1604 {
1605 Bool ret = False;
1606 *myself = False;
1607
1608 if (!it->allow_expansion && (it->cur_no == it->max_count))
1609 {
1610 *myself = True;
1611 return True;
1612 }
1613 /*endif*/
1614
1615 if (it->template->type == POINTER)
1616 {
1617 ExtraData d = ChainMgrGetExtraData (&it->cm, it->cur_no);
1618 if (d)
1619 {
1620 if (FrameInstIsIterLoopEnd (d->fi))
1621 {
1622 ret = True;
1623 }
1624 else
1625 {
1626 if (FrameInstIsEnd (d->fi))
1627 {
1628 it->cur_no++;
1629 if (!it->allow_expansion && it->cur_no == it->max_count)
1630 {
1631 *myself = True;
1632 ret = True;
1633 }
1634 /*endif*/
1635 }
1636 /*endif*/
1637 }
1638 /*endif*/
1639 }
1640 /*endif*/
1641 }
1642 else if (it->template->type == ITER)
1643 {
1644 ExtraData d = ChainMgrGetExtraData (&it->cm, it->cur_no);
1645 if (d)
1646 {
1647 Bool yourself;
1648
1649 if (IterIsLoopEnd (d->iter, &yourself))
1650 ret = True;
1651 /*endif*/
1652 }
1653 /*endif*/
1654 }
1655 /*endif*/
1656
1657 return ret;
1658 }
1659
IterGetNextType(Iter it,XimFrameTypeInfo info)1660 static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info)
1661 {
1662 XimFrameType type = it->template->type;
1663
1664 if (it->start_counter)
1665 {
1666 (*it->start_watch_proc) (it, it->client_data);
1667 it->start_counter = False;
1668 }
1669 /*endif*/
1670 if (it->cur_no >= it->max_count)
1671 {
1672 if (it->allow_expansion)
1673 it->max_count = it->cur_no + 1;
1674 else
1675 return EOL;
1676 /*endif*/
1677 }
1678 /*endif*/
1679
1680 switch (type)
1681 {
1682 case BIT8:
1683 case BIT16:
1684 case BIT32:
1685 case BIT64:
1686 it->cur_no++;
1687 return type;
1688
1689 case BARRAY:
1690 if (info)
1691 {
1692 ExtraData d;
1693
1694 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1695 info->num = NO_VALUE;
1696 else
1697 info->num = d->num;
1698 /*endif*/
1699 }
1700 /*endif*/
1701 it->cur_no++;
1702 return BARRAY;
1703
1704 case ITER:
1705 {
1706 XimFrameType ret_type;
1707 ExtraData d;
1708 ExtraDataRec dr;
1709
1710 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1711 {
1712 dr.iter = IterInit (it->template + 1, NO_VALUE);
1713 d = ChainMgrSetData (&it->cm, it->cur_no, dr);
1714 }
1715 /*endif*/
1716
1717 ret_type = IterGetNextType (d->iter, info);
1718 if (ret_type == EOL)
1719 {
1720 it->cur_no++;
1721 ret_type = IterGetNextType (it, info);
1722 }
1723 /*endif*/
1724 return ret_type;
1725 }
1726
1727 case POINTER:
1728 {
1729 XimFrameType ret_type;
1730 ExtraData d;
1731 ExtraDataRec dr;
1732
1733 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1734 {
1735 dr.fi = FrameInstInit (it->template[1].data);
1736 d = ChainMgrSetData (&it->cm, it->cur_no, dr);
1737 }
1738 /*endif*/
1739
1740 ret_type = FrameInstGetNextType (d->fi, info);
1741 if (ret_type == EOL)
1742 {
1743 it->cur_no++;
1744 ret_type = IterGetNextType (it, info);
1745 }
1746 /*endif*/
1747 return ret_type;
1748 }
1749
1750 default:
1751 return (XimFrameType) NULL;
1752 }
1753 /*endswitch*/
1754 return (XimFrameType) NULL; /* This should never occur */
1755 }
1756
IterPeekNextType(Iter it,XimFrameTypeInfo info)1757 static XimFrameType IterPeekNextType (Iter it, XimFrameTypeInfo info)
1758 {
1759 XimFrameType type = it->template->type;
1760
1761 if (!it->allow_expansion && it->cur_no >= it->max_count)
1762 return (EOL);
1763 /*endif*/
1764
1765 switch (type)
1766 {
1767 case BIT8:
1768 case BIT16:
1769 case BIT32:
1770 case BIT64:
1771 return type;
1772
1773 case BARRAY:
1774 if (info)
1775 {
1776 ExtraData d;
1777
1778 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1779 info->num = NO_VALUE;
1780 else
1781 info->num = d->num;
1782 /*endif*/
1783 }
1784 /*endif*/
1785 return BARRAY;
1786
1787 case ITER:
1788 {
1789 XimFrameType ret_type;
1790 ExtraData d;
1791 ExtraDataRec dr;
1792
1793 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1794 {
1795 dr.iter = IterInit (it->template + 1, NO_VALUE);
1796 d = ChainMgrSetData (&it->cm, it->cur_no, dr);
1797 }
1798 /*endif*/
1799
1800 ret_type = IterPeekNextType (d->iter, info);
1801 if (ret_type == EOL)
1802 ret_type = IterPeekNextType (it, info);
1803 /*endif*/
1804 return ret_type;
1805 }
1806
1807 case POINTER:
1808 {
1809 XimFrameType ret_type;
1810 ExtraData d;
1811 ExtraDataRec dr;
1812
1813 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1814 {
1815 dr.fi = FrameInstInit (it->template[1].data);
1816 d = ChainMgrSetData (&it->cm, it->cur_no, dr);
1817 }
1818 /*endif*/
1819
1820 ret_type = FrameInstPeekNextType (d->fi, info);
1821 if (ret_type == EOL)
1822 ret_type = IterPeekNextType (it, info);
1823 /*endif*/
1824 return (ret_type);
1825 }
1826
1827 default:
1828 break;
1829 }
1830 /*endswitch*/
1831 /* Reaching here is a bug! */
1832 return (XimFrameType) NULL;
1833 }
1834
IterSetSize(Iter it,int num)1835 static FmStatus IterSetSize (Iter it, int num)
1836 {
1837 XimFrameType type;
1838 register int i;
1839
1840 if (!it->allow_expansion && it->max_count == 0)
1841 return FmNoMoreData;
1842 /*endif*/
1843
1844 type = it->template->type;
1845 switch (type)
1846 {
1847 case BARRAY:
1848 {
1849 ExtraData d;
1850 ExtraDataRec dr;
1851
1852 for (i = 0; i < it->max_count; i++)
1853 {
1854 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
1855 {
1856 dr.num = NO_VALUE;
1857 d = ChainMgrSetData (&it->cm, i, dr);
1858 }
1859 /*endif*/
1860 if (d->num == NO_VALUE)
1861 {
1862 d->num = num;
1863 return FmSuccess;
1864 }
1865 /*endif*/
1866 }
1867 /*endfor*/
1868 if (it->allow_expansion)
1869 {
1870 ExtraDataRec dr;
1871
1872 dr.num = num;
1873 ChainMgrSetData (&it->cm, it->max_count, dr);
1874 it->max_count++;
1875
1876 return FmSuccess;
1877 }
1878 /*endif*/
1879 }
1880 return FmNoMoreData;
1881
1882 case ITER:
1883 {
1884 ExtraData d;
1885 ExtraDataRec dr;
1886
1887 for (i = 0; i < it->max_count; i++)
1888 {
1889 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
1890 {
1891 dr.iter = IterInit (it->template + 1, NO_VALUE);
1892 d = ChainMgrSetData (&it->cm, i, dr);
1893 }
1894 /*endif*/
1895 if (IterSetSize (d->iter, num) == FmSuccess)
1896 return FmSuccess;
1897 /*endif*/
1898 }
1899 /*endfor*/
1900 if (it->allow_expansion)
1901 {
1902 ExtraDataRec dr;
1903
1904 dr.iter = IterInit (it->template + 1, NO_VALUE);
1905 ChainMgrSetData (&it->cm, it->max_count, dr);
1906 it->max_count++;
1907
1908 if (IterSetSize(dr.iter, num) == FmSuccess)
1909 return FmSuccess;
1910 /*endif*/
1911 }
1912 /*endif*/
1913 }
1914 return FmNoMoreData;
1915
1916 case POINTER:
1917 {
1918 ExtraData d;
1919 ExtraDataRec dr;
1920
1921 for (i = 0; i < it->max_count; i++)
1922 {
1923 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
1924 {
1925 dr.fi = FrameInstInit (it->template[1].data);
1926 d = ChainMgrSetData (&it->cm, i, dr);
1927 }
1928 /*endif*/
1929 if (FrameInstSetSize (d->fi, num) == FmSuccess)
1930 return FmSuccess;
1931 /*endif*/
1932 }
1933 /*endfor*/
1934 if (it->allow_expansion)
1935 {
1936 ExtraDataRec dr;
1937
1938 dr.fi = FrameInstInit (it->template[1].data);
1939 ChainMgrSetData (&it->cm, it->max_count, dr);
1940 it->max_count++;
1941
1942 if (FrameInstSetSize (dr.fi, num) == FmSuccess)
1943 return FmSuccess;
1944 /*endif*/
1945 }
1946 /*endif*/
1947 }
1948 return FmNoMoreData;
1949
1950 default:
1951 break;
1952 }
1953 /*endswitch*/
1954 return FmNoMoreData;
1955 }
1956
IterGetSize(Iter it)1957 static int IterGetSize (Iter it)
1958 {
1959 register int i;
1960 ExtraData d;
1961 ExtraDataRec dr;
1962
1963 if (it->cur_no >= it->max_count)
1964 return NO_VALID_FIELD;
1965 /*endif*/
1966
1967 switch (it->template->type)
1968 {
1969 case BARRAY:
1970 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1971 return NO_VALUE;
1972 /*endif*/
1973 return d->num;
1974
1975 case ITER:
1976 for (i = it->cur_no; i < it->max_count; i++)
1977 {
1978 int ret_size;
1979
1980 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
1981 {
1982 dr.iter = IterInit (it->template + 1, NO_VALUE);
1983 d = ChainMgrSetData (&it->cm, i, dr);
1984 }
1985 /*endif*/
1986 ret_size = IterGetSize (d->iter);
1987 if (ret_size != NO_VALID_FIELD)
1988 return ret_size;
1989 /*endif*/
1990 }
1991 /*endfor*/
1992 return NO_VALID_FIELD;
1993
1994 case POINTER:
1995 for (i = it->cur_no; i < it->max_count; i++)
1996 {
1997 int ret_size;
1998
1999 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2000 {
2001 dr.fi = FrameInstInit (it->template[1].data);
2002 d = ChainMgrSetData (&it->cm, i, dr);
2003 }
2004 /*endif*/
2005 ret_size = FrameInstGetSize (d->fi);
2006 if (ret_size != NO_VALID_FIELD)
2007 return ret_size;
2008 /*endif*/
2009 }
2010 /*endfor*/
2011 return NO_VALID_FIELD;
2012
2013 default:
2014 break;
2015 }
2016 /*endswitch*/
2017 return NO_VALID_FIELD;
2018 }
2019
IterSetIterCount(Iter it,int num)2020 static FmStatus IterSetIterCount (Iter it, int num)
2021 {
2022 register int i;
2023
2024 if (it->allow_expansion)
2025 {
2026 it->max_count = num;
2027 it->allow_expansion = False;
2028 return FmSuccess;
2029 }
2030 /*endif*/
2031
2032 if (it->max_count == 0)
2033 return FmNoMoreData;
2034 /*endif*/
2035
2036 switch (it->template->type)
2037 {
2038 case ITER:
2039 for (i = 0; i < it->max_count; i++)
2040 {
2041 ExtraData d;
2042 ExtraDataRec dr;
2043
2044 if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL)
2045 {
2046 dr.iter = IterInit(it->template + 1, num);
2047 (void)ChainMgrSetData(&it->cm, i, dr);
2048 return FmSuccess;
2049 }
2050 /*endif*/
2051 if (IterSetIterCount(d->iter, num) == FmSuccess)
2052 return FmSuccess;
2053 /*endif*/
2054 }
2055 /*endfor*/
2056 if (it->allow_expansion)
2057 {
2058 ExtraDataRec dr;
2059
2060 dr.iter = IterInit (it->template + 1, num);
2061 ChainMgrSetData (&it->cm, it->max_count, dr);
2062 it->max_count++;
2063
2064 return FmSuccess;
2065 }
2066 /*endif*/
2067 break;
2068
2069 case POINTER:
2070 for (i = 0; i < it->max_count; i++)
2071 {
2072 ExtraData d;
2073 ExtraDataRec dr;
2074
2075 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2076 {
2077 dr.fi = FrameInstInit (it->template[1].data);
2078 d = ChainMgrSetData (&it->cm, i, dr);
2079 }
2080 /*endif*/
2081 if (FrameInstSetIterCount (d->fi, num) == FmSuccess)
2082 return FmSuccess;
2083 /*endif*/
2084 }
2085 /*endfor*/
2086 if (it->allow_expansion)
2087 {
2088 ExtraDataRec dr;
2089
2090 dr.fi = FrameInstInit (it->template[1].data);
2091 ChainMgrSetData (&it->cm, it->max_count, dr);
2092 it->max_count++;
2093
2094 if (FrameInstSetIterCount (dr.fi, num) == FmSuccess)
2095 return FmSuccess;
2096 /*endif*/
2097 }
2098 /*endif*/
2099 break;
2100
2101 default:
2102 break;
2103 }
2104 /*endswitch*/
2105 return FmNoMoreData;
2106 }
2107
IterGetTotalSize(Iter it)2108 static int IterGetTotalSize (Iter it)
2109 {
2110 register int size, i;
2111 XimFrameType type;
2112
2113 if (it->allow_expansion)
2114 return NO_VALUE;
2115 /*endif*/
2116 if (it->max_count == 0)
2117 return 0;
2118 /*endif*/
2119
2120 size = 0;
2121 type = it->template->type;
2122
2123 switch (type)
2124 {
2125 case BIT8:
2126 size = it->max_count;
2127 break;
2128
2129 case BIT16:
2130 size = it->max_count*2;
2131 break;
2132
2133 case BIT32:
2134 size = it->max_count*4;
2135 break;
2136
2137 case BIT64:
2138 size = it->max_count*8;
2139 break;
2140
2141 case BARRAY:
2142 for (i = 0; i < it->max_count; i++)
2143 {
2144 register int num;
2145 ExtraData d;
2146
2147 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2148 return NO_VALUE;
2149 /*endif*/
2150 if ((num = d->num) == NO_VALUE)
2151 return NO_VALUE;
2152 /*endif*/
2153 size += num;
2154 }
2155 /*endfor*/
2156 break;
2157
2158 case ITER:
2159 for (i = 0; i < it->max_count; i++)
2160 {
2161 register int num;
2162 ExtraData d;
2163
2164 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2165 return NO_VALUE;
2166 /*endif*/
2167 if ((num = IterGetTotalSize (d->iter)) == NO_VALUE)
2168 return NO_VALUE;
2169 /*endif*/
2170 size += num;
2171 }
2172 /*endfor*/
2173 break;
2174
2175 case POINTER:
2176 for (i = 0; i < it->max_count; i++)
2177 {
2178 register int num;
2179 ExtraData d;
2180 ExtraDataRec dr;
2181
2182 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2183 {
2184 dr.fi = FrameInstInit (it->template[1].data);
2185 d = ChainMgrSetData (&it->cm, i, dr);
2186 }
2187 /*endif*/
2188 if ((num = FrameInstGetTotalSize (d->fi)) == NO_VALUE)
2189 return NO_VALUE;
2190 /*endif*/
2191 size += num;
2192 }
2193 /*endfor*/
2194 break;
2195
2196 default:
2197 break;
2198 }
2199 /*endswitch*/
2200 return size;
2201 }
2202
IterReset(Iter it)2203 static void IterReset (Iter it)
2204 {
2205 ChainIterRec ci;
2206 int count;
2207 ExtraDataRec d;
2208
2209 switch (it->template->type)
2210 {
2211 case ITER:
2212 ChainIterInit (&ci, &it->cm);
2213 while (ChainIterGetNext (&ci, &count, &d))
2214 IterReset (d.iter);
2215 /*endwhile*/
2216 ChainIterFree (&ci);
2217 break;
2218
2219 case POINTER:
2220 ChainIterInit (&ci, &it->cm);
2221 while (ChainIterGetNext (&ci, &count, &d))
2222 FrameInstReset (d.fi);
2223 /*endwhile*/
2224 ChainIterFree (&ci);
2225 break;
2226
2227 default:
2228 break;
2229 }
2230 /*endswitch*/
2231 it->cur_no = 0;
2232 }
2233
IterSetStartWatch(Iter it,IterStartWatchProc proc,void * client_data)2234 static void IterSetStartWatch (Iter it,
2235 IterStartWatchProc proc,
2236 void *client_data)
2237 {
2238 it->start_watch_proc = proc;
2239 it->client_data = client_data;
2240 }
2241
ChainMgrSetData(ChainMgr cm,int frame_no,ExtraDataRec data)2242 static ExtraData ChainMgrSetData (ChainMgr cm,
2243 int frame_no,
2244 ExtraDataRec data)
2245 {
2246 Chain cur = (Chain) Xmalloc (sizeof (ChainRec));
2247
2248 cur->frame_no = frame_no;
2249 cur->d = data;
2250 cur->next = NULL;
2251
2252 if (cm->top == NULL)
2253 {
2254 cm->top = cm->tail = cur;
2255 }
2256 else
2257 {
2258 cm->tail->next = cur;
2259 cm->tail = cur;
2260 }
2261 /*endif*/
2262 return &cur->d;
2263 }
2264
ChainMgrGetExtraData(ChainMgr cm,int frame_no)2265 static ExtraData ChainMgrGetExtraData (ChainMgr cm, int frame_no)
2266 {
2267 Chain cur;
2268
2269 cur = cm->top;
2270
2271 while (cur)
2272 {
2273 if (cur->frame_no == frame_no)
2274 return &cur->d;
2275 /*endif*/
2276 cur = cur->next;
2277 }
2278 /*endwhile*/
2279 return NULL;
2280 }
2281
ChainIterGetNext(ChainIter ci,int * frame_no,ExtraData d)2282 static Bool ChainIterGetNext (ChainIter ci, int *frame_no, ExtraData d)
2283 {
2284 if (ci->cur == NULL)
2285 return False;
2286 /*endif*/
2287
2288 *frame_no = ci->cur->frame_no;
2289 *d = ci->cur->d;
2290
2291 ci->cur = ci->cur->next;
2292
2293 return True;
2294 }
2295
_FrameInstIncrement(XimFrame frame,int count)2296 static int _FrameInstIncrement (XimFrame frame, int count)
2297 {
2298 XimFrameType type;
2299
2300 type = frame[count].type;
2301 type &= ~COUNTER_MASK;
2302
2303 switch (type)
2304 {
2305 case BIT8:
2306 case BIT16:
2307 case BIT32:
2308 case BIT64:
2309 case BARRAY:
2310 case PADDING:
2311 return count + 1;
2312
2313 case POINTER:
2314 return count + 2;
2315
2316 case ITER:
2317 return _FrameInstIncrement (frame, count + 1);
2318 default:
2319 break;
2320 }
2321 /*endswitch*/
2322 return - 1; /* Error */
2323 }
2324
_FrameInstDecrement(XimFrame frame,int count)2325 static int _FrameInstDecrement (XimFrame frame, int count)
2326 {
2327 register int i;
2328 XimFrameType type;
2329
2330 if (count == 0)
2331 return - 1; /* cannot decrement */
2332 /*endif*/
2333
2334 if (count == 1)
2335 return 0; /* BOGUS - It should check the contents of data */
2336 /*endif*/
2337
2338 type = frame[count - 2].type;
2339 type &= ~COUNTER_MASK;
2340
2341 switch (type)
2342 {
2343 case BIT8:
2344 case BIT16:
2345 case BIT32:
2346 case BIT64:
2347 case BARRAY:
2348 case PADDING:
2349 case PTR_ITEM:
2350 return count - 1;
2351
2352 case POINTER:
2353 case ITER:
2354 i = count - 3;
2355 while (i >= 0)
2356 {
2357 if (frame[i].type != ITER)
2358 return i + 1;
2359 /*endif*/
2360 i--;
2361 }
2362 /*endwhile*/
2363 return 0;
2364 default:
2365 break;
2366 }
2367 /*enswitch*/
2368 return - 1; /* Error */
2369 }
2370
_FrameInstGetItemSize(FrameInst fi,int cur_no)2371 static int _FrameInstGetItemSize (FrameInst fi, int cur_no)
2372 {
2373 XimFrameType type;
2374
2375 type = fi->template[cur_no].type;
2376 type &= ~COUNTER_MASK;
2377
2378 switch (type)
2379 {
2380 case BIT8:
2381 return 1;
2382
2383 case BIT16:
2384 return 2;
2385
2386 case BIT32:
2387 return 4;
2388
2389 case BIT64:
2390 return 8;
2391
2392 case BARRAY:
2393 {
2394 ExtraData d;
2395
2396 if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL)
2397 return NO_VALUE;
2398 /*endif*/
2399 if (d->num == NO_VALUE)
2400 return NO_VALUE;
2401 /*endif*/
2402 return d->num;
2403 }
2404
2405 case PADDING:
2406 {
2407 register int unit;
2408 register int number;
2409 register int size;
2410 register int i;
2411
2412 unit = _UNIT ((long) fi->template[cur_no].data);
2413 number = _NUMBER ((long) fi->template[cur_no].data);
2414
2415 i = cur_no;
2416 size = 0;
2417 while (number > 0)
2418 {
2419 i = _FrameInstDecrement (fi->template, i);
2420 size += _FrameInstGetItemSize (fi, i);
2421 number--;
2422 }
2423 /*endwhile*/
2424 size = (unit - (size%unit))%unit;
2425 return size;
2426 }
2427
2428 case ITER:
2429 {
2430 ExtraData d;
2431 int sub_size;
2432
2433 if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL)
2434 return NO_VALUE;
2435 /*endif*/
2436 sub_size = IterGetTotalSize (d->iter);
2437 if (sub_size == NO_VALUE)
2438 return NO_VALUE;
2439 /*endif*/
2440 return sub_size;
2441 }
2442
2443 case POINTER:
2444 {
2445 ExtraData d;
2446 int sub_size;
2447
2448 if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL)
2449 return NO_VALUE;
2450 /*endif*/
2451 sub_size = FrameInstGetTotalSize (d->fi);
2452 if (sub_size == NO_VALUE)
2453 return NO_VALUE;
2454 /*endif*/
2455 return sub_size;
2456 }
2457
2458 default:
2459 break;
2460 }
2461 /*endswitch*/
2462 return NO_VALUE;
2463 }
2464