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