~ubuntu-branches/ubuntu/raring/sunpinyin/raring

« 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-03-30 15:31:55 UTC
  • mfrom: (1.1.3) (1.2.7 sid)
  • Revision ID: package-import@ubuntu.com-20120330153155-qgls77sogzgtg9zp
Tags: 2.0.3+git20120222-1
* Team upload: git snapshot 20120222.
   - fix breaks if LDFLAGS in environment contains
       multiple words (Closese #646001).
   - rm patches merged to upstream:
       append-os-environ-toenv.patch
       fix-ftbfs-on-sh.patch
       remove-10-candidate-words-limitation.patch
   - refresh disable-lm-dict-compile.patch.
* Bump stardard version to 3.9.3: no modify needed.
* add libsunpinyin3-dbg and python-sunpinyin packages.
* debian/compat to 9, multiarch it.
* rewrite debian/rules with dh 7 format.

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
}