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