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