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