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