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     snprintf(modname, 1024, LIBPREFIX "tape_%s" STR(LIBEXT), mode);
00099     tpath = gl_findfile(modname, NULL, 0|4);
00100     if(tpath == NULL){
00101         gl_error("unable to locate %s", modname);
00102         return NULL;
00103     }
00104     lib = fptr->hLib = DLLOAD(tpath);
00105     if(fptr->hLib == NULL){
00106         gl_error("tape module: unable to load DLL for %s", modname);
00107         return NULL;
00108     }
00109     c = (CALLBACKS **)DLSYM(lib, "callback");
00110     if(c)
00111         *c = callback;
00112     ops = fptr->collector = malloc(sizeof(TAPEOPS));
00113     ops->open = (OPENFUNC)DLSYM(lib, "open_collector");
00114     ops->read = NULL;
00115     ops->write = (WRITEFUNC)DLSYM(lib, "write_collector");
00116     ops->rewind = NULL;
00117     ops->close = (CLOSEFUNC)DLSYM(lib, "close_collector");
00118     ops = fptr->player = malloc(sizeof(TAPEOPS));
00119     ops->open = (OPENFUNC)DLSYM(lib, "open_player");
00120     ops->read = (READFUNC)DLSYM(lib, "read_player");
00121     ops->write = NULL;
00122     ops->rewind = (REWINDFUNC)DLSYM(lib, "rewind_player");
00123     ops->close = (CLOSEFUNC)DLSYM(lib, "close_player");
00124     ops = fptr->recorder = malloc(sizeof(TAPEOPS));
00125     ops->open = (OPENFUNC)DLSYM(lib, "open_recorder");
00126     ops->read = NULL;
00127     ops->write = (WRITEFUNC)DLSYM(lib, "write_recorder");
00128     ops->rewind = NULL;
00129     ops->close = (CLOSEFUNC)DLSYM(lib, "close_recorder");
00130     ops = fptr->shaper = malloc(sizeof(TAPEOPS));
00131     ops->open = (OPENFUNC)DLSYM(lib, "open_shaper");
00132     ops->read = (READFUNC)DLSYM(lib, "read_shaper");
00133     ops->write = NULL;
00134     ops->rewind = (REWINDFUNC)DLSYM(lib, "rewind_shaper");
00135     ops->close = (CLOSEFUNC)DLSYM(lib, "close_shaper");
00136     fptr->next = funcs;
00137     funcs = fptr;
00138     return funcs;
00139 }
00140 
00141 EXPORT CLASS *init(CALLBACKS *fntable, void *module, int argc, char *argv[])
00142 {
00143     if (set_callback(fntable)==NULL)
00144     {
00145         errno = EINVAL;
00146         return NULL;
00147     }
00148 
00149     /* register the first class implemented, use SHARE to reveal variables */
00150     player_class = gl_register_class(module,"player",PC_BOTTOMUP); 
00151     PUBLISH_STRUCT(player,char32,property);
00152     PUBLISH_STRUCT(player,char1024,file);
00153     PUBLISH_STRUCT(player,char8,filetype);
00154     PUBLISH_STRUCT(player,int32,loop);
00155 
00156     /* register the first class implemented, use SHARE to reveal variables */
00157     shaper_class = gl_register_class(module,"shaper",PC_BOTTOMUP); 
00158     PUBLISH_STRUCT(shaper,char1024,file);
00159     PUBLISH_STRUCT(shaper,char8,filetype);
00160     PUBLISH_STRUCT(shaper,char256,group);
00161     PUBLISH_STRUCT(shaper,char32,property);
00162     PUBLISH_STRUCT(shaper,double,magnitude);
00163     PUBLISH_STRUCT(shaper,double,events);
00164 
00165     /* register the other classes as needed, */
00166     recorder_class = gl_register_class(module,"recorder",PC_BOTTOMUP);
00167     PUBLISH_STRUCT(recorder,char1024,property);
00168     PUBLISH_STRUCT(recorder,char32,trigger);
00169     PUBLISH_STRUCT(recorder,char1024,file);
00170     PUBLISH_STRUCT(recorder,int64,interval);
00171     PUBLISH_STRUCT(recorder,int32,limit);
00172 
00173     /* register the other classes as needed, */
00174     collector_class = gl_register_class(module,"collector",PC_BOTTOMUP);
00175     PUBLISH_STRUCT(collector,char1024,property);
00176     PUBLISH_STRUCT(collector,char32,trigger);
00177     PUBLISH_STRUCT(collector,char1024,file);
00178     PUBLISH_STRUCT(collector,int64,interval);
00179     PUBLISH_STRUCT(collector,int32,limit);
00180     PUBLISH_STRUCT(collector,char256,group);
00181 
00182     /* always return the first class registered */
00183     return player_class;
00184 }
00185 
00186 EXPORT int check(void)
00187 {
00188     unsigned int errcount=0;
00189 
00190     /* check players */
00191     {   OBJECT *obj=NULL;
00192         FINDLIST *players = gl_find_objects(FL_NEW,FT_CLASS,SAME,"tape",FT_END);
00193         while ((obj=gl_find_next(players,obj))!=NULL)
00194         {
00195             struct player *pData = OBJECTDATA(obj,struct player);
00196             if (gl_findfile(pData->file,NULL,FF_EXIST)==NULL)
00197             {
00198                 errcount++;
00199                 gl_error("player %s (id=%d) uses the file '%s', which cannot be found", obj->name?obj->name:"(unnamed)", obj->id, pData->file);
00200             }
00201         }
00202     }
00203 
00204     /* check shapers */
00205     {   OBJECT *obj=NULL;
00206         FINDLIST *shapers = gl_find_objects(FL_NEW,FT_CLASS,SAME,"shaper",FT_END);
00207         while ((obj=gl_find_next(shapers,obj))!=NULL)
00208         {
00209             struct shaper *pData = OBJECTDATA(obj,struct shaper);
00210             if (gl_findfile(pData->file,NULL,FF_EXIST)==NULL)
00211             {
00212                 errcount++;
00213                 gl_error("shaper %s (id=%d) uses the file '%s', which cannot be found", obj->name?obj->name:"(unnamed)", obj->id, pData->file);
00214             }
00215         }
00216     }
00217 
00218     return errcount;
00219 }
00220 
00221 int do_kill()
00222 {
00223     /* if global memory needs to be released, this is the time to do it */
00224     return 0;
00225 }
00226 

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