bin: using Mosel's binary format
The bin driver implements a structured, architecture-independent binary format that can handle cross platform files and supports the full set of data structures that may be contained in initializations blocks. It can be used for exchanging data between Mosel models or between a Mosel model and a host application, particularly in the context of distributed applications using the Mosel remote invocation library XPRD (see the program examples in Part `V. Remote invocation of Mosel' of the `Xpress Mosel User Guide'). The bindrv library that provides the binary reading and writing functionality on the library level is independent of Mosel and can be used with any C or Java program. It comes with a documentation of its own, the `bindrv Library Reference Manual'.
Mosel code like the following expects input and output data from files in binary format.
initialisations from "bin:burgdatabin" [VALUE, WEIGHT] as "BurgData" end-initialisations ... initialisations to "bin:resdatabin" SOLTAKE as "SolTake" evaluation of getobjval as "Objective" end-initialisations
The file binary file burgdatabin has the same structure as the text file burglar.dat that we have seen in Section Example problem.
BurgData: [(camera) [ 15 2] (necklace) [100 20] ... (brick) [ 1 10] ]
The following C code produces the corresponding file burgdatabin in bindrv binary format. Notice the use of controls (label, open and close a list, open and close an index) through which we represent the structure of the file.
#include "bindrv.h" /**** Input data ****/ static double vdata[]={15,100,90,60,40,15,10, 1}; /* VALUE */ static double wdata[]={ 2, 20,20,30,40,30,60,10}; /* WEIGHT */ static char *ind[]={"camera", "necklace", "vase", "picture", "tv", "video", "chest", "brick" }; /* Index names */ int datasize=8; /**** Create a BinDrv data file ****/ static void writeburgbin(void) { FILE *f; s_bindrvctx bdrv; int i; f=fopen("burgdatabin","w"); bdrv=bindrv_newwriter((size_t (*)(const void *,size_t,size_t,void*))fwrite,f); bindrv_putctrl(bdrv,BINDRV_CTRL_LABEL); bindrv_putstring(bdrv,"BurgData"); bindrv_putctrl(bdrv,BINDRV_CTRL_OPENLST); /* [ */ for(i=0;i<datasize;i++) { bindrv_putctrl(bdrv,BINDRV_CTRL_OPENNDX); /* ( */ bindrv_putstring(bdrv,ind[i]); /* index */ bindrv_putctrl(bdrv,BINDRV_CTRL_CLOSENDX); /* ) */ bindrv_putctrl(bdrv,BINDRV_CTRL_OPENLST); /* [ */ bindrv_putreal(bdrv,vdata[i]); /* val1 */ bindrv_putreal(bdrv,wdata[i]); /* val2 */ bindrv_putctrl(bdrv,BINDRV_CTRL_CLOSELST); /* ] */ } bindrv_putctrl(bdrv,BINDRV_CTRL_CLOSELST); /* ] */ bindrv_delete(bdrv); fclose(f); }
The structure of the binary result file resdatabin corresponds to this text file:
'SolTake': [('camera') 1 ('necklace') 1 ('vase') 1 ('picture') 1 ('tv') 0 ('video') 1 ('chest') 0 ('brick') 0] 'Objective': 280
The binary file can be read and displayed with the following C code—the routines bindrv_get* follow the same logic as the bindrv_put* routines we have seen in the writing function, decoding the file structure via controls for labels, square and round brackets (for lists and indices respectively). For clarity's sake, we have implemented only a limited amount of checks whether the detected structure and data types correspond to the expected format.
static void readburgbin(void) { FILE *f; s_bindrvctx bdrv; union { int i; double r; char b; char *str; BINDRV_LONG l;} val; f=fopen("resdatabin","r"); bdrv=bindrv_newreader((size_t (*)(void *,size_t,size_t,void*))fread,f); bindrv_getctrl(bdrv,&(val.i)); if(val.i==BINDRV_CTRL_LABEL) { while(bindrv_nexttoken(bdrv)>=0) { bindrv_getstring(bdrv,&(val.str)); /* label: */ if(strcmp(val.str,"SolTake")==0) { free(val.str); printf("Solution values:\n"); bindrv_getctrl(bdrv,&(val.i)); /* [ */ while(bindrv_nexttoken(bdrv)>=0) { bindrv_getctrl(bdrv,&(val.i)); if(val.i== BINDRV_CTRL_LABEL) break; switch(val.i) { case BINDRV_CTRL_OPENNDX: /* ( */ printf(" take("); bindrv_getstring(bdrv,&(val.str)); /* index */ printf("%s",val.str); bindrv_getctrl(bdrv,&(val.i)); /* ) */ printf(")="); bindrv_getreal(bdrv,&(val.r)); /* value */ printf(" %g\n",val.r); break; case BINDRV_CTRL_CLOSELST: /* ] */ printf("\n"); break; default: printf("Unexpected token %d\n", val.i); exit(1); } } } else if(strcmp(val.str,"Objective")==0) { free(val.str); bindrv_getreal(bdrv,&(val.r)); printf("Objective value = %g\n", val.r); } else { printf("Unexpected label '%s'\n", val.str); free(val.str); exit(1); } } } else { printf("Unexpected token '%d'\n", val.i); exit(1); } bindrv_delete(bdrv); fclose(f); }
© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.