EVOLUTION-MANAGER
Edit File: ruseas.c
#include "csf.h" #include "csfimpl.h" static void UINT1tLdd(size_t nrCells, void *Buf) { size_t i; UINT1 *buf = (UINT1 *)Buf; for(i=0; i < (size_t)nrCells; i++) if (buf[i] != MV_UINT1) { buf[i] %= (UINT1)10; if (buf[i] == 0) buf[i] = MV_UINT1; } } static void INT2tLdd(size_t nrCells, void *Buf) { size_t i; INT2 *inBuf = (INT2 *)Buf; UINT1 *outBuf = (UINT1 *)Buf; for(i=0; i < (size_t)nrCells; i++) if (inBuf[i] != MV_INT2) { outBuf[i] = (UINT1)(ABS(inBuf[i]) % 10); if (outBuf[i] == 0) outBuf[i] = MV_UINT1; } else outBuf[i] = MV_UINT1; } #define TOBOOL(nr, buf, srcType)\ {\ size_t i;\ /* loop must be upward to prevent overwriting of values \ * not yet converted \ */ \ PRECOND(sizeof(srcType) >= sizeof(UINT1));\ for(i=0; i < (size_t)nr; i++)\ if (IS_MV_##srcType( ((srcType *)buf)+i) )\ ((UINT1 *)buf)[i] = MV_UINT1;\ else\ ((UINT1 *)buf)[i] = ((srcType *)buf)[i] != ZERO_##srcType;\ } static void INT1tBoolean(size_t nrCells, void *buf) { TOBOOL(nrCells, buf, INT1); } static void INT2tBoolean(size_t nrCells, void *buf) { TOBOOL(nrCells, buf, INT2); } static void INT4tBoolean(size_t nrCells, void *buf) { TOBOOL(nrCells, buf, INT4); } static void UINT1tBoolean(size_t nrCells, void *buf) { TOBOOL(nrCells, buf, UINT1); } static void UINT2tBoolean(size_t nrCells, void *buf) { TOBOOL(nrCells, buf, UINT2); } static void UINT4tBoolean(size_t nrCells, void *buf) { TOBOOL(nrCells, buf, UINT4); } static void REAL4tBoolean(size_t nrCells, void *buf) { TOBOOL(nrCells, buf, REAL4); } static void REAL8tBoolean(size_t nrCells, void *buf) { TOBOOL(nrCells, buf, REAL8); } #define CONV_BIG_TO_SMALL(nr, buf, destType, srcType)\ {\ size_t i;\ /* loop must be upward to prevent overwriting of values \ * not yet converted: \ */ \ PRECOND(sizeof(srcType) >= sizeof(destType)); /* upward loop OK */ \ for(i=0; i < (size_t)nr; i++)\ if (IS_MV_##srcType( ((srcType *)buf)+i) )\ SET_MV_##destType( ((destType *)buf)+i);\ else\ ((destType *)buf)[i] = (destType)(((srcType *)buf)[i]);\ } #define CONV_SMALL_TO_BIG(nr, buf, destType, srcType)\ {\ size_t i = (size_t)nr;\ /* loop must be downward to prevent overwriting of values \ * not yet converted: \ */ \ PRECOND(sizeof(srcType) <= sizeof(destType)); /* downward loop OK */ \ do { i--;\ if (IS_MV_##srcType( ((srcType *)buf)+i) )\ SET_MV_##destType( ((destType *)buf)+i);\ else\ ((destType *)buf)[i] = (destType)(((srcType *)buf)[i]);\ }while ( i != 0);\ } static void UINT1tINT4(size_t nrCells, void *buf) { CONV_SMALL_TO_BIG(nrCells, buf, INT4, UINT1);} static void UINT1tREAL4(size_t nrCells, void *buf) { CONV_SMALL_TO_BIG(nrCells, buf, REAL4, UINT1);} static void UINT1tREAL8(size_t nrCells, void *buf) { CONV_SMALL_TO_BIG(nrCells, buf, REAL8, UINT1);} static void INT4tUINT1(size_t nrCells, void *buf) { CONV_BIG_TO_SMALL(nrCells, buf, UINT1, INT4);} static void INT2tUINT1(size_t nrCells, void *buf) { CONV_BIG_TO_SMALL(nrCells, buf, UINT1, INT2);} static void UINT2tUINT1(size_t nrCells, void *buf) { CONV_BIG_TO_SMALL(nrCells, buf, UINT1, UINT2);} static void INT4tREAL4(size_t nrCells, void *buf) { CONV_BIG_TO_SMALL(nrCells, buf, REAL4, INT4);} static void INT4tREAL8(size_t nrCells, void *buf) { CONV_SMALL_TO_BIG(nrCells, buf, REAL8, INT4);} static void REAL4tUINT1(size_t nrCells, void *buf) { CONV_BIG_TO_SMALL(nrCells, buf, UINT1, REAL4);} static void REAL4tINT4(size_t nrCells, void *buf) { CONV_BIG_TO_SMALL(nrCells, buf, INT4, REAL4);} static void REAL4tREAL8(size_t nrCells, void *buf) { CONV_SMALL_TO_BIG(nrCells, buf, REAL8, REAL4);} static void REAL8tUINT1(size_t nrCells, void *buf) { CONV_BIG_TO_SMALL(nrCells, buf, UINT1, REAL8);} static void REAL8tINT4(size_t nrCells, void *buf) { CONV_BIG_TO_SMALL(nrCells, buf, INT4, REAL8);} static void REAL8tREAL4(size_t nrCells, void *buf) { CONV_BIG_TO_SMALL(nrCells, buf, REAL4, REAL8);} static void Transform2( size_t nrCells, void *buf, CSF_CR destCellRepr, CSF_CR currCellRepr); static void INT1tINT4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_INT4, CR_INT1);} static void INT1tREAL4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL4, CR_INT1);} static void INT1tREAL8(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL8, CR_INT1);} static void INT2tINT4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_INT4, CR_INT2);} static void INT2tREAL4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL4, CR_INT2);} static void INT2tREAL8(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL8, CR_INT2);} static void UINT2tINT4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_INT4, CR_UINT2);} static void UINT2tREAL4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL4, CR_UINT2);} static void UINT2tREAL8(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL8, CR_UINT2);} static void UINT4tREAL4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL4, CR_UINT4);} static void UINT4tREAL8(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL8, CR_UINT4);} static void ConvertToINT2( size_t nrCells, void *buf, CSF_CR src) { if (IS_SIGNED(src)) { POSTCOND(src == CR_INT1); CONV_SMALL_TO_BIG(nrCells,buf, INT2, INT1); } else { POSTCOND(src == CR_UINT1); CONV_SMALL_TO_BIG(nrCells,buf, INT2, UINT1); } } static void ConvertToINT4( size_t nrCells, void *buf, CSF_CR src) { if (IS_SIGNED(src)) { POSTCOND(src == CR_INT2); CONV_SMALL_TO_BIG(nrCells,buf, INT4, INT2); } else { POSTCOND(src == CR_UINT2); CONV_SMALL_TO_BIG(nrCells,buf, INT4, UINT2); } } static void UINT1tUINT2( size_t nrCells, void *buf) { CONV_SMALL_TO_BIG(nrCells, buf, UINT2, UINT1); } static void UINT2tUINT4( size_t nrCells, void *buf) { CONV_SMALL_TO_BIG(nrCells, buf, UINT4, UINT2); } static void ConvertToREAL4( size_t nrCells, void *buf, CSF_CR src) { size_t i; i = (size_t)nrCells; if (IS_SIGNED(src)) { POSTCOND(src == CR_INT4); INT4tREAL4(nrCells, buf); } else { POSTCOND(src == CR_UINT4); { do { i--; if ( ((UINT4 *)buf)[i] == MV_UINT4 ) ((UINT4 *)buf)[i] = MV_UINT4; else ((REAL4 *)buf)[i] = ((UINT4 *)buf)[i]; } while(i != 0); } } } static void Transform2( size_t nrCells, void *buf, CSF_CR destCellRepr, /* the output representation */ CSF_CR currCellRepr) /* at start of while this is the representation read in the MAP-file */ { /* subsequent looping changes the to the new * converted type */ while(currCellRepr != destCellRepr) { switch(currCellRepr) { case CR_INT1: ConvertToINT2(nrCells, buf, currCellRepr); currCellRepr = CR_INT2; break; case CR_INT2: ConvertToINT4(nrCells, buf, currCellRepr); currCellRepr = CR_INT4; break; case CR_INT4: ConvertToREAL4(nrCells, buf, currCellRepr); currCellRepr = CR_REAL4; break; case CR_UINT1: if (IS_SIGNED(destCellRepr)) { ConvertToINT2(nrCells, buf, currCellRepr); currCellRepr = CR_INT2; } else { UINT1tUINT2(nrCells, buf); currCellRepr = CR_UINT2; } break; case CR_UINT2: if (destCellRepr == CR_INT4) { ConvertToINT4(nrCells, buf, currCellRepr); currCellRepr = CR_INT4; } else { UINT2tUINT4(nrCells, buf); currCellRepr = CR_UINT4; } break; case CR_UINT4: ConvertToREAL4(nrCells, buf, currCellRepr); currCellRepr = CR_REAL4; break; default : POSTCOND(currCellRepr == CR_REAL4); REAL4tREAL8(nrCells, buf); currCellRepr = CR_REAL8; } } } /* OLD STUFF void TransForm( const MAP *map, size_t nrCells, void *buf) { Transform2(nrCells, buf, map->types[READ_AS], map->types[STORED_AS]); } */ #define illegal NULL #define same CsfDummyConversion static const CSF_CONV_FUNC ConvTable[8][8] = { /* ConvTable[source][destination] */ /* INT1 , INT2 , INT4 , UINT1 , UINT2 , UINT4 , REAL4 , REAL8 */ /* 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ind */ /* 0x04 , 0x05 , 0x06 , 0x00 , 0x01 , 0x02 , 0x0A , 0x0B low-nib */ { same , illegal , INT1tINT4 , illegal , illegal , illegal , INT1tREAL4, INT1tREAL8}, /* INT1 */ { illegal , same , INT2tINT4 ,INT2tUINT1 , illegal , illegal , INT2tREAL4, INT2tREAL8}, /* INT2 */ { illegal , illegal , same ,INT4tUINT1 , illegal , illegal , INT4tREAL4, INT4tREAL8}, /* INT4 */ { illegal , illegal ,UINT1tINT4 , same ,UINT1tUINT2, illegal ,UINT1tREAL4,UINT1tREAL8}, /* UINT1 */ { illegal , illegal ,UINT2tINT4 , UINT2tUINT1 , same ,UINT2tUINT4,UINT2tREAL4,UINT2tREAL8}, /* UINT2 */ { illegal , illegal , illegal , illegal , illegal , same ,UINT4tREAL4,UINT4tREAL8}, /* UINT4 */ { illegal , illegal ,REAL4tINT4 ,REAL4tUINT1, illegal , illegal , same ,REAL4tREAL8}, /* REAL4 */ { illegal , illegal ,REAL8tINT4 ,REAL8tUINT1, illegal , illegal ,REAL8tREAL4, same } /* REAL8 */ }; static const CSF_CONV_FUNC boolConvTable[8] = { INT1tBoolean, INT2tBoolean, INT4tBoolean, UINT1tBoolean, UINT2tBoolean, UINT4tBoolean, REAL4tBoolean, REAL8tBoolean }; static const char convTableIndex[12] = { 3 /* UINT1 */, 4 /* UINT2 */, 5 /* UINT4 */, -1 /* 0x03 */, 0 /* INT1 */, 1 /* INT2 */, 2 /* INT4 */, -1 /* 0x07 */, -1 /* 0x08 */, -1 /* 0x09 */, 6 /* REAL4 */, 7 /* REAL8 */ }; static CSF_CONV_FUNC ConvFuncBool(CSF_CR cr) { PRECOND(CSF_UNIQ_CR_MASK(cr) < 12); PRECOND(convTableIndex[CSF_UNIQ_CR_MASK(cr)] != -1); return boolConvTable[(int)convTableIndex[CSF_UNIQ_CR_MASK(cr)]]; } static CSF_CONV_FUNC ConvFunc(CSF_CR destType, CSF_CR srcType) { PRECOND(CSF_UNIQ_CR_MASK(destType) < 12); PRECOND(CSF_UNIQ_CR_MASK(srcType) < 12); PRECOND(convTableIndex[CSF_UNIQ_CR_MASK(srcType)] != -1); PRECOND(convTableIndex[CSF_UNIQ_CR_MASK(destType)] != -1); /* don't complain on illegal, it can be attached * to a app2file while there's no WRITE_MODE * if it's an error then it's catched in RputSomeCells */ return ConvTable[(int)convTableIndex[CSF_UNIQ_CR_MASK(srcType)]] [(int)convTableIndex[CSF_UNIQ_CR_MASK(destType)]]; } static int HasInFileCellReprType2(CSF_CR cr) { char type2[12] = { 1 /* UINT1 */, 0 /* UINT2 */, 0 /* UINT4 */, 0 /* 0x03 */, 0 /* INT1 */, 0 /* INT2 */, 1 /* INT4 */, 0 /* 0x07 */, 0 /* 0x08 */, 0 /* 0x09 */, 1 /* REAL4 */, 1 /* REAL8 */}; PRECOND(CSF_UNIQ_CR_MASK(cr) < 12); return (int)type2[CSF_UNIQ_CR_MASK(cr)]; } /* set the cell representation the application will use * RuseAs enables an application to use cell values * in a different format than they are stored in the map. * Cell values are converted when getting (Rget*-functions) and * putting (Rput*-functions) cells if necessary. * Thus no conversions are applied if cell representation and/or * value scale already match. * Any conversions between the version 2 cell representations, * (CR_UINT1, CR_INT4, CR_REAL4 and CR_REAL8) is possible. * Conversion from a non version 2 cell representation to a version * 2 cell representation is only possible when you don't * have write access to the cells. * Conversion rules are exactly as described in K&R 2nd edition section A6. * * Two special conversions are possible if you don't * have write access to the cells or if the in-file cell representation is * UINT1: * (1) VS_BOOLEAN: successive calls to the Rget*-functions returns the result of * value != 0 * , that is 0 or 1 in UINT1 format. The in-file cell representation can be * anything, except if the value scale is VS_DIRECTION or VS_LDD. * (2) VS_LDD: successive calls to the Rget*-functions returns the result of * value % 10 * , that is 1 to 9 in UINT1 format (0's are set to MV_UINT1). * The in-file cell representation must be CR_UINT1 or CR_INT2 and * the value scale must be VS_LDD, VS_CLASSIFIED or VS_NOTDETERMINED. * * NOTE * that you must use Rmalloc() to get enough space for both the in-file and * app cell representation. * * returns * 0 if conversion obeys rules given here. 1 if not (conversions * will not take place). * * Merrno * CANT_USE_AS_BOOLEAN CANT_USE_WRITE_BOOLEAN * CANT_USE_WRITE_LDD * CANT_USE_AS_LDD * CANT_USE_WRITE_OLDCR * ILLEGAL_USE_TYPE * * EXAMPLE * .so examples/maskdump.tr */ int RuseAs( MAP *m, /* map handle */ CSF_CR useType) /* CR_UINT1,CR_INT4, CR_REAL4, CR_REAL8, VS_BOOLEAN or VS_LDD */ { CSF_CR inFileCR = RgetCellRepr(m); CSF_VS inFileVS = RgetValueScale(m); int hasInFileCellReprType2 = HasInFileCellReprType2(inFileCR); switch(useType) { case VS_BOOLEAN: switch(inFileVS) { case VS_LDD: case VS_DIRECTION: M_ERROR(CANT_USE_AS_BOOLEAN); return 1; case VS_BOOLEAN: POSTCOND(inFileCR == CR_UINT1); m->appCR = CR_UINT1; m->file2app = same; m->app2file = same; return 0; default: if ( (! hasInFileCellReprType2) && WRITE_ENABLE(m) ) { /* cellrepr is old one, we can't write that */ M_ERROR(CANT_USE_WRITE_BOOLEAN); return 1; } m->appCR = CR_UINT1; m->file2app = ConvFuncBool(inFileCR); m->app2file = ConvFunc(inFileCR, CR_UINT1); return 0; } /* case useType == VS_BOOLEAN */ break; case VS_LDD: switch(inFileVS) { case VS_LDD: POSTCOND(inFileCR == CR_UINT1); m->appCR = CR_UINT1; m->file2app = same; m->app2file = same; return 0; case VS_CLASSIFIED: case VS_NOTDETERMINED: switch(inFileCR) { case CR_UINT1: m->appCR = CR_UINT1; m->file2app = UINT1tLdd; m->app2file = same; return 0; case CR_INT2: if (WRITE_ENABLE(m)) { M_ERROR(CANT_USE_WRITE_LDD); return 1; } m->appCR = CR_UINT1; m->file2app = INT2tLdd; m->app2file = illegal; return 0; default: assert( FALSE ); } default: M_ERROR(CANT_USE_AS_LDD); return 1; } /* case useType == VS_LDD */ break; case CR_UINT1: case CR_INT4 : case CR_REAL4: case CR_REAL8: if ( (! hasInFileCellReprType2) && WRITE_ENABLE(m) ) { /* cellrepr is old one, we can't write that */ M_ERROR(CANT_USE_WRITE_OLDCR); return 1; } m->appCR = useType; m->file2app = ConvFunc(useType, inFileCR); m->app2file = ConvFunc(inFileCR, useType); POSTCOND(m->file2app != NULL); return 0; default: M_ERROR(ILLEGAL_USE_TYPE); return 1; } /* NOTREACHED */ }