Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

vml.C

Go to the documentation of this file.
00001 /*
00002  * Peter Boyle, 2004
00003  * vml.c, Generic VML routines implementation.
00004  */
00005 
00006 #ifndef NO_CPS
00007 #include <config.h>
00008 #endif
00009 #include <stdio.h>
00010 #include <limits.h>
00011 #include <string.h>
00012 #define DEB(A) fprintf(stderr,A)
00013 
00014 #ifndef NO_CPS
00015 #include <util/qcdio.h>
00016 #include <util/vml/types.h>
00017 #include <util/vml/vml.h>
00018 #include <util/vml/vml_encoder.h>
00019 CPS_START_NAMESPACE
00020 USING_NAMESPACE_CPS
00021 #else
00022 #include <rpc/types.h>
00023 #include <rpc/rpc.h>
00024 #include <vml.h>
00025 #include <vml_encoder.h>
00026 #endif
00027 
00028 static GenericEncoder *VmlEncode = new TextEncoder;
00029 
00030 
00031 extern "C" { 
00032 
00033 /*
00034  * constants specific to the vml "protocol"
00035  */
00036 #define LASTUNSIGNED    ((u_int) 0-1)
00037 
00038 /*
00039  * for unit alignment
00040  */
00041 static const char vml_zero[4] = {0, 0, 0, 0};
00042 
00043 /*
00044  * Free a data structure using VML
00045  * Not a filter, but a convenient utility nonetheless
00046  */
00047 void
00048 vml_free (vmlproc_t proc, char *name, char *objp)
00049 {
00050   VML x;
00051 
00052   x.x_op = VML_FREE;
00053   (*proc) (&x, name, objp);
00054 }
00055 
00056 
00057 /*
00058  * VML nothing
00059  */
00060 bool_t
00061 vml_void (void)
00062 {
00063   return VML_TRUE;
00064 }
00065 
00066 /*
00067  * VML integers
00068  */
00069 bool_t
00070 vml_int (VML *vmls, char *name,int *ip)
00071 {
00072   return VmlEncode->Int(vmls,name,*ip);
00073 }
00074 
00075 /*
00076  * VML unsigned integers
00077  */
00078 bool_t
00079 vml_u_int (VML *vmls, char *name,  u_int *up)
00080 {
00081   return VmlEncode->UnsignedInt(vmls,name,*up);
00082 }
00083 
00084 /*
00085  * VML long integers
00086  * same as vml_u_long - open coded to save a proc call!
00087  */
00088 bool_t
00089 vml_long (VML *vmls, char *name, long *lp)
00090 {
00091   return VmlEncode->Long(vmls,name,*lp);
00092 }
00093 
00094 /*
00095  * VML unsigned long integers
00096  * same as vml_long - open coded to save a proc call!
00097  */
00098 bool_t
00099 vml_u_long (VML *vmls, char *name, u_long *ulp)
00100 {
00101   return VmlEncode->UnsignedLong(vmls,name,*ulp);
00102 }
00103 
00104 /*
00105  * VML hyper integers
00106  * same as vml_u_hyper - open coded to save a proc call!
00107  */
00108 bool_t
00109 vml_hyper (VML *vmls, char *name, quad_t *llp)
00110 {
00111   bool_t ret;
00112   long long lll = *llp;
00113   ret = VmlEncode->LongLong(vmls,name,lll);
00114   *llp = lll;
00115   return ret;
00116 }
00117 
00118 
00119 /*
00120  * VML hyper integers
00121  * same as vml_hyper - open coded to save a proc call!
00122  */
00123 bool_t
00124 vml_u_hyper (VML *vmls, char *name, u_quad_t *ullp)
00125 {
00126   bool_t ret;
00127   unsigned long long lll = *ullp;
00128   ret = VmlEncode->UnsignedLongLong(vmls,name,lll);
00129   *ullp = lll;
00130   return ret;
00131 }
00132 
00133 bool_t
00134 vml_longlong_t (VML *vmls, char *name, quad_t *llp)
00135 {
00136   return vml_hyper (vmls, name, llp);
00137 }
00138 
00139 bool_t
00140 vml_u_longlong_t (VML *vmls, char *name, u_quad_t *ullp)
00141 {
00142   return vml_u_hyper (vmls, name, ullp);
00143 }
00144 
00145 /*
00146  * VML short integers
00147  */
00148 bool_t
00149 vml_short (VML *vmls, char *name, short *sp)
00150 {
00151   return VmlEncode->Short(vmls,name,*sp);
00152 }
00153 
00154 /*
00155  * VML unsigned short integers
00156  */
00157 bool_t
00158 vml_u_short (VML *vmls, char *name, u_short *usp)
00159 {
00160   return VmlEncode->UnsignedShort(vmls,name,*usp);
00161 }
00162 
00163 
00164 /*
00165  * VML a char
00166  */
00167 bool_t
00168 vml_char (VML *vmls, char *name, char *cp)
00169 {
00170   return VmlEncode->Char(vmls,name,*cp);
00171 }
00172 
00173 /*
00174  * VML an unsigned char
00175  */
00176 bool_t
00177 vml_u_char (VML *vmls, char *name, u_char *cp)
00178 {
00179   return VmlEncode->UnsignedChar(vmls,name,*cp);
00180 }
00181 
00182 /*
00183  * VML booleans
00184  */
00185 bool_t
00186 vml_bool (VML *vmls, char *name, bool_t *bp)
00187 {
00188   return VmlEncode->Bool(vmls,name,*bp);
00189 }
00190 char *vml_enum_string ( enum_t *val, struct vml_enum_map *map )
00191 {
00192   for ( int i=0;map[i].name!=NULL; i++ ) {
00193     if ( map[i].val == *val ) {
00194       return map[i].name;
00195     }
00196   }
00197   fprintf(stderr,"logic bomb in vml_enum_string\n");
00198   // exit(-1);
00199   return NULL;
00200 }
00201 enum_t *vml_enum_val  ( char *string, struct vml_enum_map * map)
00202 {
00203   for ( int i=0;map[i].name!=NULL; i++ ) {
00204     if ( !strcmp(string,map[i].name) ) {
00205       return &map[i].val;
00206     }
00207   }
00208   fprintf(stderr,"logic bomb in vml_enum_val in \"%s\" \n",string); exit(-1);
00209 }
00210 /*
00211  * VML enumerations
00212  */
00213 bool_t
00214 vml_enum (VML *vmls, char *name, enum_t *ep,struct vml_enum_map *list)
00215 {
00216   char val_buf[256];
00217   char * val_str = val_buf;
00218   /*Fix me... error codes?*/
00219   if ( vmls->x_op == VML_ENCODE ) { 
00220     val_str = vml_enum_string(ep,list);
00221         if(!val_str) {fprintf(stderr,"%d not in %s\n",ep,list->enum_name);exit(-1);}
00222   }
00223   
00224   VmlEncode->Enum(vmls,list[0].enum_name,name,val_str);
00225   if ( vmls->x_op == VML_DECODE ) { 
00226     *ep = *(vml_enum_val(val_str,list));
00227   }
00228   return VML_TRUE;
00229 }
00230 
00231 /*
00232  * VML opaque data
00233  * Allows the specification of a fixed size sequence of opaque bytes.
00234  * cp points to the opaque object and cnt gives the byte length.
00235  */
00236 #define BYTES_PER_VML_UNIT 4
00237 bool_t
00238 vml_opaque (VML *vmls, char *name, caddr_t cp, u_int cnt)
00239 {
00240   int icnt = cnt;
00241   char *tmp = (char *)cp;
00242   VmlEncode->Bytes(vmls,name,tmp,icnt);
00243   cnt = icnt;
00244   return VML_TRUE;
00245 }
00246 
00247 /*
00248  * VML counted bytes
00249  * *cpp is a pointer to the bytes, *sizep is the count.
00250  * If *cpp is NULL maxsize bytes are allocated
00251  */
00252 bool_t
00253 vml_bytes (
00254   VML *vmls,
00255   char *name,
00256   char **cpp,
00257   u_int *sizep,
00258   u_int maxsize)
00259 {
00260   int icnt = *sizep;
00261   VmlEncode->Bytes(vmls,name,*cpp,icnt);
00262   *sizep = icnt;
00263   return VML_TRUE;
00264 }
00265 
00266 /*
00267  * Implemented here due to commonality of the object.
00268  */
00269 bool_t
00270 vml_netobj (
00271             VML *vmls,
00272             char *name,
00273             struct netobj *np)
00274 {
00275 
00276   return vml_bytes (vmls, name, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ);
00277 }
00278 
00279 /*
00280  * VML a discriminated union
00281  * Support routine for discriminated unions.
00282  * You create an array of vmldiscrim structures, terminated with
00283  * an entry with a null procedure pointer.  The routine gets
00284  * the discriminant value and then searches the array of vmldiscrims
00285  * looking for that value.  It calls the procedure given in the vmldiscrim
00286  * to handle the discriminant.  If there is no specific routine a default
00287  * routine may be called.
00288  * If there is no specific or default routine an error is returned.
00289  */
00290 bool_t
00291 vml_union (
00292            VML *vmls,
00293            char *name,
00294      enum_t *dscmp,     /* enum to decide which arm to work on */
00295      char *unp,         /* the union itself */
00296      const struct vml_discrim *choices, /* [value, vml proc] for each arm */
00297      vmlproc_t dfault)          /* default vml routine */
00298 {
00299   enum_t dscm;
00300   long tmp;
00301 
00302   if ( dscmp ) tmp = *dscmp;
00303   /*
00304    * we deal with the discriminator;  it's an enum
00305    */
00306   if (!vml_long (vmls, name, &tmp))
00307     {
00308       return VML_FALSE;
00309     }
00310   dscm = tmp;
00311   *dscmp = tmp;
00312 
00313   /*
00314    * search choices for a value that matches the discriminator.
00315    * if we find one, execute the vml routine for that value.
00316    */
00317   for (; choices->proc != NULL_vmlproc_t; choices++)
00318     {
00319       if (choices->value == dscm)
00320         return (*(choices->proc)) (vmls, name, unp, LASTUNSIGNED);
00321     }
00322 
00323   /*
00324    * no match - execute the default vml routine if there is one
00325    */
00326   return ((dfault == NULL_vmlproc_t) ? VML_FALSE :
00327           (*dfault) (vmls, name, unp, LASTUNSIGNED));
00328 }
00329 
00330 
00331 /*
00332  * Non-portable vml primitives.
00333  * Care should be taken when moving these routines to new architectures.
00334  */
00335 
00336 
00337 /*
00338  * VML null terminated ASCII strings
00339  * vml_string deals with "C strings" - arrays of bytes that are
00340  * terminated by a NULL character.  The parameter cpp references a
00341  * pointer to storage; If the pointer is null, then the necessary
00342  * storage is allocated.  The last parameter is the max allowed length
00343  * of the string as specified by a protocol.
00344  */
00345 bool_t
00346 vml_string (
00347             VML *vmls,
00348             char *name,
00349             char **cpp,
00350             u_int maxsize)
00351 {
00352   return VmlEncode->String(vmls,name,*cpp);
00353 }
00354 
00355 /*
00356  * Wrapper for vml_string that can be called directly from
00357  * routines like clnt_call
00358  */
00359 bool_t
00360 vml_wrapstring (
00361                 VML *vmls,
00362                 char * name,
00363                 char **cpp)
00364 {
00365   if (vml_string (vmls, name, cpp, LASTUNSIGNED))
00366     {
00367       return VML_TRUE;
00368     }
00369   return VML_FALSE;
00370 }
00371 
00372 bool_t
00373 vml_float(VML *vmls,
00374           char *name,
00375           float *fp)
00376 {
00377   return VmlEncode->Float(vmls,name,*fp);
00378 }
00379 
00380 
00381 bool_t
00382 vml_double(VML *vmls,
00383            char *name,
00384            double *dp)
00385 {
00386   return VmlEncode->Double(vmls,name,*dp);
00387 }
00388 
00389 /* VML 64bit integers */
00390 bool_t
00391 vml_int64_t (VML *vmls, char *name, int64_t *ip)
00392 {
00393   return VmlEncode->Int64(vmls,name,*ip);
00394 }
00395 
00396 /* VML 64bit unsigned integers */
00397 bool_t
00398 vml_uint64_t (VML *vmls, char *name, uint64_t *uip)
00399 {
00400   return VmlEncode->UnsignedInt64(vmls,name,*uip);
00401 }
00402 
00403 /* VML 32bit integers */
00404 bool_t
00405 vml_int32_t (VML *vmls, char *name, int32_t *lp)
00406 {
00407   return VmlEncode->Int32(vmls,name,*lp);
00408 }
00409 
00410 /* VML 32bit unsigned integers */
00411 bool_t
00412 vml_uint32_t (VML *vmls, char *name, uint32_t *ulp)
00413 {
00414   return VmlEncode->UnsignedInt32(vmls,name,*ulp);
00415 }
00416 
00417 /* VML 16bit integers */
00418 bool_t
00419 vml_int16_t (VML *vmls, char *name, int16_t *ip)
00420 {
00421   return VmlEncode->Int16(vmls,name,*ip);
00422 }
00423 
00424 /* VML 16bit unsigned integers */
00425 bool_t
00426 vml_uint16_t (VML *vmls, char *name ,uint16_t *uip)
00427 {
00428   return VmlEncode->UnsignedInt16(vmls,name,*uip);
00429 }
00430 
00431 /* VML 8bit integers */
00432 bool_t
00433 vml_int8_t (VML *vmls, char *name, int8_t *ip)
00434 {
00435   return VmlEncode->Int8(vmls,name,*ip);
00436 }
00437 
00438 /* VML 8bit unsigned integers */
00439 bool_t
00440 vml_uint8_t (VML *vmls, char *name, uint8_t *uip)
00441 {
00442   return VmlEncode->UnsignedInt8(vmls,name,*uip);
00443 }
00444 
00445 
00446 
00447 bool_t
00448 vml_array (
00449            VML *vmls,
00450            char *name,
00451            caddr_t *addrp,              /* array pointer */
00452            u_int *sizep,                /* number of elements */
00453            u_int maxsize,               /* max numberof elements */
00454            u_int elsize,                /* size in bytes of each element */
00455            vmlproc_t elproc)    /* vml routine to handle each element */
00456 {
00457   int nvals  = *sizep;
00458   int sz = elsize;
00459   char *tmp = (char *)(* addrp);
00460   bool_t ret = VmlEncode->Array(vmls,(char *)"Array",
00461                                 name,tmp,nvals,sz,elproc);
00462   *addrp = tmp;
00463   *sizep = nvals;
00464   return ret;
00465 }
00466 bool_t
00467 vml_vector (VML *vmls,
00468             char *name,
00469             char *basep,
00470             u_int nelem,
00471             u_int elemsize,
00472             vmlproc_t vml_elem)
00473 {
00474   int nvals  = nelem;
00475   int sz = elemsize;
00476 
00477   /* For VECTOR
00478    * Disable allocate, and never pass on a free request
00479    */
00480   if ( vmls->x_op == VML_FREE ) return true;
00481 
00482   bool_t ret = VmlEncode->Array(vmls,(char *)"Vector",
00483                                 name,basep,nvals,
00484                                 sz,
00485                                 vml_elem,0);
00486   return ret;
00487 }
00488 bool_t
00489 vml_reference (
00490                VML *vmls,
00491                char *name,
00492                caddr_t *pp, /* the pointer to work on */
00493                u_int size,  /* size of the object pointed to */
00494                vmlproc_t proc) /* vml routine to handle the object */
00495 {
00496   char *tmp = (char *)*pp;
00497   char *type = "Reference";
00498   bool_t ret = VmlEncode->Reference(vmls,type,name,tmp,proc,size);
00499   *pp = tmp;
00500   return ret;
00501 }
00502 bool_t
00503 vml_pointer (
00504              VML *vmls,
00505              char *name,
00506              char **objpp,
00507              u_int obj_size,
00508              vmlproc_t vml_obj)
00509 {
00510 
00511   bool_t more_data;
00512 
00513   more_data = (*objpp != NULL);
00514   if (!vml_bool (vmls, name, &more_data))
00515     {
00516       return VML_FALSE;
00517     }
00518   if (!more_data)
00519     {
00520       *objpp = NULL;
00521       return VML_TRUE;
00522     }
00523   return vml_reference (vmls, name, objpp, obj_size, vml_obj);
00524 }
00525 
00526 
00527 void vml_struct_begin (VML *vmls, char *type, char *instance)
00528 {
00529   VmlEncode->StructBegin(vmls,type,instance);
00530 }
00531 void vml_struct_end   (VML *vmls, char *type, char *instance)
00532 {
00533   VmlEncode->StructEnd(vmls,type,instance);
00534 }
00535 void vml_class_begin (VML *vmls, char *type, char *instance)
00536 {
00537   VmlEncode->ClassBegin(vmls,type,instance);
00538 }
00539 void vml_class_end   (VML *vmls, char *type, char *instance)
00540 {
00541   VmlEncode->ClassEnd(vmls,type,instance);
00542 }
00543 
00544 }
00545 
00546 bool_t VML::Puts(char *string)
00547 {
00548   switch ( StreamType ) { 
00549   case VML_STDIO:
00550   case VML_DESCRIPTOR:
00551 #ifndef NO_CPS
00552     Fprintf(x_fp,string);
00553 #else
00554     fprintf(x_fp,string);
00555     fflush(x_fp);
00556 #endif
00557     return true;
00558     break;
00559   case VML_MEM:
00560     int len = strlen(string);
00561     if ( x_handy - len  > 0 ) { 
00562       strcpy((char *)x_private,string);
00563       x_private = x_private + len;
00564       x_handy   = x_handy - len;
00565       return true;
00566     } 
00567     return false;
00568     break;
00569   }
00570   return false;
00571 }
00572 char *VML::Gets(char *string,int n)
00573 {
00574   char *ret;
00575   switch ( StreamType ) { 
00576   case VML_STDIO:
00577   case VML_DESCRIPTOR:
00578     ret = fgets(string, n, x_fp);
00579     if ( ret == NULL ) DEB("bad fgets\n");
00580     return ret;
00581     break;
00582   case VML_MEM:
00583     char *cp=(char *)x_private;
00584     int count=0;
00585     unsigned long x_private_new;
00586     while( (*cp!='\0') && (*cp!='\n') && count < n-2 ) { 
00587       string[count++] = *cp++;
00588     }
00589     string[count++] = '\n';
00590     string[count++] = '\0';
00591     if (*cp=='\n') cp++;
00592     
00593     x_private_new = (unsigned long)cp;
00594     x_handy= x_handy - (x_private_new - (unsigned long)x_private);
00595     x_private = (char *)x_private_new;
00596     if ( x_handy >= 0 ) return string;
00597     else return NULL;
00598     break;
00599   }
00600   DEB("Bad StreamType in Gets\n");
00601   return NULL;
00602 }
00603 bool_t VML::Create(char *buf,int length, enum vml_op op)
00604 {
00605   x_op = op;
00606   x_private = x_base = buf;
00607   x_handy = length;
00608   StreamType = VML_MEM;
00609   return true;
00610 }
00611 bool_t VML::Create(int fd,enum vml_op op)
00612 {
00613   
00614   FILE *fp = NULL;
00615   if ( op == VML_ENCODE ) fp = fdopen(fd,"w");
00616   if ( op == VML_DECODE ) fp = fdopen(fd,"r");
00617   if ( fp == NULL ) return VML_FALSE;
00618   return Create(fp,op);
00619 }
00620 bool_t VML::Create(char *file, enum vml_op op)
00621 {
00622   FILE *fp = NULL;
00623 #ifndef NO_CPS
00624   if ( op == VML_ENCODE ) { 
00625     fp  = Fopen(file,"w");
00626   } else if ( op == VML_DECODE ) { 
00627     fp  = fopen(file,"r");
00628   }
00629 #else
00630   if ( op == VML_ENCODE ) { 
00631     fp  = fopen(file,"w");
00632   } else if ( op == VML_DECODE ) { 
00633     fp  = fopen(file,"r");
00634   }
00635 #endif
00636   if ( fp == NULL ) return VML_FALSE;
00637   return Create(fp,op);
00638 
00639 }
00640 bool_t VML::Create(FILE *file, enum vml_op op)
00641 {
00642   x_fp = file;
00643   x_op = op;
00644   StreamType = VML_STDIO;
00645   if ( file ) return true;
00646   return false;
00647 }
00648 
00649 void VML::Destroy(void) 
00650 {
00651   if ( StreamType == VML_MEM ) return;
00652 #ifndef NO_CPS
00653   else if (x_fp) Fclose(x_fp);
00654 #else
00655   else if (x_fp) fclose(x_fp);
00656 #endif
00657 }
00658 bool_t vmlmem_create (VML *__vmls, char * __addr,
00659                                 int __size, enum vml_op __xop)
00660 {
00661   return __vmls->Create(__addr,__size,__xop);
00662 }
00663 bool_t vmlstdio_create (VML *__vmls, FILE *fp, enum vml_op __xop)
00664 { 
00665   return __vmls->Create(fp,__xop);
00666 }
00667 bool_t vmlfd_create (VML *__vmls, int fd, enum vml_op __xop)
00668 {
00669   return __vmls->Create(fd,__xop);
00670 }
00671 
00672 bool_t vmlfile_create (VML *__vmls, char *file, enum vml_op __xop)
00673 {
00674   return __vmls->Create(file,__xop);
00675 }
00676 void vml_markup_type(enum vml_markup type)
00677 {
00678   switch (type) {
00679   case VML_TEXT:
00680      VmlEncode = new TextEncoder;
00681      break;
00682   case VML_XML:
00683      VmlEncode = new XmlEncoder;
00684      break;
00685   default:
00686     exit(-1);
00687   };
00688 
00689   return ;
00690 }
00691 void vml_destroy (VML *__vmls)
00692 {
00693   __vmls->Destroy();
00694 }
00695 #ifndef NO_CPS
00696 CPS_END_NAMESPACE
00697 #endif

Generated on Sat Oct 10 14:11:33 2009 for Columbia Physics System by  doxygen 1.3.9.1