G:/ScriptBasic/source/extensions/t/interface.c

Go to the documentation of this file.
00001 /*
00002 FILE: tools.c
00003 
00004 ScriptBasic module with handy functions.
00005 
00006 NTLIBS:
00007 UXLIBS:
00008 DWLIBS:
00009 MCLIBS:
00010 
00011 */
00012 
00024 #include <stdio.h>
00025 #include "../../basext.h"
00026 
00027 besVERSION_NEGOTIATE
00028 
00029   return (int)INTERFACE_VERSION;
00030 
00031 besEND
00032 
00033 besSUB_START
00034 besEND
00035 
00036 besSUB_FINISH
00037 besEND
00038 
00039 /*
00040 This function calculates the size in terms of bytes (or characters) of the
00041 variable after the conversion. This is needed to allocate the appropriate
00042 size of STRING variable into which the program can put the serialized data.
00043 
00044 The argument vVAR is the variable to be converted and pSt is the support table
00045 pointer.
00046 
00047 The return value is the size of the string converted.
00048 */
00049 static long sersize(VARIABLE vVAR, pSupportTable pSt){
00050   long i;
00051   unsigned long size;
00052 
00053   /* get the real variable in case this is a reference variable pointing to
00054      another variable */
00055   besDEREFERENCE(vVAR);
00056   /* undef is stored in one byte that tells this is undef */
00057   if( vVAR == NULL )return 1;
00058   switch( TYPE(vVAR) ){
00059     case VTYPE_ARRAY :
00060       /* we need 1 byte for the type 'array' and two longs for low and high limits */
00061       size = 2*sizeof(long)+1;
00062       for( i = vVAR->ArrayLowLimit ; i <= vVAR->ArrayHighLimit ; i++ ){
00063         size += sersize(vVAR->Value.aValue[i-vVAR->ArrayLowLimit],pSt);
00064         }
00065       return size;
00066     case VTYPE_LONG: return sizeof(long)+1;
00067     case VTYPE_DOUBLE: return sizeof(double)+1;
00068     case VTYPE_STRING: return sizeof(long)+STRLEN(vVAR)+1;
00069     default: return 0;
00070     }
00071   }
00072 
00073 static long serconv(VARIABLE vVAR, unsigned char *buf){
00074   long i;
00075   unsigned long size;
00076   unsigned long chunk;
00077 
00078   size = 0;
00079   if( vVAR == NULL ){
00080     *buf++ = VTYPE_UNDEF;
00081     return 1;
00082     }
00083   switch( TYPE(vVAR) ){
00084     case VTYPE_ARRAY :
00085       *buf++ = VTYPE_ARRAY;
00086       memcpy(buf,&(vVAR->ArrayLowLimit),sizeof(long));
00087       buf += sizeof(long);
00088       memcpy(buf,&(vVAR->ArrayHighLimit),sizeof(long));
00089       buf += sizeof(long);
00090       size = 2*sizeof(long)+1;
00091       for( i = vVAR->ArrayLowLimit ; i <= vVAR->ArrayHighLimit ; i++ ){
00092         chunk = serconv(vVAR->Value.aValue[i-vVAR->ArrayLowLimit],buf);
00093         buf += chunk;
00094         size += chunk;
00095         }
00096       return size;
00097     case VTYPE_LONG:
00098       *buf++ = VTYPE_LONG;
00099       memcpy(buf,&(LONGVALUE(vVAR)),sizeof(long));
00100       return sizeof(long)+1;
00101     case VTYPE_DOUBLE:
00102       *buf++ = VTYPE_DOUBLE;
00103       memcpy(buf,&(DOUBLEVALUE(vVAR)),sizeof(double));
00104       return sizeof(double)+1;
00105     case VTYPE_STRING:
00106       *buf++ = VTYPE_STRING;
00107       memcpy(buf,&(STRLEN(vVAR)),sizeof(long));
00108       buf += sizeof(long);
00109       memcpy(buf,STRINGVALUE(vVAR),STRLEN(vVAR));
00110       return sizeof(long)+STRLEN(vVAR)+1;
00111     default: return 0;
00112     }
00113   }
00114 
00115 static long serconvXML(VARIABLE vVAR, unsigned char *buf,int copy){
00116   long i;
00117   unsigned long size;
00118   unsigned long chunk;
00119   unsigned char szBuffer[100]; /* just a buffer to store decimal numbers */
00120 #define my_strcpy(a,b) do{if(copy)strcpy(a,b);}while(0)
00121   size = 0;
00122   if( vVAR == NULL ){
00123     my_strcpy(buf,"<U/>");
00124     buf += 4;
00125     return 4;
00126     }
00127   switch( TYPE(vVAR) ){
00128     case VTYPE_ARRAY :
00129       sprintf(szBuffer,"<A l=\"%d\" h=\"%d\">",vVAR->ArrayLowLimit,vVAR->ArrayHighLimit);
00130       my_strcpy(buf,szBuffer);
00131       buf += (size=strlen(szBuffer));
00132       for( i = vVAR->ArrayLowLimit ; i <= vVAR->ArrayHighLimit ; i++ ){
00133         chunk = serconvXML(vVAR->Value.aValue[i-vVAR->ArrayLowLimit],buf,copy);
00134         buf += chunk;
00135         size += chunk;
00136         }
00137       my_strcpy(buf,"</A>");
00138       buf += 4;
00139       size += 4;
00140       return size;
00141     case VTYPE_LONG:
00142       sprintf(szBuffer,"<I>%d</I>",LONGVALUE(vVAR));
00143       my_strcpy(buf,szBuffer);
00144       buf += (size=strlen(szBuffer));
00145       return size;
00146     case VTYPE_DOUBLE:
00147       sprintf(szBuffer,"<R>%f</R>",DOUBLEVALUE(vVAR));
00148       my_strcpy(buf,szBuffer);
00149       buf += (size=strlen(szBuffer));
00150       return size;
00151     case VTYPE_STRING:
00152       my_strcpy(buf,"<S>");
00153       buf += 3;
00154       size = 3;
00155       for( i=0 ; i < STRLEN(vVAR) ; i++ ){
00156         switch( STRINGVALUE(vVAR)[i] ) {
00157           case ';':  my_strcpy(buf,"&amp;");  buf += 5; size += 5; break;
00158           case '<':  my_strcpy(buf,"&lt;");   buf += 4; size += 4; break;
00159           case '>':  my_strcpy(buf,"&gt;");   buf += 4; size += 4; break;
00160           case '\"': my_strcpy(buf,"&quot;"); buf += 6; size += 6; break;
00161           default:
00162             if( (STRINGVALUE(vVAR)[i] < ' ') || (STRINGVALUE(vVAR)[i] > 127 ) ){
00163               sprintf(szBuffer, "&x%02X;", (unsigned char)(STRINGVALUE(vVAR)[i]) );
00164               my_strcpy(buf,szBuffer);
00165               buf  += (chunk=strlen(szBuffer));
00166               size += chunk;
00167             }else{
00168               if(copy)*buf++ = STRINGVALUE(vVAR)[i];
00169               size++;
00170             }
00171           }
00172         }
00173       my_strcpy(buf,"</S>");
00174       buf += 4;
00175       size += 4;
00176       return size;
00177     default: return 0;
00178     }
00179   }
00180 
00181 static VARIABLE unserconv(pExecuteObject pEo, unsigned char **buf,int *piError){
00182   long i;
00183   pSupportTable pSt;
00184   VARIABLE vRET;
00185   long ArrayLowLimit,ArrayHighLimit;
00186   unsigned long StringLen;
00187 
00188   pSt = pEo->pST;
00189   *piError = COMMAND_ERROR_SUCCESS;
00190   switch( **buf ){
00191     case VTYPE_ARRAY :
00192       (*buf)++;
00193       memcpy(&ArrayLowLimit,*buf,sizeof(long));
00194       (*buf) += sizeof(long);
00195       memcpy(&ArrayHighLimit,*buf,sizeof(long));
00196       (*buf) += sizeof(long);
00197       vRET = besNEWARRAY(ArrayLowLimit,ArrayHighLimit);
00198       if( vRET == NULL ){ *piError = COMMAND_ERROR_MEMORY_LOW; return NULL;}
00199       for( i = ArrayLowLimit ; i <= ArrayHighLimit ; i++ ){
00200         vRET->Value.aValue[i-ArrayLowLimit] = unserconv(pEo,buf,piError);
00201         }
00202       return vRET;
00203     case VTYPE_LONG:
00204       (*buf)++;
00205       vRET = besNEWLONG;
00206       if( vRET == NULL ){ *piError = COMMAND_ERROR_MEMORY_LOW; return NULL;}
00207       memcpy(&(LONGVALUE(vRET)),*buf,sizeof(long));
00208       (*buf) += sizeof(long);
00209       return vRET;
00210     case VTYPE_DOUBLE:
00211       (*buf)++;
00212       vRET = besNEWDOUBLE;
00213       if( vRET == NULL ){ *piError = COMMAND_ERROR_MEMORY_LOW; return NULL;}
00214       memcpy(&(DOUBLEVALUE(vRET)),*buf,sizeof(double));
00215       (*buf) += sizeof(double);
00216       return vRET;
00217     case VTYPE_STRING:
00218       (*buf)++;
00219       memcpy(&StringLen,*buf,sizeof(long));
00220       (*buf) += sizeof(long);
00221       vRET = besNEWSTRING(StringLen);
00222       if( vRET == NULL ){ *piError = COMMAND_ERROR_MEMORY_LOW; return NULL;}
00223       memcpy(STRINGVALUE(vRET),*buf,StringLen);
00224       (*buf) += StringLen;
00225       return vRET;
00226     case VTYPE_UNDEF:
00227       (*buf)++;
00228       return NULL;
00229     default: *piError = COMMAND_ERROR_ARGUMENT_RANGE;
00230              return NULL;
00231     }
00232   }
00233 
00250 besCOMMAND(serialize)
00251   NODE nItem;
00252   VARIABLE vARR;
00253   unsigned long size;
00254 
00255   besASSERT_COMMAND
00256 
00257   /* this is a function and not a command, therefore we do not have our own mortal list */
00258   USE_CALLER_MORTALS;
00259 
00260   /* evaluate the parameter */
00261   nItem = besPARAMETERLIST;
00262   if( ! nItem ){
00263     RESULT = NULL;
00264     RETURN;
00265     }
00266   vARR = _besEVALUATEEXPRESSION_A(CAR(nItem));
00267   ASSERTOKE;
00268   size = sersize(vARR,pSt);
00269   RESULT = besNEWMORTALSTRING(size);
00270   if( RESULT == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
00271   serconv(vARR,STRINGVALUE(RESULT));
00272 besEND_COMMAND
00273 
00298 besCOMMAND(xmlserialize)
00299   NODE nItem;
00300   VARIABLE vARR;
00301   unsigned long size;
00302 
00303   besASSERT_COMMAND
00304 
00305   /* this is a function and not a command, therefore we do not have our own mortal list */
00306   USE_CALLER_MORTALS;
00307 
00308   /* evaluate the parameter */
00309   nItem = besPARAMETERLIST;
00310   if( ! nItem ){
00311     RESULT = NULL;
00312     RETURN;
00313     }
00314   vARR = _besEVALUATEEXPRESSION_A(CAR(nItem));
00315   ASSERTOKE;
00316 #define XMLSTART "<?xml version=\"1.0\" encoding=\"UTF-8\"?><V>"
00317 #define XMLEND   "</V>"
00318   size = serconvXML(vARR,NULL,0) + strlen(XMLSTART) + strlen(XMLEND);
00319   RESULT = besNEWMORTALSTRING(size);
00320   if( RESULT == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
00321   strcpy(STRINGVALUE(RESULT),XMLSTART);
00322   serconvXML(vARR,STRINGVALUE(RESULT)+strlen(XMLSTART),1);
00323   strcat(STRINGVALUE(RESULT),XMLEND);
00324 besEND_COMMAND
00325 
00340 besFUNCTION(unserialize)
00341   VARIABLE Argument;
00342   LEFTVALUE Lval;
00343   int iError;
00344   unsigned long __refcount_;
00345   unsigned char *s;
00346 
00347   Argument = besARGUMENT(1);
00348   besLEFTVALUE(Argument,Lval);
00349   Argument = besARGUMENT(2);
00350   besDEREFERENCE(Argument);
00351   Argument = besCONVERT2STRING(Argument);
00352   s = STRINGVALUE(Argument);
00353   if( Lval ){
00354     besRELEASE(*Lval);
00355     *Lval = unserconv(pSt->pEo,&s,&iError);
00356     }
00357   return iError;
00358 besEND
00359 
00368 besFUNCTION(savestring)
00369   unsigned char *pszString;
00370   char *pszFileName;
00371   unsigned long cbString;
00372   FILE *fp;
00373   VARIABLE Argumentum;
00374 
00375   if( besARGNR < 2 )return COMMAND_ERROR_MANDARG;
00376 
00377   Argumentum = besARGUMENT(1);
00378   besDEREFERENCE(Argumentum);
00379   Argumentum = besCONVERT2STRING(Argumentum);
00380   besCONVERT2ZCHAR(Argumentum,pszFileName);
00381 
00382   Argumentum = besARGUMENT(2);
00383   besDEREFERENCE(Argumentum);
00384   Argumentum = besCONVERT2STRING(Argumentum);
00385 
00386   pszString = STRINGVALUE(Argumentum);
00387   cbString = STRLEN(Argumentum);
00388   fp = besHOOK_FOPEN(pszFileName,"wb");
00389   if( fp == NULL ){
00390     besFREE(pszFileName);
00391     return COMMAND_ERROR_FILE_CANNOT_BE_OPENED;
00392     }
00393   besHOOK_FWRITE(pszString,1,cbString,fp);
00394   besHOOK_FCLOSE(fp);
00395 
00396   besFREE(pszFileName);
00397 
00398 besEND
00399 
00408 besFUNCTION(loadstring)
00409   char *pszFileName;
00410   unsigned long cbString;
00411   FILE *fp;
00412   VARIABLE Argumentum;
00413 
00414   if( besARGNR < 1 )return COMMAND_ERROR_MANDARG;
00415 
00416   Argumentum = besARGUMENT(1);
00417   besDEREFERENCE(Argumentum);
00418   Argumentum = besCONVERT2STRING(Argumentum);
00419   besCONVERT2ZCHAR(Argumentum,pszFileName);
00420 
00421   cbString = besHOOK_SIZE(pszFileName);
00422   besRETURNVALUE = besNEWMORTALSTRING(cbString);
00423   if( besRETURNVALUE == NULL ){
00424     besFREE(pszFileName);
00425     return COMMAND_ERROR_MEMORY_LOW;
00426     }
00427 
00428   fp = besHOOK_FOPEN(pszFileName,"rb");
00429   if( fp == NULL ){
00430     besFREE(pszFileName);
00431     return COMMAND_ERROR_FILE_CANNOT_BE_OPENED;
00432     }
00433   besHOOK_FREAD(STRINGVALUE(besRETURNVALUE),1,cbString,fp);
00434   besHOOK_FCLOSE(fp);
00435 
00436   besFREE(pszFileName);
00437 
00438 besEND
00439 
00453 besFUNCTION(md5fun)
00454   VARIABLE Argument;
00455   MD5_CTX Md5Context;
00456 
00457   besASSERT_FUNCTION
00458 
00459   /* md5() or md5(undef) is undef */
00460   besRETURNVALUE = NULL;
00461   if( besARGNR < 1 )return COMMAND_ERROR_SUCCESS;
00462   Argument = besARGUMENT(1);
00463   if( Argument == NULL )return COMMAND_ERROR_SUCCESS;
00464   besDEREFERENCE(Argument);
00465 
00466   besALLOC_RETURN_STRING(16);
00467 
00468   Argument = besCONVERT2STRING(Argument);
00469 
00470   besMD5INIT( &Md5Context);
00471   besMD5UPDATE(&Md5Context,STRINGVALUE(Argument),STRLEN(Argument));
00472 
00473   besMD5FINAL(STRINGVALUE(besRETURNVALUE),&Md5Context);
00474 
00475 besEND
00476 
00492 besCOMMAND(md5serialize)
00493   NODE nItem;
00494   VARIABLE vARR;
00495   unsigned long size;
00496   MD5_CTX Md5Context;
00497 
00498   besASSERT_COMMAND
00499 
00500   /* this is a function and not a command, therefore we do not have our own mortal list */
00501   USE_CALLER_MORTALS;
00502 
00503   /* evaluate the parameter */
00504   nItem = besPARAMETERLIST;
00505   if( ! nItem ){
00506     RESULT = NULL;
00507     RETURN;
00508     }
00509   vARR = _besEVALUATEEXPRESSION_A(CAR(nItem));
00510   ASSERTOKE;
00511   size = sersize(vARR,pSt);
00512   RESULT = besNEWMORTALSTRING(size + 16);
00513   if( RESULT == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
00514   serconv(vARR,STRINGVALUE(RESULT));
00515   besMD5INIT( &Md5Context);
00516   besMD5UPDATE(&Md5Context,STRINGVALUE(RESULT),size);
00517 
00518   besMD5FINAL(STRINGVALUE(RESULT)+size,&Md5Context);
00519 
00520 besEND_COMMAND
00521 
00530 besFUNCTION(md5unserialize)
00531   VARIABLE Argument;
00532   LEFTVALUE Lval;
00533   int iError;
00534   unsigned long __refcount_;
00535   unsigned char *s;
00536   MD5_CTX Md5Context;
00537   unsigned char MD5[16];
00538 
00539   Argument = besARGUMENT(1);
00540   besLEFTVALUE(Argument,Lval);
00541   Argument = besARGUMENT(2);
00542   besDEREFERENCE(Argument);
00543   Argument = besCONVERT2STRING(Argument);
00544   s = STRINGVALUE(Argument);
00545   besMD5INIT( &Md5Context);
00546   besMD5UPDATE(&Md5Context,s,STRLEN(Argument)-16);
00547   besMD5FINAL(MD5,&Md5Context);
00548   if( memcmp(s+STRLEN(Argument)-16,MD5,16) )return COMMAND_ERROR_ARGUMENT_RANGE;
00549 
00550   if( Lval ){
00551     besRELEASE(*Lval);
00552     *Lval = unserconv(pSt->pEo,&s,&iError);
00553     }
00554   return iError;
00555 besEND
00556 
00577 besFUNCTION(toolExit)
00578   VARIABLE Argument;
00579   long retcode;
00580 
00581   besASSERT_FUNCTION;
00582   /* md5() or md5(undef) is undef */
00583   besRETURNVALUE = NULL;
00584   if( besARGNR < 1 )return COMMAND_ERROR_SUCCESS;
00585   Argument = besARGUMENT(1);
00586   if( Argument == NULL )return COMMAND_ERROR_SUCCESS;
00587   besDEREFERENCE(Argument);
00588   retcode = besGETLONGVALUE(Argument);
00589   exit(retcode);
00590 besEND
00591 

Generated on Sun Mar 12 23:56:29 2006 for ScriptBasic by  doxygen 1.4.6-NO