Back to index

im-sdk  12.3.91
FrameMgr.h
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 /*
00043  *      Copyright (c) 1997, by Sun Microsystems, Inc.
00044  *      All rights reserved.
00045  */
00046 
00047 /******************************************************************
00048 Copyright 1993, 1994 by Digital Equipment Corporation, Maynard, Massachusetts,
00049 
00050                         All Rights Reserved
00051 
00052 Permission to use, copy, modify, and distribute this software and its 
00053 documentation for any purpose and without fee is hereby granted, 
00054 provided that the above copyright notice appear in all copies and that
00055 both that copyright notice and this permission notice appear in 
00056 supporting documentation, and that the names of Digital or MIT not be
00057 used in advertising or publicity pertaining to distribution of the
00058 software without specific, written prior permission.  
00059 
00060 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
00061 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
00062 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
00063 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00064 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
00065 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00066 SOFTWARE.
00067 
00068   Author: Hiroyuki Miyamoto  Digital Equipment Corporation
00069                              miyamoto@jrd.dec.com
00070 ******************************************************************/
00071 
00072 #ifndef FRAMEMGR_H
00073 #define FRAMEMGR_H
00074 
00075 #include <stdlib.h>
00076 #include <stdio.h>
00077 #include <string.h>
00078 
00079 #ifndef Bool
00080 #define Bool int
00081 #define True 1
00082 #define False 0
00083 #endif
00084 
00085 #if defined(VAXC) && !defined(__DECC)
00086 #define xim_externalref globalref
00087 #define xim_externaldef globaldef
00088 #else
00089 #define xim_externalref extern
00090 #define xim_externaldef
00091 #endif
00092 
00093 #ifdef __cplusplus
00094 #define NeedFunctionPrototypes 1
00095 #endif
00096 /* Definitions for FrameMgr */
00097 
00098 #define COUNTER_MASK 0x10
00099 
00100 typedef unsigned int   CARD32;
00101 typedef unsigned short CARD16;
00102 typedef unsigned char  CARD8;
00103 
00104 typedef enum {
00105     BIT8     = 0x1,       /* {CARD8* | INT8*} */
00106     BIT16    = 0x2,       /* {CARD16* | INT16*} */
00107     BIT32    = 0x3,       /* {CARD32* | INT32*} */
00108     BARRAY   = 0x4,       /* int*, void* */
00109     ITER     = 0x5,       /* int* */
00110     POINTER  = 0x6,       /* specifies next item is a PTR_ITEM */
00111     PTR_ITEM = 0x7,       /* specifies the item has a pointer */
00112     /* BOGUS - POINTER and PTR_ITEM
00113      *   In the current implementation, PTR_ITEM should be lead by
00114      *   POINTER.  But actually, it's just redundant logically.  Someone 
00115      *   may remove this redundancy and POINTER from the enum member but he
00116      *   should also modify the logic in FrameMgr program.
00117      */
00118     PADDING  = 0x8,       /* specifies that a padding is needed.
00119                          * This requires extra data in data field.
00120                          */
00121     EOL      = 0x9,       /* specifies the end of list */
00122 
00123     COUNTER_BIT8  = COUNTER_MASK|0x1,
00124     COUNTER_BIT16 = COUNTER_MASK|0x2,
00125     COUNTER_BIT32 = COUNTER_MASK|0x3
00126 
00127 } XimFrameType;
00128 
00129 /* Convenient macro */
00130 #define _FRAME(a) {a, NULL}
00131 #define _PTR(p)   {PTR_ITEM, (void *)p}
00132 /* PADDING's usage of data field
00133  * B15-B8  : Shows the number of effective items.
00134  * B7-B0   : Shows padding unit.  ex) 04 shows 4 unit padding.
00135  */
00136 #define _PAD2(n)   {PADDING, (void*)((n)<<8|2)}
00137 #define _PAD4(n)   {PADDING, (void*)((n)<<8|4)}
00138 
00139 #define FmCounterByte 0
00140 #define FmCounterNumber 1
00141     
00142 #define _BYTE_COUNTER(type, offset) \
00143                {(COUNTER_MASK|type), (void*)((offset)<<8|FmCounterByte)}
00144 
00145 #define _NUMBER_COUNTER(type, offset) \
00146                {(COUNTER_MASK|type), (void*)((offset)<<8|FmCounterNumber)}
00147 
00148 typedef struct _XimFrame {
00149     int type;
00150     void* data;       /* For PTR_ITEM and PADDING */
00151 } XimFrameRec, *XimFrame;
00152 
00153 typedef enum {
00154     FmSuccess, 
00155     FmEOD,
00156     FmInvalidCall,
00157     FmBufExist,
00158     FmCannotCalc,
00159     FmNoMoreData
00160 } FmStatus;
00161 
00162 typedef struct _FrameMgr *FrameMgr;
00163 
00164 /* Convenient macro */
00165 
00166 #define _UNIT(n)   ((int)(n) & 0xff)
00167 #define _NUMBER(n) (((int)(n) >> 8) & 0xff)
00168 
00169 /* For byte swapping */
00170 
00171 #define Swap16(p, n) ((p)->byte_swap ?       \
00172                     (((n) << 8 & 0xff00) | \
00173                      ((n) >> 8 & 0xff)     \
00174                     ) : n)
00175 #define Swap32(p, n) ((p)->byte_swap ?            \
00176                     (((n) << 24 & 0xff000000) | \
00177                      ((n) <<  8 & 0xff0000) |   \
00178                      ((n) >>  8 & 0xff00) |     \
00179                      ((n) >> 24 & 0xff)         \
00180                     ) : n)
00181 
00182 /* Type definition */
00183 
00184 typedef struct _Iter *Iter;
00185 
00186 typedef struct _FrameInst *FrameInst;
00187 
00188 typedef union {
00189     int num;         /* For BARRAY */
00190     FrameInst fi;    /* For POINTER */
00191     Iter iter;              /* For ITER */
00192 } ExtraDataRec, *ExtraData;
00193 
00194 typedef struct _Chain {
00195        ExtraDataRec d;
00196        int frame_no;
00197        struct _Chain *next;
00198 } ChainRec, *Chain;
00199 
00200 typedef struct _ChainMgr {
00201     Chain top;
00202     Chain tail;
00203 } ChainMgrRec, *ChainMgr;
00204 
00205 typedef struct _ChainIter {
00206     Chain cur;
00207 } ChainIterRec, *ChainIter;
00208 
00209 typedef struct _FrameIter {
00210     Iter iter;
00211     Bool counting;
00212     unsigned int counter;
00213     int end;
00214     struct _FrameIter* next;
00215 } FrameIterRec, *FrameIter;
00216 
00217 typedef struct _FrameInst {
00218     XimFrame Fr_template;
00219     ChainMgrRec cm;
00220     int cur_no;
00221 } FrameInstRec;
00222 
00223 typedef void  (*IterStartWatchProc)(
00224 #if NeedFunctionPrototypes
00225                                 Iter it, void* client_data
00226 #endif
00227                                 );
00228 
00229 typedef struct _Iter {
00230     XimFrame Fr_template;
00231     int max_count;
00232     Bool allow_expansion;
00233     ChainMgrRec cm;
00234     int cur_no;
00235     IterStartWatchProc start_watch_proc;
00236     void* client_data;
00237     Bool start_counter;
00238 } IterRec;
00239 
00240 typedef struct _FrameMgr {
00241     XimFrame frame;
00242     FrameInst fi;
00243     char* area;
00244     int idx;
00245     Bool byte_swap;
00246     int total_size;
00247     FrameIter iters;
00248 } FrameMgrRec;
00249 
00250 typedef union {
00251     int num;          /* For BARRAY and PAD */
00252     struct {          /* For COUNTER_* */
00253        Iter iter;        
00254        Bool is_byte_len;
00255     } counter;
00256 } XimFrameTypeInfoRec, *XimFrameTypeInfo;
00257 
00258 /* Special values */
00259 #define NO_VALUE -1
00260 #define NO_VALID_FIELD -2
00261 
00262 static FrameInst FrameInstInit(XimFrame frame);
00263 static void FrameInstFree(FrameInst fi);
00264 static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info);
00265 static XimFrameType FrameInstPeekNextType(FrameInst fi, XimFrameTypeInfo info);
00266 static FmStatus FrameInstSetSize(FrameInst fi, int num);
00267 static FmStatus FrameInstSetIterCount(FrameInst fi, int num);
00268 static int FrameInstGetTotalSize(FrameInst fi);
00269 static void FrameInstReset(FrameInst fi);
00270 
00271 static Iter IterInit(XimFrame frame, int count);
00272 static void IterFree(Iter it);
00273 static int FrameInstGetSize(FrameInst fi);
00274 static int IterGetSize(Iter it);
00275 static XimFrameType IterGetNextType(Iter it, XimFrameTypeInfo info);
00276 static XimFrameType IterPeekNextType(Iter it, XimFrameTypeInfo info);
00277 static FmStatus IterSetSize(Iter it, int num);
00278 static FmStatus IterSetIterCount(Iter it, int num);
00279 static int IterGetTotalSize(Iter it);
00280 static void IterReset(Iter it);
00281 static Bool IterIsLoopEnd(Iter it, Bool* myself);
00282 static void IterSetStartWatch(Iter it, IterStartWatchProc proc, void* client_data);
00283 static void _IterStartWatch(Iter it, void* client_data);
00284 
00285 static ExtraData ChainMgrGetExtraData(ChainMgr cm, int frame_no);
00286 static ExtraData ChainMgrSetData(ChainMgr cm, int frame_no,
00287                              ExtraDataRec data);
00288 static Bool ChainIterGetNext(ChainIter ci, int* frame_no, ExtraData d);
00289 static int _FrameInstIncrement(XimFrame frame, int count);
00290 static int _FrameInstDecrement(XimFrame frame, int count);
00291 static int _FrameInstGetItemSize(FrameInst fi, int cur_no);
00292 static Bool FrameInstIsIterLoopEnd(FrameInst fi);
00293 
00294 static FrameIter _FrameMgrAppendIter(FrameMgr fm, Iter it, int end);
00295 static FrameIter _FrameIterCounterIncr(FrameIter fitr, int i);
00296 static void _FrameMgrRemoveIter(FrameMgr fm, FrameIter it);
00297 static Bool _FrameMgrIsIterLoopEnd(FrameMgr fm);
00298 static Bool _FrameMgrProcessPadding(FrameMgr fm, FmStatus* status);
00299 
00300 #define IterGetIterCount(it) ((it)->allow_expansion ? \
00301                            NO_VALUE : (it)->max_count)
00302 
00303 #define IterFixIteration(it) ((it)->allow_expansion = False)
00304 
00305 #define IterSetStarter(it) ((it)->start_counter = True)
00306 
00307 #define ChainMgrInit(cm) (cm)->top = (cm)->tail = NULL
00308 #define ChainMgrFree(cm) {\
00309     Chain tmp, cur = (cm)->top;\
00310 \
00311     while (cur) {\
00312        tmp = cur->next;\
00313         delete cur;\
00314        cur = tmp;\
00315     }\
00316 }
00317 #define ChainIterInit(ci, cm) {\
00318     (ci)->cur = (cm)->top;\
00319 }
00320 /* ChainIterFree has nothing to do. */
00321 #define ChainIterFree(ci)
00322 
00323 #define FrameInstIsEnd(fi) ((fi)->Fr_template[(fi)->cur_no].type == EOL)
00324 
00325 static void FrameInstFree(FrameInst fi)
00326 {
00327     ChainIterRec ci;
00328     int frame_no;
00329     ExtraDataRec d;
00330 
00331     ChainIterInit(&ci, &fi->cm);
00332 
00333     while (ChainIterGetNext(&ci, &frame_no, &d)) {
00334        int type;
00335        type = fi->Fr_template[frame_no].type;
00336        if (type == ITER) {
00337            if (d.iter)
00338               IterFree(d.iter);
00339        } else if (type == POINTER) {
00340            if (d.fi)
00341               FrameInstFree(d.fi);
00342        }
00343     }
00344     ChainIterFree(&ci);
00345     ChainMgrFree(&fi->cm);
00346     delete fi;
00347 }
00348 
00349 static
00350 #if NeedFunctionPrototypes
00351 FrameMgr FrameMgrInit(XimFrame frame, char* area, Bool byte_swap)
00352 #else
00353 FrameMgr FrameMgrInit(frame, area, byte_swap)
00354 XimFrame frame;
00355 void* area;
00356 Bool byte_swap;
00357 #endif
00358 {
00359     FrameMgr fm;
00360 
00361     fm = new FrameMgrRec;
00362 
00363     fm->frame = frame;
00364     fm->fi = FrameInstInit(frame);
00365     fm->area = (char *)area;
00366     fm->idx = 0;
00367     fm->byte_swap = byte_swap;
00368     fm->total_size = NO_VALUE;
00369     fm->iters = NULL;
00370 
00371     return fm;
00372 }
00373 
00374 static
00375 #if NeedFunctionPrototypes
00376 void FrameMgrInitWithData(FrameMgr fm, XimFrame frame, void* area,
00377                        Bool byte_swap)
00378 #else
00379 void FrameMgrInitWithData(fm, frame, area, byte_swap)
00380 FrameMgr fm;
00381 XimFrame frame;
00382 void* area;
00383 Bool byte_swap;
00384 #endif
00385 {
00386     fm->frame = frame;
00387     fm->fi = FrameInstInit(frame);
00388     fm->area = (char *)area;
00389     fm->idx = 0;
00390     fm->byte_swap = byte_swap;
00391     fm->total_size = NO_VALUE;
00392 }
00393 
00394 static
00395 #if NeedFunctionPrototypes
00396 void FrameMgrFree(FrameMgr fm)
00397 #else
00398 void FrameMgrFree(fm)
00399 FrameMgr fm;
00400 #endif
00401 {
00402     FrameInstFree(fm->fi);
00403     if (fm->iters) {
00404        /* this does not often happen */
00405        FrameIter prev, p;
00406        for (prev = fm->iters; p = prev; ) {
00407            prev = p->next;
00408            delete p;
00409        }
00410     }
00411     delete fm;
00412 }
00413 
00414 static
00415 #if NeedFunctionPrototypes
00416 FmStatus FrameMgrSetBuffer(FrameMgr fm, void* area)
00417 #else
00418 FmStatus FrameMgrSetBuffer(fm, area)
00419 FrameMgr fm;
00420 void* area;
00421 #endif
00422 {
00423     if (fm->area) {
00424        return FmBufExist;
00425     }
00426     fm->area = (char *)area;
00427     return FmSuccess;
00428 }
00429 
00430 static
00431 #if NeedFunctionPrototypes
00432 FmStatus _FrameMgrPutToken(FrameMgr fm, void* data, int data_size)
00433 #else
00434 FmStatus _FrameMgrPutToken(fm, data, data_size)
00435 FrameMgr fm;
00436 void* data;
00437 int data_size;
00438 #endif
00439 {
00440     XimFrameType type;
00441     XimFrameTypeInfoRec info;
00442 
00443     if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size)
00444        return FmNoMoreData;
00445 
00446     type = FrameInstGetNextType(fm->fi, &info);
00447 
00448     if (type & COUNTER_MASK) {
00449        unsigned long input_length;
00450 
00451        if (info.counter.is_byte_len) {
00452            if ((input_length = IterGetTotalSize(info.counter.iter))
00453               == NO_VALUE) {
00454               return FmCannotCalc;
00455            }
00456        } else {
00457            if ((input_length = IterGetIterCount(info.counter.iter))
00458               == NO_VALUE) {
00459               return FmCannotCalc;
00460            }
00461        }
00462        if (type == COUNTER_BIT8) {
00463            *(CARD8*)(fm->area + fm->idx) = input_length;
00464            fm->idx++;
00465        } else if (type == COUNTER_BIT16) {
00466            *(CARD16*)(fm->area + fm->idx) = Swap16(fm, input_length);
00467            fm->idx += 2;
00468        } else if (type == COUNTER_BIT32) {
00469            *(CARD32*)(fm->area + fm->idx) = Swap32(fm, input_length);
00470            fm->idx += 4;
00471        }
00472        _FrameMgrPutToken(fm, data, data_size);
00473        return FmSuccess;
00474     }
00475 
00476     if (type == BIT8) {
00477        if (data_size == sizeof(unsigned char)) {
00478            unsigned long num = *(unsigned char*)data;
00479            *(CARD8*)(fm->area + fm->idx) = num;
00480        } else if (data_size == sizeof(unsigned short)) {
00481            unsigned long num = *(unsigned short*)data;
00482            *(CARD8*)(fm->area + fm->idx) = num;
00483        } else if (data_size == sizeof(unsigned int)) {
00484            unsigned long num = *(unsigned int*)data;
00485            *(CARD8*)(fm->area + fm->idx) = num;
00486        } else if (data_size == sizeof(unsigned long)) {
00487            unsigned long num = *(unsigned long*)data;
00488            *(CARD8*)(fm->area + fm->idx) = num;
00489        } else {
00490            ;/* Should never reached */
00491        }
00492        fm->idx++;
00493        return FmSuccess;
00494     } else if (type == BIT16) {
00495        if (data_size == sizeof(unsigned char)) {
00496            unsigned long num = *(unsigned char*)data;
00497            *(CARD16*)(fm->area + fm->idx) = Swap16(fm, num);
00498        } else if (data_size == sizeof(unsigned short)) {
00499            unsigned long num = *(unsigned short*)data;
00500            *(CARD16*)(fm->area + fm->idx) = Swap16(fm, num);
00501        } else if (data_size == sizeof(unsigned int)) {
00502            unsigned long num = *(unsigned int*)data;
00503            *(CARD16*)(fm->area + fm->idx) = Swap16(fm, num);
00504        } else if (data_size == sizeof(unsigned long)) {
00505            unsigned long num = *(unsigned long*)data;
00506            *(CARD16*)(fm->area + fm->idx) = Swap16(fm, num);
00507        } else {
00508            ;/* Should never reached */
00509        }
00510        fm->idx += 2;
00511        return FmSuccess;
00512     } else if (type == BIT32) {
00513        if (data_size == sizeof(unsigned char)) {
00514            unsigned long num = *(unsigned char*)data;
00515            *(CARD32*)(fm->area + fm->idx) = Swap32(fm, num);
00516        } else if (data_size == sizeof(unsigned short)) {
00517            unsigned long num = *(unsigned short*)data;
00518            *(CARD32*)(fm->area + fm->idx) = Swap32(fm, num);
00519        } else if (data_size == sizeof(unsigned int)) {
00520            unsigned long num = *(unsigned int*)data;
00521            *(CARD32*)(fm->area + fm->idx) = Swap32(fm, num);
00522        } else if (data_size == sizeof(unsigned long)) {
00523            unsigned long num = *(unsigned long*)data;
00524            *(CARD32*)(fm->area + fm->idx) = Swap32(fm, num);
00525        } else {
00526            ;/* Should never reached */
00527        }
00528        fm->idx += 4;
00529        return FmSuccess;
00530     }
00531      else if (type == BARRAY && info.num != NO_VALUE) {
00532        if (info.num > 0) {
00533            //memcpy(*(char**)data, fm->area + fm->idx, info.num);
00534            memcpy(fm->area + fm->idx, *(char**)data, info.num);
00535            fm->idx += info.num;
00536        }
00537        return FmSuccess;
00538     } else if (type == BARRAY && info.num == NO_VALUE) {
00539        return FmInvalidCall;
00540     } else if (type == PADDING && info.num != NO_VALUE) {
00541         fm->idx += info.num;
00542        return _FrameMgrPutToken(fm, data, data_size);
00543     } else if (type == PADDING && info.num == NO_VALUE) {
00544         return FmInvalidCall;
00545     } else if (type == ITER) {
00546        return FmInvalidCall;
00547     } else if (type == EOL) {
00548        return FmEOD;
00549     } else {
00550        ; /* Should never be reached */
00551     }
00552     return FmSuccess;
00553 }
00554 
00555 static
00556 #if NeedFunctionPrototypes
00557 FmStatus _FrameMgrGetToken(FrameMgr fm , void* data, int data_size)
00558 #else
00559 FmStatus _FrameMgrGetToken(fm, data, data_size)
00560 FrameMgr fm;
00561 void* data;
00562 int data_size;
00563 #endif
00564 {
00565     int type;
00566     static XimFrameTypeInfoRec info; /* memory */
00567     ExtraData d;
00568     FrameIter fitr;
00569 
00570     if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size)
00571        return FmNoMoreData;
00572 
00573     type = FrameInstGetNextType(fm->fi, &info);
00574 
00575     if (type & COUNTER_MASK) {
00576        int end;
00577        FrameIter client_data;
00578 
00579        type &= ~COUNTER_MASK;
00580        if (type == BIT8) {
00581            end = *(CARD8*)(fm->area + fm->idx);
00582        }
00583        else if (type == BIT16) {
00584            end = Swap16(fm, *(CARD16*)(fm->area + fm->idx));
00585        }
00586        else if (type == BIT32) {
00587            end = Swap32(fm, *(CARD32*)(fm->area + fm->idx));
00588        }
00589        if (client_data = _FrameMgrAppendIter(fm, info.counter.iter, end)) {
00590            IterSetStarter(info.counter.iter);
00591            IterSetStartWatch(info.counter.iter, 
00592                            _IterStartWatch, (void*)client_data);
00593        }
00594     }
00595 
00596     type &= ~COUNTER_MASK;
00597     if (type == BIT8) {
00598        if (data_size == sizeof(unsigned char)) {
00599            *(unsigned char*)data = *(CARD8*)(fm->area + fm->idx);
00600        } else if (data_size == sizeof(unsigned short)) {
00601            *(unsigned short*)data = *(CARD8*)(fm->area + fm->idx);
00602        } else if (data_size == sizeof(unsigned int)) {
00603            *(unsigned int*)data = *(CARD8*)(fm->area + fm->idx);
00604        } else if (data_size == sizeof(unsigned long)) {
00605            *(unsigned long*)data = *(CARD8*)(fm->area + fm->idx);
00606        } else {
00607            ;/* Should never reached */
00608        }
00609        fm->idx++;
00610        if (fitr = _FrameIterCounterIncr(fm->iters, 1/*BIT8*/)) {
00611            _FrameMgrRemoveIter(fm, fitr);
00612        }
00613        return FmSuccess;
00614     } else if (type == BIT16) {
00615        if (data_size == sizeof(unsigned char)) {
00616            *(unsigned char*)data =
00617               Swap16(fm, *(CARD16*)(fm->area + fm->idx));
00618        } else if (data_size == sizeof(unsigned short)) {
00619            *(unsigned short*)data =
00620               Swap16(fm, *(CARD16*)(fm->area + fm->idx));
00621        } else if (data_size == sizeof(unsigned int)) {
00622            *(unsigned int*)data =
00623               Swap16(fm, *(CARD16*)(fm->area + fm->idx));
00624        } else if (data_size == sizeof(unsigned long)) {
00625            *(unsigned long*)data =
00626               Swap16(fm, *(CARD16*)(fm->area + fm->idx));
00627        } else {
00628            ;/* Should never reached */
00629        }
00630        fm->idx += 2;
00631        if (fitr = _FrameIterCounterIncr(fm->iters, 2/*BIT16*/)) {
00632            _FrameMgrRemoveIter(fm, fitr);
00633        }
00634        return FmSuccess;
00635     } else if (type == BIT32) {
00636        if (data_size == sizeof(unsigned char)) {
00637            *(unsigned char*)data =
00638               Swap32(fm, *(CARD32*)(fm->area + fm->idx));
00639        } else if (data_size == sizeof(unsigned short)) {
00640            *(unsigned short*)data =
00641               Swap32(fm, *(CARD32*)(fm->area + fm->idx));
00642        } else if (data_size == sizeof(unsigned int)) {
00643            *(unsigned int*)data =
00644               Swap32(fm, *(CARD32*)(fm->area + fm->idx));
00645        } else if (data_size == sizeof(unsigned long)) {
00646            *(unsigned long*)data =
00647               Swap32(fm, *(CARD32*)(fm->area + fm->idx));
00648        } else {
00649            ;/* Should never reached */
00650        }
00651        fm->idx += 4;
00652        if (fitr = _FrameIterCounterIncr(fm->iters, 4/*BIT32*/)) {
00653            _FrameMgrRemoveIter(fm, fitr);
00654        }
00655        return FmSuccess;
00656     }
00657       else if (type == BARRAY && info.num != NO_VALUE) {
00658        if (info.num > 0) {
00659            *(char**)data = fm->area + fm->idx;
00660            fm->idx += info.num;
00661            if (fitr = _FrameIterCounterIncr(fm->iters, info.num)) {
00662               _FrameMgrRemoveIter(fm, fitr);
00663            }
00664        } else {
00665            *(char**)data = NULL;
00666        }
00667        return FmSuccess;
00668     } else if (type == BARRAY && info.num == NO_VALUE) {
00669        return FmInvalidCall;
00670     } else if (type == PADDING && info.num != NO_VALUE) {
00671         fm->idx += info.num;
00672        if (fitr = _FrameIterCounterIncr(fm->iters, info.num)) {
00673            _FrameMgrRemoveIter(fm, fitr);
00674        }
00675        return _FrameMgrGetToken(fm, data, data_size);
00676     } else if (type == PADDING && info.num == NO_VALUE) {
00677         return FmInvalidCall;
00678     } else if (type == ITER) {
00679        return FmInvalidCall;       /* if comes here, it's a bug! */
00680     } else if (type == EOL) {
00681        return FmEOD;
00682     } else {
00683        ; /* Should never be reached */
00684     }
00685     return FmSuccess;
00686 }
00687 
00688 
00689 static
00690 #if NeedFunctionPrototypes
00691 FmStatus FrameMgrSetSize(FrameMgr fm, int barray_size)
00692 #else
00693 FmStatus FrameMgrSetSize(fm, barray_size)
00694 FrameMgr fm;
00695 int barray_size;
00696 #endif
00697 {
00698     if (FrameInstSetSize(fm->fi, barray_size) == FmSuccess)
00699        return FmSuccess;
00700     else
00701        return FmNoMoreData;
00702 }
00703 
00704 
00705 static
00706 #if NeedFunctionPrototypes
00707 FmStatus FrameMgrSetIterCount(FrameMgr fm, int count)
00708 #else
00709 FmStatus FrameMgrSetIterCount(fm, count)
00710 FrameMgr fm;
00711 int count;
00712 #endif
00713 {
00714     if (FrameInstSetIterCount(fm->fi, count) == FmSuccess)
00715        return FmSuccess;
00716     else
00717        return FmNoMoreData;
00718 }
00719 
00720 static
00721 #if NeedFunctionPrototypes
00722 FmStatus FrameMgrSetTotalSize(FrameMgr fm, int total_size)
00723 #else
00724 FmStatus FrameMgrSetTotalSize(fm, total_size)
00725 FrameMgr fm;
00726 int total_size;
00727 #endif
00728 {
00729     fm->total_size = total_size;
00730     return FmSuccess;
00731 }
00732 
00733 static
00734 #if NeedFunctionPrototypes
00735 int FrameMgrGetTotalSize(FrameMgr fm)
00736 #else
00737 int FrameMgrGetTotalSize(fm)
00738 FrameMgr fm;
00739 #endif
00740 {
00741     return FrameInstGetTotalSize(fm->fi);
00742 }
00743 
00744 static
00745 #if NeedFunctionPrototypes
00746 int FrameMgrGetSize(FrameMgr fm)
00747 #else
00748 int FrameMgrGetSize(fm)
00749 FrameMgr fm;
00750 #endif
00751 {
00752     int ret_size;
00753 
00754     ret_size = FrameInstGetSize(fm->fi);
00755     if (ret_size == NO_VALID_FIELD)
00756        return NO_VALUE;
00757 
00758     return ret_size;
00759 }
00760 
00761 
00762 static
00763 #if NeedFunctionPrototypes
00764 FmStatus FrameMgrSkipToken(FrameMgr fm, int skip_count)
00765 #else
00766 FmStatus FrameMgrSkipToken(fm, skip_count)
00767 FrameMgr fm;
00768 int skip_count;
00769 #endif
00770 {
00771     int type;
00772     XimFrameTypeInfoRec info;
00773     int i;
00774 
00775     if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size)
00776        return FmNoMoreData;
00777 
00778     for (i = 0; i < skip_count; i++) {
00779        type = FrameInstGetNextType(fm->fi, &info);
00780        type &= ~COUNTER_MASK;
00781 
00782        if (type == BIT8) {
00783            fm->idx++;
00784        } else if (type == BIT16) {
00785            fm->idx += 2;
00786        } else if (type == BIT32) {
00787            fm->idx += 4;
00788        }
00789          else if (type == BARRAY && info.num != NO_VALUE) {
00790            fm->idx += info.num;
00791        } else if (type == BARRAY && info.num == NO_VALUE) {
00792            return FmInvalidCall;
00793        } else if (type == PADDING && info.num != NO_VALUE) {
00794            fm->idx += info.num;
00795            return FrameMgrSkipToken(fm, skip_count);
00796        } else if (type == PADDING && info.num == NO_VALUE) {
00797            return FmInvalidCall;
00798        } else if (type == ITER) {
00799            return FmInvalidCall;
00800        } else if (type == EOL) {
00801            return FmEOD;
00802        } else {
00803            ; /* Should never be reached */
00804        }
00805     }
00806     return FmSuccess;
00807 }
00808 
00809 static
00810 #if NeedFunctionPrototypes
00811 void FrameMgrReset(FrameMgr fm)
00812 #else
00813 void FrameMgrReset(fm)
00814 FrameMgr fm;
00815 #endif
00816 {
00817     fm->idx = 0;
00818     FrameInstReset(fm->fi);
00819 }
00820 
00821 
00822 static
00823 #if NeedFunctionPrototypes
00824 Bool FrameMgrIsIterLoopEnd(FrameMgr fm, FmStatus* status)
00825 #else
00826 Bool FrameMgrIsIterLoopEnd(fm, status)
00827 FrameMgr fm;
00828 FmStatus* status;
00829 #endif
00830 {
00831     do {
00832        if (_FrameMgrIsIterLoopEnd(fm)) {
00833            return(True);
00834        }
00835     } while (_FrameMgrProcessPadding(fm, status));
00836     
00837     return(False);
00838 }
00839 
00840 
00841 /* Internal routines */
00842 
00843 #if NeedFunctionPrototypes
00844 static Bool _FrameMgrIsIterLoopEnd(FrameMgr fm)
00845 #else
00846 static Bool _FrameMgrIsIterLoopEnd(fm)
00847 FrameMgr fm;
00848 #endif
00849 {
00850     return(FrameInstIsIterLoopEnd(fm->fi));
00851 }
00852 
00853 
00854 #if NeedFunctionPrototypes
00855 static Bool _FrameMgrProcessPadding(FrameMgr fm, FmStatus* status)
00856 #else
00857 static Bool _FrameMgrProcessPadding(fm, status)
00858 FrameMgr fm;
00859 FmStatus* status;
00860 #endif
00861 {
00862     XimFrameTypeInfoRec info;
00863     XimFrameType next_type = FrameInstPeekNextType(fm->fi, &info);
00864     FrameIter fitr;
00865 
00866     if ((next_type == PADDING) && (info.num != NO_VALUE)) {
00867         next_type = FrameInstGetNextType(fm->fi, &info);
00868         fm->idx += info.num;
00869        if (fitr = _FrameIterCounterIncr(fm->iters, info.num)) {
00870            _FrameMgrRemoveIter(fm, fitr);
00871        }
00872        *status = FmSuccess;
00873        return(True);
00874     } 
00875     else if ((next_type == PADDING) && (info.num == NO_VALUE)) {
00876        *status = FmInvalidCall;
00877        return(True);
00878     }
00879     else {
00880        *status = FmSuccess;
00881        return(False);
00882     }
00883 }
00884 
00885 
00886 #if NeedFunctionPrototypes
00887 static FrameInst FrameInstInit(XimFrame frame)
00888 #else
00889 static FrameInst FrameInstInit(frame)
00890 XimFrame frame;
00891 #endif
00892 {
00893     FrameInst fi;
00894     int i;
00895 
00896     fi = new FrameInstRec;
00897 
00898     fi->Fr_template = frame;
00899     fi->cur_no = 0;
00900     ChainMgrInit(&fi->cm);
00901     return fi;
00902 }
00903 
00904 #if NeedFunctionPrototypes
00905 static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info)
00906 #else
00907 static XimFrameType FrameInstGetNextType(fi, info)
00908 FrameInst fi;
00909 XimFrameTypeInfo info;
00910 #endif
00911 {
00912     int ret_type;
00913 
00914     ret_type = fi->Fr_template[fi->cur_no].type;
00915 
00916     switch (ret_type) {
00917       case BIT8 :
00918       case BIT16 :
00919       case BIT32 :
00920       case EOL :
00921        fi->cur_no = _FrameInstIncrement(fi->Fr_template, fi->cur_no);
00922        break;
00923 
00924       case COUNTER_BIT8 :
00925       case COUNTER_BIT16 :
00926       case COUNTER_BIT32 :
00927        if (info) {
00928            int offset, iter_idx;
00929 
00930            info->counter.is_byte_len = 
00931               ((int)fi->Fr_template[fi->cur_no].data & 0xff) == FmCounterByte;
00932            offset = (int)fi->Fr_template[fi->cur_no].data >> 8;
00933            iter_idx = fi->cur_no + offset;
00934            if (fi->Fr_template[iter_idx].type == ITER) {
00935               ExtraData d;
00936               ExtraDataRec dr;
00937 
00938               if ((d = ChainMgrGetExtraData(&fi->cm, iter_idx)) == NULL) {
00939                   dr.iter = IterInit(&fi->Fr_template[iter_idx + 1], NO_VALUE);
00940                   d = ChainMgrSetData(&fi->cm, iter_idx, dr);
00941               }
00942               info->counter.iter = d->iter;
00943            } else {
00944               /* Should not be reached here */
00945            }
00946        }
00947        fi->cur_no = _FrameInstIncrement(fi->Fr_template, fi->cur_no);
00948        break;
00949 
00950       case BARRAY :
00951        if (info) {
00952            ExtraData d;
00953 
00954            if ((d = ChainMgrGetExtraData(&fi->cm, fi->cur_no)) == NULL) {
00955               info->num = NO_VALUE;
00956            } else {
00957               info->num = d->num;
00958            }
00959        }
00960        fi->cur_no = _FrameInstIncrement(fi->Fr_template, fi->cur_no);
00961        break;
00962 
00963       case PADDING :
00964        if (info) {
00965            int unit, number, size, i;
00966 
00967            unit = _UNIT(fi->Fr_template[fi->cur_no].data);
00968            number = _NUMBER(fi->Fr_template[fi->cur_no].data);
00969            
00970            i = fi->cur_no;
00971            size = 0;
00972            while (number > 0) {
00973                i = _FrameInstDecrement(fi->Fr_template, i);
00974               size += _FrameInstGetItemSize(fi, i);
00975               number--;
00976            }
00977            info->num = (unit - (size % unit)) % unit;
00978        }
00979        fi->cur_no = _FrameInstIncrement(fi->Fr_template, fi->cur_no);
00980        break;
00981        
00982       case ITER :
00983        {
00984            ExtraData d;
00985            ExtraDataRec dr;
00986            XimFrameType sub_type;
00987 
00988 
00989            if ((d = ChainMgrGetExtraData(&fi->cm, fi->cur_no)) == NULL) {
00990               dr.iter = IterInit(&fi->Fr_template[fi->cur_no + 1], NO_VALUE);
00991               d = ChainMgrSetData(&fi->cm, fi->cur_no, dr);
00992            }
00993            sub_type = IterGetNextType(d->iter, info);
00994            if (sub_type == EOL) {
00995               fi->cur_no = _FrameInstIncrement(fi->Fr_template, fi->cur_no);
00996               ret_type = FrameInstGetNextType(fi, info);
00997            } else {
00998               ret_type = sub_type;
00999            }
01000        }
01001        break;
01002 
01003       case POINTER :
01004        {
01005            ExtraData d;
01006            ExtraDataRec dr;
01007            XimFrameType sub_type;
01008 
01009            if ((d = ChainMgrGetExtraData(&fi->cm, fi->cur_no)) == NULL) {
01010               dr.fi = FrameInstInit((XimFrame )fi->Fr_template[fi->cur_no + 1].data);
01011               d = ChainMgrSetData(&fi->cm, fi->cur_no, dr);
01012            }
01013            sub_type = FrameInstGetNextType(d->fi, info);
01014            if (sub_type == EOL) {
01015               fi->cur_no = _FrameInstIncrement(fi->Fr_template, fi->cur_no);
01016               ret_type = FrameInstGetNextType(fi, info);
01017            } else {
01018               ret_type = sub_type;
01019            }
01020        }
01021        break;
01022       default :
01023        /* Should never be reached */
01024        break;
01025     }
01026     return (XimFrameType)ret_type;
01027 }
01028 
01029 
01030 #if NeedFunctionPrototypes
01031 static XimFrameType FrameInstPeekNextType(FrameInst fi, XimFrameTypeInfo info)
01032 #else
01033 static XimFrameType FrameInstPeekNextType(fi, info)
01034 FrameInst fi;
01035 XimFrameTypeInfo info;
01036 #endif
01037 {
01038     int ret_type;
01039 
01040     ret_type = fi->Fr_template[fi->cur_no].type;
01041 
01042     switch (ret_type) {
01043       case BIT8 :
01044       case BIT16 :
01045       case BIT32 :
01046       case EOL :
01047        break;
01048 
01049       case COUNTER_BIT8 :
01050       case COUNTER_BIT16 :
01051       case COUNTER_BIT32 :
01052        if (info) {
01053            int offset, iter_idx;
01054 
01055            info->counter.is_byte_len = 
01056               ((int)fi->Fr_template[fi->cur_no].data & 0xff) == FmCounterByte;
01057            offset = (int)fi->Fr_template[fi->cur_no].data >> 8;
01058            iter_idx = fi->cur_no + offset;
01059            if (fi->Fr_template[iter_idx].type == ITER) {
01060               ExtraData d;
01061               ExtraDataRec dr;
01062 
01063               if ((d = ChainMgrGetExtraData(&fi->cm, iter_idx)) == NULL) {
01064                   dr.iter = IterInit(&fi->Fr_template[iter_idx + 1], NO_VALUE);
01065                   d = ChainMgrSetData(&fi->cm, iter_idx, dr);
01066               }
01067               info->counter.iter = d->iter;
01068            } else {
01069               /* Should not be reached here */
01070            }
01071        }
01072        break;
01073 
01074       case BARRAY :
01075        if (info) {
01076            ExtraData d;
01077 
01078            if ((d = ChainMgrGetExtraData(&fi->cm, fi->cur_no)) == NULL) {
01079               info->num = NO_VALUE;
01080            } else {
01081               info->num = d->num;
01082            }
01083        }
01084        break;
01085 
01086       case PADDING :
01087        if (info) {
01088            int unit, number, size, i;
01089 
01090            unit = _UNIT(fi->Fr_template[fi->cur_no].data);
01091            number = _NUMBER(fi->Fr_template[fi->cur_no].data);
01092            
01093            i = fi->cur_no;
01094            size = 0;
01095            while (number > 0) {
01096                i = _FrameInstDecrement(fi->Fr_template, i);
01097               size += _FrameInstGetItemSize(fi, i);
01098               number--;
01099            }
01100            info->num = (unit - (size % unit)) % unit;
01101        }
01102        break;
01103        
01104       case ITER :
01105        {
01106            ExtraData d;
01107            ExtraDataRec dr;
01108            XimFrameType sub_type;
01109 
01110 
01111            if ((d = ChainMgrGetExtraData(&fi->cm, fi->cur_no)) == NULL) {
01112               dr.iter = IterInit(&fi->Fr_template[fi->cur_no + 1], NO_VALUE);
01113               d = ChainMgrSetData(&fi->cm, fi->cur_no, dr);
01114            }
01115            sub_type = IterPeekNextType(d->iter, info);
01116            if (sub_type == EOL) {
01117               ret_type = FrameInstPeekNextType(fi, info);
01118            } else {
01119               ret_type = sub_type;
01120            }
01121        }
01122        break;
01123 
01124       case POINTER :
01125        {
01126            ExtraData d;
01127            ExtraDataRec dr;
01128            XimFrameType sub_type;
01129 
01130            if ((d = ChainMgrGetExtraData(&fi->cm, fi->cur_no)) == NULL) {
01131               dr.fi = FrameInstInit((XimFrame )fi->Fr_template[fi->cur_no + 1].data);
01132               d = ChainMgrSetData(&fi->cm, fi->cur_no, dr);
01133            }
01134            sub_type = FrameInstPeekNextType(d->fi, info);
01135            if (sub_type == EOL) {
01136               ret_type = FrameInstPeekNextType(fi, info);
01137            } else {
01138               ret_type = sub_type;
01139            }
01140        }
01141        break;
01142       default :
01143        /* If comes here, bug! */
01144        break;
01145     }
01146     return (XimFrameType)ret_type;
01147 }
01148 
01149 
01150 #if NeedFunctionPrototypes
01151 static Bool FrameInstIsIterLoopEnd(FrameInst fi)
01152 #else
01153 static Bool FrameInstIsIterLoopEnd(fi)
01154 FrameInst fi;
01155 #endif
01156 {
01157     Bool ret = False;
01158 
01159     if (fi->Fr_template[fi->cur_no].type == ITER) {
01160        ExtraData d = ChainMgrGetExtraData(&fi->cm, fi->cur_no);
01161        Bool yourself;
01162 
01163        if (d) {
01164            ret = IterIsLoopEnd(d->iter, &yourself);
01165            if (ret && yourself) {
01166               fi->cur_no = _FrameInstIncrement(fi->Fr_template, fi->cur_no);
01167            }
01168        }
01169     }
01170 
01171     return(ret);
01172 }
01173 
01174 #if NeedFunctionPrototypes
01175 static FrameIter _FrameMgrAppendIter(FrameMgr fm, Iter it, int end)
01176 #else
01177 static FrameIter _FrameMgrAppendIter(fm, it, end)
01178 FrameMgr fm;
01179 Iter it;
01180 int end;
01181 #endif
01182 {
01183     FrameIter p = fm->iters;
01184 
01185     while (p && p->next) {
01186        p = p->next;
01187     }
01188     if (!p) {
01189        fm->iters = p = new FrameIterRec;
01190     }
01191     else {
01192       p->next = (FrameIter)new FrameIterRec;
01193       p = p->next;
01194     }
01195     if (p) {
01196        p->iter = it;
01197        p->counting = False;
01198        p->counter = 0;
01199        p->end = end;
01200        p->next = NULL;
01201     }
01202 
01203     return(p);
01204 }
01205 
01206 
01207 #if NeedFunctionPrototypes
01208 static void _FrameMgrRemoveIter(FrameMgr fm, FrameIter it)
01209 #else
01210 static void _FrameMgrRemoveIter(fm, it)
01211 FrameMgr fm;
01212 FrameIter it;
01213 #endif
01214 {
01215     FrameIter prev, p;
01216 
01217     prev = NULL;
01218     p = fm->iters;
01219     while (p) {
01220        if (p == it) {
01221            if (prev) {
01222               prev->next = p->next;
01223            }
01224            else {
01225               fm->iters = p->next;
01226            }
01227            delete p;
01228            break;
01229        }
01230        else {
01231            prev = p;
01232            p = p->next;
01233        }
01234     }
01235 }
01236 
01237 
01238 #if NeedFunctionPrototypes
01239 static FrameIter _FrameIterCounterIncr(FrameIter fitr, int i)
01240 #else
01241 static FrameIter _FrameIterCounterIncr(fitr, i)
01242 FrameIter fitr;
01243 int i;
01244 #endif
01245 {
01246     FrameIter p = fitr;
01247 
01248     while (p) {
01249        if (p->counting) {
01250            p->counter += i;
01251            if (p->counter >= p->end) {
01252               IterFixIteration(p->iter);
01253               return(p);
01254            }
01255        }
01256        p = p->next;
01257     }
01258     return(NULL);
01259 }
01260 
01261 
01262 #if NeedFunctionPrototypes
01263 static void _IterStartWatch(Iter it, void* client_data)
01264 #else
01265 static void _IterStartWatch(it, client_data)
01266 Iter it;
01267 void* client_data;
01268 #endif
01269 {
01270     FrameIter p = (FrameIter)client_data;
01271     p->counting = True;
01272 }
01273 
01274 
01275 #if NeedFunctionPrototypes
01276 static FmStatus FrameInstSetSize(FrameInst fi, int num)
01277 #else
01278 static FmStatus FrameInstSetSize(fi, num)
01279 FrameInst fi;
01280 int num;
01281 #endif
01282 {
01283     ChainIterRec ci;
01284     ExtraData d;
01285     ExtraDataRec dr;
01286     int type;
01287     int i;
01288 
01289     i = 0;
01290     while ((type = fi->Fr_template[i].type) != EOL) {
01291        if (type == BARRAY) {
01292            if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) {
01293               dr.num = -1;
01294               d = ChainMgrSetData(&fi->cm, i, dr);
01295            }
01296            if (d->num == NO_VALUE) {
01297               d->num = num;
01298               return FmSuccess;
01299            }
01300        } else if (type == ITER) {
01301            if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) {
01302               dr.iter = IterInit(&fi->Fr_template[i + 1], NO_VALUE);
01303               d = ChainMgrSetData(&fi->cm, i, dr);
01304            }
01305            if (IterSetSize(d->iter, num) == FmSuccess) {
01306               return FmSuccess;
01307            }
01308        } else if (type == POINTER) {
01309            if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) {
01310               dr.fi = FrameInstInit((XimFrame )fi->Fr_template[i + 1].data);
01311               d = ChainMgrSetData(&fi->cm, i, dr);
01312            }
01313            if (FrameInstSetSize(d->fi, num) == FmSuccess) {
01314               return FmSuccess;
01315            }
01316        }
01317        i = _FrameInstIncrement(fi->Fr_template, i);
01318     }
01319     return FmNoMoreData;
01320 }
01321 
01322 
01323 #if NeedFunctionPrototypes
01324 static int FrameInstGetSize(FrameInst fi)
01325 #else
01326 static int FrameInstGetSize(fi)
01327 FrameInst fi;
01328 #endif
01329 {
01330     int type;
01331     int i;
01332     ExtraData d;
01333     ExtraDataRec dr;
01334 
01335     i = fi->cur_no;
01336     while ((type = fi->Fr_template[i].type) != EOL) {
01337        if (type == BARRAY) {
01338            if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) {
01339               return NO_VALUE;
01340            }
01341            return d->num;
01342        } else if (type == ITER) {
01343            int ret_size;
01344            if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) {
01345               dr.iter = IterInit(&fi->Fr_template[i + 1], NO_VALUE);
01346               d = ChainMgrSetData(&fi->cm, i, dr);
01347            }
01348            ret_size = IterGetSize(d->iter);
01349            if (ret_size != NO_VALID_FIELD)
01350               return ret_size;
01351        } else if (type == POINTER) {
01352            int ret_size;
01353            if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) {
01354               dr.fi = FrameInstInit((XimFrame )fi->Fr_template[i + 1].data);
01355               d = ChainMgrSetData(&fi->cm, i, dr);
01356            }
01357            ret_size = FrameInstGetSize(d->fi);
01358            if (ret_size != NO_VALID_FIELD)
01359                return ret_size;
01360        }
01361        i = _FrameInstIncrement(fi->Fr_template, i);
01362     }
01363     return NO_VALID_FIELD;
01364 }
01365 
01366 
01367 #if NeedFunctionPrototypes
01368 static FmStatus FrameInstSetIterCount(FrameInst fi, int num)
01369 #else
01370 static FmStatus FrameInstSetIterCount(fi, num)
01371 FrameInst fi;
01372 int num;
01373 #endif
01374 {
01375     ChainIterRec ci;
01376     ExtraData d;
01377     ExtraDataRec dr;
01378     int i;
01379     int type;
01380 
01381     i = 0;
01382     while ((type = fi->Fr_template[i].type) != EOL) {
01383        if (type == ITER) {
01384            if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) {
01385               dr.iter = IterInit(&fi->Fr_template[i + 1], num);
01386               (void)ChainMgrSetData(&fi->cm, i, dr);
01387               return FmSuccess;
01388            }
01389            if (IterSetIterCount(d->iter, num) == FmSuccess) {
01390               return FmSuccess;
01391            }
01392        } else if (type == POINTER) {
01393            if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) {
01394               dr.fi = FrameInstInit((XimFrame )fi->Fr_template[i + 1].data);
01395               d = ChainMgrSetData(&fi->cm, i, dr);
01396            }
01397            if (FrameInstSetIterCount(d->fi, num) == FmSuccess) {
01398               return FmSuccess;
01399            }
01400        }
01401        i = _FrameInstIncrement(fi->Fr_template, i);
01402     }
01403     return FmNoMoreData;
01404 }
01405 
01406 
01407 #if NeedFunctionPrototypes
01408 static int FrameInstGetTotalSize(FrameInst fi)
01409 #else
01410 static int FrameInstGetTotalSize(fi)
01411 FrameInst fi;
01412 #endif
01413 {
01414     int size, i;
01415 
01416     size = 0;
01417 
01418     i = 0;
01419 
01420     while (fi->Fr_template[i].type != EOL) {
01421         size += _FrameInstGetItemSize(fi, i);
01422        i = _FrameInstIncrement(fi->Fr_template, i);
01423     }
01424     return size;
01425 }
01426 
01427 
01428 #if NeedFunctionPrototypes
01429 static void FrameInstReset(FrameInst fi)
01430 #else
01431 static void FrameInstReset(fi)
01432 FrameInst fi;
01433 #endif
01434 {
01435     ChainIterRec ci;
01436     int frame_no;
01437     ExtraDataRec d;
01438 
01439     ChainIterInit(&ci, &fi->cm);
01440 
01441     while (ChainIterGetNext(&ci, &frame_no, &d)) {
01442        int type;
01443        type = fi->Fr_template[frame_no].type;
01444        if (type == ITER) {
01445            if (d.iter)
01446               IterReset(d.iter);
01447        } else if (type == POINTER) {
01448            if (d.fi)
01449               FrameInstReset(d.fi);
01450        }
01451     }
01452     ChainIterFree(&ci);
01453 
01454     fi->cur_no = 0;
01455 }
01456 
01457 
01458 #if NeedFunctionPrototypes
01459 static Iter IterInit(XimFrame frame, int count)
01460 #else
01461 static Iter IterInit(frame, count)
01462 XimFrame frame;
01463 int count;
01464 #endif
01465 {
01466     Iter it;
01467     int type;
01468 
01469     it = (Iter)new IterRec;
01470     it->Fr_template = frame;
01471     it->max_count = (count == NO_VALUE) ? 0 : count;
01472     it->allow_expansion = count == NO_VALUE;
01473     it->cur_no = 0;
01474     it->start_watch_proc = NULL;
01475     it->client_data = NULL;
01476     it->start_counter = False;
01477 
01478     type = frame->type;
01479     if (type & COUNTER_MASK) {  /* COUNTER_XXX cannot be an item of a ITER */
01480        delete it;
01481        return NULL;
01482     }
01483 
01484     if (type == BIT8 || type == BIT16 || type == BIT32
01485        ) {
01486        /* Do nothing */;
01487     } else if (type == BARRAY || type == ITER || type == POINTER) {
01488        ChainMgrInit(&it->cm);
01489     } else {
01490        delete it;
01491        return NULL;/* This should never occur */
01492     }
01493     return it;
01494 }
01495 
01496 
01497 #if NeedFunctionPrototypes
01498 static void IterFree(Iter it)
01499 #else
01500 static void IterFree(it)
01501 Iter it;
01502 #endif
01503 {
01504     if (it->Fr_template->type == BARRAY) {
01505        ChainMgrFree(&it->cm);
01506     } else if (it->Fr_template->type == ITER) {
01507        ChainIterRec ci;
01508        int count;
01509        ExtraDataRec d;
01510 
01511        ChainIterInit(&ci, &it->cm);
01512        while (ChainIterGetNext(&ci, &count, &d)) {
01513            IterFree(d.iter);
01514        }
01515        ChainIterFree(&ci);
01516        ChainMgrFree(&it->cm);
01517     } else if (it->Fr_template->type == POINTER) {
01518        ChainIterRec ci;
01519        int count;
01520        ExtraDataRec dr;
01521 
01522        ChainIterInit(&ci, &it->cm);
01523        while (ChainIterGetNext(&ci, &count, &dr)) {
01524            FrameInstFree(dr.fi);
01525        }
01526        ChainIterFree(&ci);
01527        ChainMgrFree(&it->cm);
01528     }
01529     delete it;
01530 }
01531 
01532 
01533 #if NeedFunctionPrototypes
01534 static Bool IterIsLoopEnd(Iter it, Bool* myself)
01535 #else
01536 static Bool IterIsLoopEnd(it, myself)
01537 Iter it;
01538 Bool* myself;
01539 #endif
01540 {
01541     Bool ret = False;
01542     *myself = False;
01543 
01544     if (!it->allow_expansion && (it->cur_no == it->max_count)) {
01545        *myself = True;
01546        ret = True;
01547     }
01548     else if (it->Fr_template->type == POINTER) {
01549        ExtraData d = ChainMgrGetExtraData(&it->cm, it->cur_no);
01550        if (d) {
01551            if (FrameInstIsIterLoopEnd(d->fi)) {
01552               ret = True;
01553            }
01554            else {
01555               if (FrameInstIsEnd(d->fi)) {
01556                   it->cur_no++;
01557                   if (!it->allow_expansion && (it->cur_no == it->max_count)) {
01558                      *myself = True;
01559                      ret = True;
01560                   }
01561               }
01562            }
01563        }
01564     }
01565     else if (it->Fr_template->type == ITER) {
01566        ExtraData d = ChainMgrGetExtraData(&it->cm, it->cur_no);
01567        if (d) {
01568            Bool yourself;
01569            if (IterIsLoopEnd(d->iter, &yourself)) {
01570               ret = True;
01571            }
01572        }
01573     }
01574 
01575     return(ret);
01576 }
01577 
01578 
01579 #if NeedFunctionPrototypes
01580 static XimFrameType IterGetNextType(Iter it, XimFrameTypeInfo info)
01581 #else
01582 static XimFrameType IterGetNextType(it, info)
01583 Iter it;
01584 XimFrameTypeInfo info;
01585 #endif
01586 {
01587     int type = it->Fr_template->type;
01588 
01589     if (it->start_counter) {
01590        (*it->start_watch_proc)(it, it->client_data);
01591        it->start_counter = False;
01592     }
01593 
01594     if (it->cur_no >= it->max_count) {
01595        if (it->allow_expansion) {
01596            it->max_count = it->cur_no + 1;
01597        } else {
01598            return EOL;
01599        }
01600     }
01601 
01602     if (type == BIT8 || type == BIT16 || type == BIT32
01603        ) {
01604        it->cur_no++;
01605        return (XimFrameType)type;
01606     } else if (type == BARRAY) {
01607        ExtraData d;
01608        ExtraDataRec dr;
01609 
01610        if (info) {
01611            if ((d = ChainMgrGetExtraData(&it->cm, it->cur_no)) == NULL) {
01612               info->num = NO_VALUE;
01613            } else {
01614               info->num = d->num;
01615            }
01616        }
01617        it->cur_no++;
01618        return BARRAY;
01619     } else if (type == ITER) {
01620        int ret_type;
01621        ExtraData d;
01622        ExtraDataRec dr;
01623 
01624        if ((d = ChainMgrGetExtraData(&it->cm, it->cur_no)) == NULL) {
01625            dr.iter = IterInit(it->Fr_template + 1, NO_VALUE);
01626            d = ChainMgrSetData(&it->cm, it->cur_no, dr);
01627        }
01628 
01629        ret_type = IterGetNextType(d->iter, info);
01630        if (ret_type == EOL) {
01631            it->cur_no++;
01632            ret_type = IterGetNextType(it, info);
01633        }
01634        return (XimFrameType)ret_type;
01635     } else if (type == POINTER) {
01636        XimFrameType ret_type;
01637        ExtraData d;
01638        ExtraDataRec dr;
01639 
01640        if ((d = ChainMgrGetExtraData(&it->cm, it->cur_no)) == NULL) {
01641            dr.fi = FrameInstInit((XimFrame )it->Fr_template[1].data);
01642            d = ChainMgrSetData(&it->cm, it->cur_no, dr);
01643        }
01644        
01645        ret_type = FrameInstGetNextType(d->fi, info);
01646        if (ret_type == EOL) {
01647            it->cur_no++;
01648            ret_type = IterGetNextType(it, info);
01649        }
01650        return ret_type;
01651     } else {
01652        ;/* This should never occur */
01653     }
01654     return EOL;
01655 }
01656 
01657 
01658 #if NeedFunctionPrototypes
01659 static XimFrameType IterPeekNextType(Iter it, XimFrameTypeInfo info)
01660 #else
01661 static XimFrameType IterPeekNextType(it, info)
01662 Iter it;
01663 XimFrameTypeInfo info;
01664 #endif
01665 {
01666     int type = it->Fr_template->type;
01667 
01668     if (!it->allow_expansion && (it->cur_no >= it->max_count)) {
01669        return(EOL);
01670     }
01671 
01672     if (type == BIT8 || type == BIT16 || type == BIT32) {
01673        return (XimFrameType)type;
01674     }
01675     else if (type == BARRAY) {
01676        ExtraData d;
01677        ExtraDataRec dr;
01678 
01679        if (info) {
01680            if ((d = ChainMgrGetExtraData(&it->cm, it->cur_no)) == NULL) {
01681               info->num = NO_VALUE;
01682            } else {
01683               info->num = d->num;
01684            }
01685        }
01686        return(BARRAY);
01687     }
01688     else if (type == ITER) {
01689        int ret_type;
01690        ExtraData d;
01691        ExtraDataRec dr;
01692 
01693        if ((d = ChainMgrGetExtraData(&it->cm, it->cur_no)) == NULL) {
01694            dr.iter = IterInit(it->Fr_template + 1, NO_VALUE);
01695            d = ChainMgrSetData(&it->cm, it->cur_no, dr);
01696        }
01697 
01698        ret_type = IterPeekNextType(d->iter, info);
01699        if (ret_type == EOL) {
01700            ret_type = IterPeekNextType(it, info);
01701        }
01702        return (XimFrameType)ret_type;
01703     }
01704     else if (type == POINTER) {
01705        int ret_type;
01706        ExtraData d;
01707        ExtraDataRec dr;
01708 
01709        if ((d = ChainMgrGetExtraData(&it->cm, it->cur_no)) == NULL) {
01710            dr.fi = FrameInstInit((XimFrame )it->Fr_template[1].data);
01711            d = ChainMgrSetData(&it->cm, it->cur_no, dr);
01712        }
01713        
01714        ret_type = FrameInstPeekNextType(d->fi, info);
01715        if (ret_type == EOL) {
01716            ret_type = IterPeekNextType(it, info);
01717        }
01718        return (XimFrameType)ret_type;
01719     }
01720     else {
01721        ;/* If comes here, bug! */
01722     }
01723     return EOL;
01724 }
01725 
01726 
01727 #if NeedFunctionPrototypes
01728 static FmStatus IterSetSize(Iter it, int num)
01729 #else
01730 static FmStatus IterSetSize(it, num)
01731 Iter it;
01732 int num;
01733 #endif
01734 {
01735     int type;
01736     int i;
01737 
01738     if (!it->allow_expansion && it->max_count == 0) {
01739        return FmNoMoreData;
01740     }
01741 
01742     type = it->Fr_template->type;
01743     if (type == BARRAY) {
01744        ExtraData d;
01745        ExtraDataRec dr;
01746        for (i = 0; i < it->max_count; i++) {
01747            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01748               dr.num = NO_VALUE;
01749               d = ChainMgrSetData(&it->cm, i, dr);
01750            }
01751            if (d->num == NO_VALUE) {
01752               d->num = num;
01753               return FmSuccess;
01754            }
01755        }
01756        if (it->allow_expansion) {
01757            ExtraDataRec dr;
01758            dr.num = num;
01759            (void)ChainMgrSetData(&it->cm, it->max_count, dr);
01760            it->max_count++;
01761 
01762            return FmSuccess;
01763        }
01764        return FmNoMoreData;
01765     } else if (type == ITER) {
01766        ExtraData d;
01767        ExtraDataRec dr;
01768        for (i = 0; i < it->max_count; i++) {
01769            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01770               dr.iter = IterInit(it->Fr_template + 1, NO_VALUE);
01771               d = ChainMgrSetData(&it->cm, i, dr);
01772            }
01773            if (IterSetSize(d->iter, num) == FmSuccess) {
01774               return FmSuccess;
01775            }
01776        }
01777        if (it->allow_expansion) {
01778            ExtraDataRec dr;
01779            dr.iter = IterInit(it->Fr_template + 1, NO_VALUE);
01780            (void)ChainMgrSetData(&it->cm, it->max_count, dr);
01781            it->max_count++;
01782 
01783            if (IterSetSize(dr.iter, num) == FmSuccess) {
01784               return FmSuccess;
01785            }
01786        }
01787        return FmNoMoreData;
01788     } else if (type == POINTER) {
01789        ExtraData d;
01790        ExtraDataRec dr;
01791        for (i = 0; i < it->max_count; i++) {
01792            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01793               dr.fi = FrameInstInit((XimFrame )it->Fr_template[1].data);
01794               d = ChainMgrSetData(&it->cm, i, dr);
01795            }
01796            if (FrameInstSetSize(d->fi, num) == FmSuccess) {
01797               return FmSuccess;
01798            }
01799        }
01800        if (it->allow_expansion) {
01801            ExtraDataRec dr;
01802            dr.fi = FrameInstInit((XimFrame )it->Fr_template[1].data);
01803            (void)ChainMgrSetData(&it->cm, it->max_count, dr);
01804            it->max_count++;
01805 
01806            if (FrameInstSetSize(dr.fi, num) == FmSuccess) {
01807               return FmSuccess;
01808            }
01809        }
01810        return FmNoMoreData;
01811     }
01812     return FmNoMoreData;
01813 }
01814 
01815 
01816 #if NeedFunctionPrototypes
01817 static int IterGetSize(Iter it)
01818 #else
01819 static int IterGetSize(it)
01820 Iter it;
01821 #endif
01822 {
01823     int i;
01824     ExtraData d;
01825     ExtraDataRec dr;
01826 
01827     if (it->cur_no >= it->max_count) {
01828        return NO_VALID_FIELD;
01829     }
01830 
01831     if (it->Fr_template->type == BARRAY) {
01832        if ((d = ChainMgrGetExtraData(&it->cm, it->cur_no)) == NULL) {
01833            return NO_VALUE;
01834        }
01835        return d->num;
01836     } else if (it->Fr_template->type == ITER) {
01837        for (i = it->cur_no; i < it->max_count; i++) {
01838            int ret_size;
01839            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01840               dr.iter = IterInit(it->Fr_template + 1, NO_VALUE);
01841               d = ChainMgrSetData(&it->cm, i, dr);
01842            }
01843            ret_size = IterGetSize(d->iter);
01844            if (ret_size == NO_VALID_FIELD)
01845               continue;
01846            else
01847               return ret_size;
01848        }
01849        return NO_VALID_FIELD;
01850     } else if (it->Fr_template->type == POINTER) {
01851        for (i = it->cur_no; i < it->max_count; i++) {
01852            int ret_size;
01853            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01854               dr.fi = FrameInstInit((XimFrame )it->Fr_template[1].data);
01855               d = ChainMgrSetData(&it->cm, i, dr);
01856            }
01857            ret_size = FrameInstGetSize(d->fi);
01858            if (ret_size == NO_VALID_FIELD)
01859               continue;
01860            else
01861               return ret_size;
01862        }
01863        return NO_VALID_FIELD;
01864     }
01865     return NO_VALID_FIELD;
01866 }
01867 
01868 
01869 #if NeedFunctionPrototypes
01870 static FmStatus IterSetIterCount(Iter it, int num)
01871 #else
01872 static FmStatus IterSetIterCount(it, num)
01873 Iter it;
01874 int num;
01875 #endif
01876 {
01877     XimFrameType type;
01878     int i;
01879 
01880     if (it->allow_expansion) {
01881        it->max_count = num;
01882        it->allow_expansion = False;
01883        return FmSuccess;
01884     }
01885 
01886     if (it->max_count == 0) {
01887        return FmNoMoreData;
01888     }
01889 
01890     if (it->Fr_template->type == ITER) {
01891        for (i = 0; i < it->max_count; i++) {
01892            ExtraData d;
01893            ExtraDataRec dr;
01894            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01895               dr.iter = IterInit(it->Fr_template + 1, num);
01896               (void)ChainMgrSetData(&it->cm, i, dr);
01897               return FmSuccess;
01898            }
01899            if (IterSetIterCount(d->iter, num) == FmSuccess)
01900               return FmSuccess;
01901        }
01902        if (it->allow_expansion) {
01903            ExtraDataRec dr;
01904            dr.iter = IterInit(it->Fr_template + 1, num);
01905            (void)ChainMgrSetData(&it->cm, it->max_count, dr);
01906            it->max_count++;
01907            
01908            return FmSuccess;
01909        }
01910     } else if (it->Fr_template->type == POINTER) {
01911        for (i = 0; i < it->max_count; i++) {
01912            ExtraData d;
01913            ExtraDataRec dr;
01914            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01915               dr.fi = FrameInstInit((XimFrame )it->Fr_template[1].data);
01916               d = ChainMgrSetData(&it->cm, i, dr);
01917            }
01918            if (FrameInstSetIterCount(d->fi, num) == FmSuccess)
01919               return FmSuccess;
01920        }
01921        if (it->allow_expansion) {
01922            ExtraDataRec dr;
01923            dr.fi = FrameInstInit((XimFrame )it->Fr_template[1].data);
01924            (void)ChainMgrSetData(&it->cm, it->max_count, dr);
01925            it->max_count++;
01926 
01927            if (FrameInstSetIterCount(dr.fi, num) == FmSuccess)
01928               return FmSuccess;
01929        }
01930     }
01931     return FmNoMoreData;
01932 }
01933 
01934 
01935 #if NeedFunctionPrototypes
01936 static int IterGetTotalSize(Iter it)
01937 #else
01938 static int IterGetTotalSize(it)
01939 Iter it;
01940 #endif
01941 {
01942     int size, i;
01943     int type;
01944 
01945     if (it->allow_expansion)
01946        return NO_VALUE;
01947     else if (it->max_count == 0)
01948        return 0;
01949 
01950     type = it->Fr_template->type;
01951 
01952     size = 0;
01953 
01954     if (type == BIT8)
01955        size = it->max_count;
01956     else if (type == BIT16)
01957        size = it->max_count * 2;
01958     else if (type == BIT32)
01959        size = it->max_count * 4;
01960     else if (type == BARRAY) {
01961        for (i = 0; i < it->max_count; i++) {
01962            int num;
01963            ExtraData d;
01964            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01965               return NO_VALUE;
01966            }
01967            if ((num = d->num) == NO_VALUE)
01968               return NO_VALUE;
01969            size += num;
01970        }
01971     } else if (type == ITER) {
01972        for (i = 0; i < it->max_count; i++) {
01973            int num;
01974            ExtraData d;
01975            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01976               return NO_VALUE;
01977            }
01978            if ((num = IterGetTotalSize(d->iter)) == NO_VALUE)
01979               return NO_VALUE;
01980            size += num;
01981        }
01982     } else if (type == POINTER) {
01983        for (i = 0; i < it->max_count; i++) {
01984            int num;
01985            ExtraData d;
01986            ExtraDataRec dr;
01987            if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) {
01988               dr.fi = FrameInstInit((XimFrame )it->Fr_template[1].data);
01989               d = ChainMgrSetData(&it->cm, i, dr);
01990            }
01991            if ((num = FrameInstGetTotalSize(d->fi)) == NO_VALUE)
01992               return NO_VALUE;
01993            size += num;
01994        }
01995     } else {
01996        ;/* Should never reached */
01997     }
01998     return size;
01999 }
02000 
02001 
02002 #if NeedFunctionPrototypes
02003 static void IterReset(Iter it)
02004 #else
02005 static void IterReset(it)
02006 Iter it;
02007 #endif
02008 {
02009     if (it->Fr_template->type == ITER) {
02010        ChainIterRec ci;
02011        int count;
02012        ExtraDataRec d;
02013 
02014        ChainIterInit(&ci, &it->cm);
02015        while (ChainIterGetNext(&ci, &count, &d)) {
02016            IterReset(d.iter);
02017        }
02018        ChainIterFree(&ci);
02019     } else if (it->Fr_template->type == POINTER) {
02020        ChainIterRec ci;
02021        int count;
02022        ExtraDataRec dr;
02023 
02024        ChainIterInit(&ci, &it->cm);
02025        while (ChainIterGetNext(&ci, &count, &dr)) {
02026            FrameInstReset(dr.fi);
02027        }
02028        ChainIterFree(&ci);
02029     }
02030     it->cur_no = 0;
02031 }
02032 
02033 
02034 #if NeedFunctionPrototypes
02035 static void IterSetStartWatch(Iter it, 
02036                            IterStartWatchProc proc, void* client_data)
02037 #else
02038 static void IterSetStartWatch(it, proc, client_data)
02039 Iter it;
02040 IterStartWatchProc proc;
02041 void* client_data;
02042 #endif
02043 {
02044     it->start_watch_proc = proc;
02045     it->client_data = client_data;
02046 }
02047 
02048 
02049 #if NeedFunctionPrototypes
02050 static ExtraData ChainMgrSetData(ChainMgr cm, int frame_no, ExtraDataRec data)
02051 #else
02052 static ExtraData ChainMgrSetData(cm, frame_no, data)
02053 ChainMgr cm;
02054 int frame_no;
02055 ExtraDataRec data;
02056 #endif
02057 {
02058     Chain cur = (Chain)new ChainRec;
02059 
02060     cur->frame_no = frame_no;
02061     cur->d = data;
02062     cur->next = NULL;
02063 
02064     if (cm->top == NULL) {
02065        cm->top = cm->tail = cur;
02066     } else {
02067        cm->tail->next = cur;
02068        cm->tail = cur;
02069     }
02070     return &cur->d;
02071 }
02072 
02073 
02074 #if NeedFunctionPrototypes
02075 static ExtraData ChainMgrGetExtraData(ChainMgr cm, int frame_no)
02076 #else
02077 static ExtraData ChainMgrGetExtraData(cm, frame_no)
02078 ChainMgr cm;
02079 int frame_no;
02080 #endif
02081 {
02082     Chain cur;
02083 
02084     cur = cm->top;
02085 
02086     while (cur) {
02087        if (cur->frame_no == frame_no) {
02088            return &cur->d;
02089        }
02090        cur = cur->next;
02091     }
02092     return NULL;
02093 }
02094 
02095 
02096 #if NeedFunctionPrototypes
02097 static Bool ChainIterGetNext(ChainIter ci, int* frame_no, ExtraData d)
02098 #else
02099 static Bool ChainIterGetNext(ci, frame_no, d)
02100 ChainIter ci;
02101 int* frame_no;
02102 ExtraData d;
02103 #endif
02104 {
02105     if (ci->cur == NULL)
02106        return False;
02107 
02108     *frame_no = ci->cur->frame_no;
02109     *d = ci->cur->d;
02110 
02111     ci->cur = ci->cur->next;
02112 
02113     return True;
02114 }
02115 
02116 
02117 #if NeedFunctionPrototypes
02118 static int _FrameInstIncrement(XimFrame frame, int count)
02119 #else
02120 static int _FrameInstIncrement(frame, count)
02121 XimFrame frame;
02122 int count;
02123 #endif
02124 {
02125     int type;
02126 
02127     type = frame[count].type;
02128     type &= ~COUNTER_MASK;
02129     
02130     switch (type) {
02131       case BIT8:
02132       case BIT16:
02133       case BIT32:
02134 #if 0 /* Temporary hack - 64 bit support */
02135       case BIT64:
02136 #endif
02137       case BARRAY:
02138       case PADDING:
02139        return count + 1;
02140       case POINTER:
02141        return count + 2;
02142       case ITER:
02143        return _FrameInstIncrement(frame, count + 1);
02144       default:
02145        break;
02146     }
02147     return -1;   /* Error */
02148 }
02149 
02150 
02151 #if NeedFunctionPrototypes
02152 static int _FrameInstDecrement(XimFrame frame, int count)
02153 #else
02154 static int _FrameInstDecrement(frame, count)
02155 XimFrame frame;
02156 int count;
02157 #endif
02158 {
02159     int i;
02160     int type;
02161 
02162     if (count == 0)
02163        return -1;   /* cannot decrement */
02164     else if (count == 1) {
02165        return 0;    /* BOGUS - It should check the contents of data */
02166     }
02167 
02168     type = frame[count - 2].type;
02169     type &= ~COUNTER_MASK;
02170 
02171     switch (type) {
02172       case BIT8:
02173       case BIT16:
02174       case BIT32:
02175       case BARRAY:
02176       case PADDING:
02177       case PTR_ITEM:
02178        return count - 1;
02179       case POINTER:
02180       case ITER:
02181        i = count - 3;
02182        while (i >= 0) {
02183            if (frame[i].type != ITER)
02184                return i + 1;
02185            i--;
02186        }
02187        return 0;
02188       default:
02189        break;
02190     }
02191     return -1;   /* Error */
02192 }
02193 
02194 
02195 #if NeedFunctionPrototypes
02196 static int _FrameInstGetItemSize(FrameInst fi, int cur_no)
02197 #else
02198 static int _FrameInstGetItemSize(fi, cur_no)
02199 FrameInst fi;
02200 int cur_no;
02201 #endif
02202 {
02203     int type;
02204 
02205     type = fi->Fr_template[cur_no].type;
02206     type &= ~COUNTER_MASK;
02207 
02208     switch (type) {
02209       case BIT8 :
02210        return 1;
02211       case BIT16 :
02212         return 2;
02213       case BIT32 :
02214        return 4;
02215       case BARRAY :
02216        {
02217          ExtraData d;
02218          
02219          if ((d = ChainMgrGetExtraData(&fi->cm, cur_no)) == NULL)
02220              return NO_VALUE;
02221          if (d->num == NO_VALUE)
02222              return NO_VALUE;
02223          return d->num;
02224        }
02225       case PADDING :
02226        {
02227          int unit, number, size, i;
02228 
02229          unit = _UNIT(fi->Fr_template[cur_no].data);
02230          number = _NUMBER(fi->Fr_template[cur_no].data);
02231 
02232          i = cur_no;
02233          size = 0;
02234          while (number > 0) {
02235              i = _FrameInstDecrement(fi->Fr_template, i);
02236              size += _FrameInstGetItemSize(fi, i);
02237              number--;
02238          }
02239          size = (unit - (size % unit)) % unit;
02240          return size;
02241        }
02242       case ITER :
02243        {
02244          ExtraData d;
02245          int sub_size;
02246          
02247          if ((d = ChainMgrGetExtraData(&fi->cm, cur_no)) == NULL)
02248              return NO_VALUE;
02249          sub_size = IterGetTotalSize(d->iter);
02250          if (sub_size == NO_VALUE)
02251              return NO_VALUE;
02252          return sub_size;
02253        }
02254       case POINTER :
02255        {
02256          ExtraData d;
02257          int sub_size;
02258 
02259          if ((d = ChainMgrGetExtraData(&fi->cm, cur_no)) == NULL)
02260              return NO_VALUE;
02261          sub_size = FrameInstGetTotalSize(d->fi);
02262          if (sub_size == NO_VALUE)
02263              return NO_VALUE;
02264          return sub_size;
02265        }
02266       default :
02267        break;
02268     }
02269     return NO_VALUE;
02270 }
02271 
02272 #define FrameMgrPutToken(fm, obj) _FrameMgrPutToken((fm), &(obj), sizeof(obj))
02273 #define FrameMgrGetToken(fm, obj) _FrameMgrGetToken((fm), &(obj), sizeof(obj))
02274 
02275 #endif /* FRAMEMGR_H */