~ubuntu-branches/ubuntu/quantal/sunpinyin/quantal

« back to all changes in this revision

Viewing changes to wrapper/xim/IMdkit/FrameMgr.c

  • Committer: Package Import Robot
  • Author(s): YunQiang Su
  • Date: 2012-04-11 03:06:40 UTC
  • mfrom: (1.1.4) (1.2.8 sid)
  • Revision ID: package-import@ubuntu.com-20120411030640-8mxepz5e6wffy87c
Tags: 2.0.3+git20120404-1
* Medium urgency for fixing RC bug.
* New upstream commit: fix FTBFS with gcc-4.7 (Closes: #667385).
* Add Multi-Arch: same to libsunpinyin3, -dev and -dbg.
* Add YunQiang Su to uploaders.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
730
 
FmStatus FrameMgrSetTotalSize (FrameMgr fm, int total_size)
731
 
{
732
 
    fm->total_size = total_size;
733
 
    return FmSuccess;
734
 
}
735
 
 
736
 
int FrameMgrGetTotalSize (FrameMgr fm)
737
 
{
738
 
    return FrameInstGetTotalSize (fm->fi);
739
 
}
740
 
 
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
 
 
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
 
 
812
 
void FrameMgrReset (FrameMgr fm)
813
 
{
814
 
    fm->idx = 0;
815
 
    FrameInstReset (fm->fi);
816
 
}
817
 
 
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
 
 
834
 
static Bool _FrameMgrIsIterLoopEnd (FrameMgr fm)
835
 
{
836
 
    return FrameInstIsIterLoopEnd (fm->fi);
837
 
}
838
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
1300
 
static void _IterStartWatch (Iter it, void *client_data)
1301
 
{
1302
 
    FrameIter p = (FrameIter) client_data;
1303
 
    p->counting = True;
1304
 
}
1305
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
}