tape/tape.c

Go to the documentation of this file.
00001 
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <errno.h>
00019 #include <ctype.h>
00020 #include "gridlabd.h"
00021 #include "object.h"
00022 #include "aggregate.h"
00023 
00024 #define _TAPE_C
00025 
00026 #include "tape.h"
00027 #include "file.h"
00028 #include "odbc.h"
00029 
00030 #define MAP_DOUBLE(X,LO,HI) {#X,VT_DOUBLE,&X,LO,HI}
00031 #define MAP_INTEGER(X,LO,HI) {#X,VT_INTEGER,&X,LO,HI}
00032 #define MAP_STRING(X) {#X,VT_STRING,X,sizeof(X),0}
00033 #define MAP_END {NULL}
00034 
00035 VARMAP varmap[] = {
00036     /* add module variables you want to be available using module_setvar in core */
00037     MAP_STRING(timestamp_format),
00038     MAP_END
00039 };
00040 
00041 extern CLASS *player_class;
00042 extern CLASS *shaper_class;
00043 extern CLASS *recorder_class;
00044 extern CLASS *collector_class;
00045 
00046 
00047 /* The following hack is required to stringize LIBEXT as passed in from
00048  * Makefile and used by snprintf below to construct the library name. */
00049 #define _STR(x) #x
00050 #define STR(x) _STR(x)
00051 
00052 
00053 #ifdef WIN32
00054 #define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
00055 #define _WIN32_WINNT 0x0400
00056 #include <windows.h>
00057 #define LIBPREFIX
00058 #ifndef LIBEXT
00059 #define LIBEXT .dll
00060 #endif
00061 #define DLLOAD(P) LoadLibrary(P)
00062 #define DLSYM(H,S) GetProcAddress((HINSTANCE)H,S)
00063 #define snprintf _snprintf
00064 #else /* ANSI */
00065 #include "dlfcn.h"
00066 #define LIBPREFIX "lib"
00067 #ifndef LIBEXT
00068 #define LIBEXT .so
00069 #else
00070 #endif
00071 #define DLLOAD(P) dlopen(P,RTLD_LAZY)
00072 #define DLSYM(H,S) dlsym(H,S)
00073 #endif
00074 
00075 static TAPEFUNCS *funcs = NULL;
00076 
00077 typedef int (*OPENFUNC)(void *, char *, char *);
00078 typedef char *(*READFUNC)(void *, char *, unsigned int);
00079 typedef int (*WRITEFUNC)(void *, char *, char *);
00080 typedef int (*REWINDFUNC)(void *);
00081 typedef void (*CLOSEFUNC)(void *);
00082 
00083 TAPEFUNCS *get_ftable(char *mode){
00084     /* check what we've already loaded */
00085     char256 modname;
00086     TAPEFUNCS *fptr = funcs;
00087     TAPEOPS *ops = NULL;
00088     void *lib = NULL;
00089     CALLBACKS **c = NULL;
00090     char *tpath = NULL;
00091     while(fptr != NULL){
00092         if(strcmp(fptr->mode, mode) == 0)
00093             return fptr;
00094         fptr = fptr->next;
00095     }
00096     /* fptr = NULL */
00097     fptr = malloc(sizeof(TAPEFUNCS));
00098     if(fptr == NULL)
00099         return NULL; /* out of memory */
00100     snprintf(modname, 1024, LIBPREFIX "tape_%s" STR(LIBEXT), mode);
00101     tpath = gl_findfile(modname, NULL, 0|4);
00102     if(tpath == NULL){
00103         GL_THROW("unable to locate %s", modname);
00104         return NULL;
00105     }
00106     lib = fptr->hLib = DLLOAD(tpath);
00107     if(fptr->hLib == NULL){
00108         GL_THROW("tape module: unable to load DLL for %s", modname);
00109         return NULL;
00110     }
00111     c = (CALLBACKS **)DLSYM(lib, "callback");
00112     if(c)
00113         *c = callback;
00114     //  nonfatal ommission
00115     ops = fptr->collector = malloc(sizeof(TAPEOPS));
00116     ops->open = (OPENFUNC)DLSYM(lib, "open_collector");
00117     ops->read = NULL;
00118     ops->write = (WRITEFUNC)DLSYM(lib, "write_collector");
00119     ops->rewind = NULL;
00120     ops->close = (CLOSEFUNC)DLSYM(lib, "close_collector");
00121     ops = fptr->player = malloc(sizeof(TAPEOPS));
00122     ops->open = (OPENFUNC)DLSYM(lib, "open_player");
00123     ops->read = (READFUNC)DLSYM(lib, "read_player");
00124     ops->write = NULL;
00125     ops->rewind = (REWINDFUNC)DLSYM(lib, "rewind_player");
00126     ops->close = (CLOSEFUNC)DLSYM(lib, "close_player");
00127     ops = fptr->recorder = malloc(sizeof(TAPEOPS));
00128     ops->open = (OPENFUNC)DLSYM(lib, "open_recorder");
00129     ops->read = NULL;
00130     ops->write = (WRITEFUNC)DLSYM(lib, "write_recorder");
00131     ops->rewind = NULL;
00132     ops->close = (CLOSEFUNC)DLSYM(lib, "close_recorder");
00133     ops = fptr->shaper = malloc(sizeof(TAPEOPS));
00134     ops->open = (OPENFUNC)DLSYM(lib, "open_shaper");
00135     ops->read = (READFUNC)DLSYM(lib, "read_shaper");
00136     ops->write = NULL;
00137     ops->rewind = (REWINDFUNC)DLSYM(lib, "rewind_shaper");
00138     ops->close = (CLOSEFUNC)DLSYM(lib, "close_shaper");
00139     fptr->next = funcs;
00140     funcs = fptr;
00141     return funcs;
00142 }
00143 
00144 EXPORT CLASS *init(CALLBACKS *fntable, void *module, int argc, char *argv[])
00145 {
00146     if (set_callback(fntable)==NULL)
00147     {
00148         errno = EINVAL;
00149         return NULL;
00150     }
00151 
00152     /* register the first class implemented, use SHARE to reveal variables */
00153     player_class = gl_register_class(module,"player",PC_BOTTOMUP); 
00154     PUBLISH_STRUCT(player,char32,property);
00155     PUBLISH_STRUCT(player,char1024,file);
00156     PUBLISH_STRUCT(player,char8,filetype);
00157     PUBLISH_STRUCT(player,int32,loop);
00158 
00159     /* register the first class implemented, use SHARE to reveal variables */
00160     shaper_class = gl_register_class(module,"shaper",PC_BOTTOMUP); 
00161     PUBLISH_STRUCT(shaper,char1024,file);
00162     PUBLISH_STRUCT(shaper,char8,filetype);
00163     PUBLISH_STRUCT(shaper,char256,group);
00164     PUBLISH_STRUCT(shaper,char32,property);
00165     PUBLISH_STRUCT(shaper,double,magnitude);
00166     PUBLISH_STRUCT(shaper,double,events);
00167 
00168     /* register the other classes as needed, */
00169     recorder_class = gl_register_class(module,"recorder",PC_BOTTOMUP);
00170     PUBLISH_STRUCT(recorder,char1024,property);
00171     PUBLISH_STRUCT(recorder,char32,trigger);
00172     PUBLISH_STRUCT(recorder,char1024,file);
00173     PUBLISH_STRUCT(recorder,int64,interval);
00174     PUBLISH_STRUCT(recorder,int32,limit);
00175 
00176     /* register the other classes as needed, */
00177     collector_class = gl_register_class(module,"collector",PC_BOTTOMUP);
00178     PUBLISH_STRUCT(collector,char1024,property);
00179     PUBLISH_STRUCT(collector,char32,trigger);
00180     PUBLISH_STRUCT(collector,char1024,file);
00181     PUBLISH_STRUCT(collector,int64,interval);
00182     PUBLISH_STRUCT(collector,int32,limit);
00183     PUBLISH_STRUCT(collector,char256,group);
00184 
00185     /* always return the first class registered */
00186     return player_class;
00187 }
00188 
00189 EXPORT int check(void)
00190 {
00191     unsigned int errcount=0;
00192 
00193     /* check players */
00194     {   OBJECT *obj=NULL;
00195         FINDLIST *players = gl_find_objects(FL_NEW,FT_CLASS,SAME,"tape",FT_END);
00196         while ((obj=gl_find_next(players,obj))!=NULL)
00197         {
00198             struct player *pData = OBJECTDATA(obj,struct player);
00199             if (gl_findfile(pData->file,NULL,FF_EXIST)==NULL)
00200             {
00201                 errcount++;
00202                 gl_error("player %s (id=%d) uses the file '%s', which cannot be found", obj->name?obj->name:"(unnamed)", obj->id, pData->file);
00203             }
00204         }
00205     }
00206 
00207     /* check shapers */
00208     {   OBJECT *obj=NULL;
00209         FINDLIST *shapers = gl_find_objects(FL_NEW,FT_CLASS,SAME,"shaper",FT_END);
00210         while ((obj=gl_find_next(shapers,obj))!=NULL)
00211         {
00212             struct shaper *pData = OBJECTDATA(obj,struct shaper);
00213             if (gl_findfile(pData->file,NULL,FF_EXIST)==NULL)
00214             {
00215                 errcount++;
00216                 gl_error("shaper %s (id=%d) uses the file '%s', which cannot be found", obj->name?obj->name:"(unnamed)", obj->id, pData->file);
00217             }
00218         }
00219     }
00220 
00221     return errcount;
00222 }
00223 
00224 int do_kill()
00225 {
00226     /* if global memory needs to be released, this is the time to do it */
00227     return 0;
00228 }
00229 

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy