/*****************************************************************************\ * * * SES CODECs * * * \*****************************************************************************/ /* This is #included by both sides of the SES connection * before including it you must define SES__CODEC_ERROR(); * additional parameters can be defined by SESCODECPAR and SESCODECPARD, see * beginning of file klsesi.c, actually using this file as a template. */ #ifndef SESCODECPAR #define SESCODECPAR #endif #ifndef SESCODECPARD #define SESCODECPARD #endif /*****************************************************************************\ * encoding/decoding data * \*****************************************************************************/ /* encodes / decodes data onto a byte stream at ptr, returns ptr afterwards * Supposes the room has already been reserved. * encoders are kept close to decoders for easier maintainance */ /*********************************************************************** Int */ kl_uchar * SES__EncodeInt(ptr, number) kl_uchar *ptr; int number; { SES_PS_Int ps = (SES_PS_Int) ptr; ps->type = SES_Int; ps->number = number; return ptr + SES_PS_Int_padlen; } kl_uchar * SES__DecodeInt(ptr, numberp SESCODECPAR) kl_uchar *ptr; int *numberp; SESCODECPARD { SES_PS_Int ps = (SES_PS_Int) ptr; if (ps->type != SES_Int) {SES__CODEC_ERROR(SES_Int, ps->type);} *numberp = ps->number; return ptr + SES_PS_Int_padlen; } /******************************************************************** String */ kl_uchar * SES__EncodeString(ptr, namelen, name) kl_uchar *ptr; int namelen; char *name; { SES_PS_String ps = (SES_PS_String) ptr; ps->type = SES_String; ps->length = namelen; memcpy(ps->string, name, namelen+1); return ptr + SES_PS_String_padlen(namelen); } /* warning: namep points on volatile storage copy or use before next decode */ kl_uchar * SES__DecodeString(ptr, namelenp, namep SESCODECPAR) kl_uchar *ptr; int *namelenp; kl_uchar **namep; SESCODECPARD { SES_PS_String ps = (SES_PS_String) ptr; if (ps->type != SES_String) {SES__CODEC_ERROR(SES_String, ps->type);} *namelenp = ps->length; *namep = ps->string; return ptr + SES_PS_String_padlen(*namelenp); } /********************************************************************** Atom */ kl_uchar * SES__EncodeAtom(ptr, name) kl_uchar *ptr; char *name; { SES_PS_Atom ps = (SES_PS_Atom) ptr; ps->type = SES_Atom; ps->length = strlen(name); memcpy(ps->string, name, ps->length+1); return ptr + SES_PS_Atom_padlen(ps->length); } /* warning: namep points on volatile storage copy or use before next decode */ kl_uchar * SES__DecodeAtom(ptr, namelenp, namep SESCODECPAR) kl_uchar *ptr; int *namelenp; kl_uchar **namep; SESCODECPARD { SES_PS_Atom ps = (SES_PS_Atom) ptr; if (ps->type != SES_Atom) {SES__CODEC_ERROR(SES_Atom, ps->type);} *namelenp = ps->length; *namep = ps->string; return ptr + SES_PS_Atom_padlen(*namelenp); } /************************************************************************ Id */ kl_uchar * SES__EncodeId(ptr, idtype, value) kl_uchar *ptr; int idtype; void *value; { SES_PS_Id ps = (SES_PS_Id) ptr; ps->type = SES_Id; ps->idtype = idtype; ps->value = value; return ptr + SES_PS_Id_padlen; } kl_uchar * SES__DecodeId(ptr, idtype, valuep SESCODECPAR) kl_uchar *ptr; int idtype; /* must be of this type */ void **valuep; SESCODECPARD { SES_PS_Id ps = (SES_PS_Id) ptr; if (ps->type != SES_Id) {SES__CODEC_ERROR(SES_Id, ps->type);} if (ps->idtype != idtype) {SES__CODEC_ERROR(idtype, ps->idtype);} *valuep = ps->value; return ptr + SES_PS_Id_padlen; } /* may be useful * parses any id type, and returns the actual type read */ kl_uchar * SES__DecodeAnyId(ptr, idtypep, valuep SESCODECPAR) kl_uchar *ptr; int *idtypep; /* returns type here */ void **valuep; SESCODECPARD { SES_PS_Id ps = (SES_PS_Id) ptr; if (ps->type != SES_Id) {SES__CODEC_ERROR(SES_Id, ps->type);} *idtypep = ps->idtype; *valuep = ps->value; return ptr + SES_PS_Id_padlen; } /******************************************************************* Boolean */ kl_uchar * SES__EncodeBoolean(ptr, number) kl_uchar *ptr; int number; { SES_PS_Boolean ps = (SES_PS_Boolean) ptr; ps->type = SES_Boolean; ps->number = number; return ptr + SES_PS_Boolean_padlen; } kl_uchar * SES__DecodeBoolean(ptr, numberp SESCODECPAR) kl_uchar *ptr; int *numberp; SESCODECPARD { SES_PS_Boolean ps = (SES_PS_Boolean) ptr; if (ps->type != SES_Boolean) {SES__CODEC_ERROR(SES_Boolean, ps->type);} *numberp = ps->number; return ptr + SES_PS_Boolean_padlen; } /********************************************************** Reals (Doubles) */ kl_uchar * SES__EncodeReal(ptr, number) kl_uchar *ptr; double number; { SES_PS_Real ps = (SES_PS_Real) ptr; ps->type = SES_Real; ps->number = number; return ptr + SES_PS_Real_padlen; } kl_uchar * SES__DecodeReal(ptr, numberp SESCODECPAR) kl_uchar *ptr; double *numberp; SESCODECPARD { SES_PS_Real ps = (SES_PS_Real) ptr; if (ps->type != SES_Real) {SES__CODEC_ERROR(SES_Real, ps->type);} *numberp = ps->number; return ptr + SES_PS_Real_padlen; } /*********************************************************************** Ptr */ kl_uchar * SES__EncodePtr(ptr, anyptr) kl_uchar *ptr; void *anyptr; { SES_PS_Ptr ps = (SES_PS_Ptr) ptr; ps->type = SES_Ptr; ps->ptr = anyptr; return ptr + SES_PS_Ptr_padlen; } kl_uchar * SES__DecodePtr(ptr, anyptrp SESCODECPAR) kl_uchar *ptr; void **anyptrp; SESCODECPARD { SES_PS_Ptr ps = (SES_PS_Ptr) ptr; if (ps->type != SES_Ptr) {SES__CODEC_ERROR(SES_Ptr, ps->type);} *anyptrp = ps->ptr; return ptr + SES_PS_Ptr_padlen; } /********************************************************************* ERROR */ kl_uchar * SES__EncodeERROR(ptr, number) kl_uchar *ptr; int number; { SES_PS_ERROR ps = (SES_PS_ERROR) ptr; ps->type = SES_ERROR; ps->errnum = number; return ptr + SES_PS_ERROR_padlen; } kl_uchar * SES__DecodeERROR(ptr, numberp SESCODECPAR) kl_uchar *ptr; int *numberp; SESCODECPARD { SES_PS_ERROR ps = (SES_PS_ERROR) ptr; if (ps->type != SES_ERROR) {SES__CODEC_ERROR(SES_ERROR, ps->type);} *numberp = ps->errnum; return ptr + SES_PS_ERROR_padlen; } /********************************************************************** List */ /* only the header. elements must be handled by application * on encoding, the length field should be filled later by the user, it is * NOT set by this function! */ kl_uchar * SES__EncodeList(ptr, size) kl_uchar *ptr; int size; { SES_PS_List ps = (SES_PS_List) ptr; ps->type = SES_List; ps->size = size; return ptr + SES_PS_ListEmpty_padlen; } kl_uchar * SES__DecodeList(ptr, sizep SESCODECPAR) kl_uchar *ptr; int *sizep; SESCODECPARD { SES_PS_List ps = (SES_PS_List) ptr; if (ps->type != SES_List) {SES__CODEC_ERROR(SES_List, ps->type);} *sizep = ps->size; return ptr + SES_PS_ListEmpty_padlen; } /********************************************************************* Cache */ kl_uchar * SES__EncodeCache(ptr, number) kl_uchar *ptr; int number; { SES_PS_Cache ps = (SES_PS_Cache) ptr; ps->type = SES_Cache; ps->id = number; return ptr + SES_PS_Cache_padlen; } kl_uchar * SES__DecodeCache(ptr, numberp SESCODECPAR) kl_uchar *ptr; int *numberp; SESCODECPARD { SES_PS_Cache ps = (SES_PS_Cache) ptr; if (ps->type != SES_Cache) {SES__CODEC_ERROR(SES_Cache, ps->type);} *numberp = ps->id; return ptr + SES_PS_Cache_padlen; } /******************************************************************** AtomId */ kl_uchar * SES__EncodeAtomId(ptr, number) kl_uchar *ptr; int number; { SES_PS_AtomId ps = (SES_PS_AtomId) ptr; ps->type = SES_AtomId; ps->id = number; return ptr + SES_PS_AtomId_padlen; } kl_uchar * SES__DecodeAtomId(ptr, numberp SESCODECPAR) kl_uchar *ptr; int *numberp; SESCODECPARD { SES_PS_AtomId ps = (SES_PS_AtomId) ptr; if (ps->type != SES_AtomId) {SES__CODEC_ERROR(SES_AtomId, ps->type);} *numberp = ps->id; return ptr + SES_PS_AtomId_padlen; } /*********************************************************************** END */ /* to add a codec for type XXX: * - add above the codec function pair SES__EncodeXXX SES__DecodeXXX * - define the data structure SES_PS_XXX in ses.h * - add the SES_XXX tag value in ses.h, increment SES_MAX_Builtins */