|
HL-HDF
|
When creating your own HDF5 product, there is one header files that should be included (hlhdf.h).
If you are going to create your own compound datatype, then include hlhdf_compound_utils.h as well.
When compiling a binary, there are three libraries that must be linked in; these are libhlhdf.a, libhdf5.a and libz.a. It is also possible to link the shared library libhdf5.so instead of libhdf5.a.
The HL-HDF package was installed with a hldef.mk file that can be included in your own Makefile in order to get the correct paths to both the zlib and the hdf5 library. It also contains information on which C++-compiler the HL-HDF package was compiled with and some other goodies.
A simple Makefile could look like this:
include /usr/local/hlhdf/mkf/hldef.mk
HLHDF_INCDIR = -I/usr/local/hlhdf/include
HLHDF_LIBDIR = -L/usr/local/hlhdf/lib
CFLAGS = $(OPTS) $(DEFS) -I. $(ZLIB_INCDIR) $(HDF5_INCDIR) \
$(HLHDF_INCDIR)
LDFLAGS = -L. $(ZLIB_LIBDIR) $(HDF5_LIBDIR) $(HLHDF_LIBDIR)
LIBS = -lhlhdf -lhdf5 -lz -lm
TARGET=myTestProgram
SOURCES=test_program.c
OBJECTS=$(SOURCES:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) -o $@ $(LDFLAGS) $(OBJECTS) $(LIBS)
clean:
@\rm -f *.o *~ so_locations core
distclean: clean
@\rm -f $(TARGET)
distribution:
@echo "Would bring the latest revision upto date"
install:
@$(HL_INSTALL) -f -o -C $(TARGET) ${MY_BIN_PATH}/$(TARGET)
Now, when the Makefile has been created, it might be a good idea to write your own HDF5 product. The following example will create a dataset with a two-dimensional array of integers, and two attributes connected to this dataset. It will also create a group containing one attribute.
#include <hlhdf.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
HL_NodeList* aList=NULL;
HL_Node* aNode=NULL;
HL_Compression compression;
int* anArray=NULL;
int anIntValue;
float aFloatValue;
hsize_t dims[]={10,10};
int npts=100;
int i;
HL_init(); /* Initialize the HL-HDF library */
HL_setDebugMode(2); /* Activate debugging */
if(!(aList = HLNodeList_new())) {
fprintf(stderr,"Failed to allocate nodelist");
goto fail;
}
if(!(anArray = malloc(sizeof(int)*npts))) {
fprintf(stderr,"Failed to allocate memory for array.");
goto fail;
}
for(i=0;i<npts;i++)
anArray[i]=i;
HLNodeList_addNode(aList,(aNode = HLNode_newGroup("/group1")));
HLNodeList_addNode(aList,(aNode = HLNode_newAttribute("/group1/attribute1")));
anIntValue=10;
HLNode_setScalarValue(aNode,sizeof(anIntValue),(unsigned char*)&anIntValue,"int",-1);
HLNodeList_addNode(aList,(aNode = HLNode_newDataset("/dataset1")));
HLNode_setArrayValue(aNode,sizeof(int),2,dims,(unsigned char*)anArray,"int",-1);
HLNodeList_addNode(aList,(aNode = HLNode_newAttribute("/dataset1/attribute2")));
anIntValue=20;
HLNode_setScalarValue(aNode,sizeof(anIntValue),(unsigned char*)&anIntValue,"int",-1);
HLNodeList_addNode(aList,(aNode = HLNode_newAttribute("/dataset1/attribute3")));
aFloatValue=99.99;
HLNode_setScalarValue(aNode,sizeof(aFloatValue),(unsigned char*)&aFloatValue,
"float",-1);
HLNodeList_setFileName(aList,"written_hdffile.hdf");
HLCompression_init(&compression, CT_ZLIB);
compression.level = 6;
HLNodeList_write(aList,NULL,&compression);
HLNodeList_free(aList);
exit(0);
return 0; /* Won't come here */
fail:
HLNodeList_free(aList);
exit(1);
return 1; /* Won't come here */
}
When you have created your own HDF5 product, it might be a good idea to create some code for reading this file and checking its contents.
#include <hlhdf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv)
{
HL_NodeList* aList=NULL;
HL_Node* aNode=NULL;
int* anArray=NULL;
int anIntValue;
float aFloatValue;
int npts;
int i;
HL_init(); /* Initialize the HL-HDF library */
HL_setDebugMode(2); /* Activate debugging */
if(!(aList = HLNodeList_read("written_hdffile.hdf"))) {
fprintf(stderr,"Failed to read nodelist\n");
goto fail;
}
HLNodeList_selectAllNodes(aList); /* Select everything for retrival */
HLNodeList_fetchMarkedNodes(aList);
if((aNode = HLNodeList_getNodeByName(aList,"/group1")))
printf("%s exists\n",HLNode_getName(aNode));
if((aNode = HLNodeList_getNodeByName(aList,"/group1/attribute1"))) {
memcpy(&anIntValue, HLNode_getData(aNode), HLNode_getDataSize(aNode));
printf("%s exists and have value %d\n",HLNode_getName(aNode),anIntValue);
}
if((aNode = HLNodeList_getNodeByName(aList,"/dataset1"))) {
anArray = (int*)HLNode_getData(aNode);
npts = 1;
for(i=0;i<HLNode_getRank(aNode);i++)
npts*=HLNode_getDimension(aNode, i);
printf("%s exists and has the values:\n",HLNode_getName(aNode));
for(i=0;i<npts;i++) {
printf("%d ", anArray[i]);
if((i%HLNode_getDimension(aNode, 0))==0) {
printf("\n");
}
}
printf("\n");
}
if((aNode = HLNodeList_getNodeByName(aList,"/dataset1/attribute2"))) {
memcpy(&anIntValue,HLNode_getData(aNode),HLNode_getDataSize(aNode));
printf("%s exists and have the value %d\n",HLNode_getName(aNode),anIntValue);
}
if((aNode = HLNodeList_getNodeByName(aList,"/dataset1/attribute3"))) {
memcpy(&aFloatValue,HLNode_getData(aNode),HLNode_getDataSize(aNode));
printf("%s exists and have the value %f\n",HLNode_getName(aNode),aFloatValue);
}
HLNodeList_free(aList);
exit(0);
return 0; /* Never reached */
fail:
HLNodeList_free(aList);
exit(1);
return 1; /* Never reached */
}
A small example on how to reroute the error messages is shown below, currently there is no similar functionality for the _pyhl module.
#include <hlhdf.h>
#include <hlhdf_debug.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
void hlhdf_error_handler(char* filename, int lineno, HL_Debug lvl, const char* fmt, ...)
{
va_list alist;
char errbuff[512];
va_start(alist,fmt);
fprintf(stdout,"<hlhdferror>\n");
fprintf(stdout," <filename>%s</filename>\n",filename);
fprintf(stdout," <linenumber>%d</linenumber>\n",lineno);
fprintf(stdout," <level>%d</level>\n",lvl);
vsprintf(errbuff,fmt,alist);
fprintf(stdout," <message>%s</message>\n",errbuff);
fprintf(stdout,"</hlhdferror>\n");
}
void hdf5_error_handler(unsigned n, const H5E_error_t* rowmsg)
{
fprintf(stdout,"<hdf5error>\n");
fprintf(stdout," <filename>%s</filename>\n",rowmsg->file_name);
fprintf(stdout," <linenumber>%d</linenumber>\n",rowmsg->line);
fprintf(stdout," <funcname>%s</funcname>\n",rowmsg->func_name);
fprintf(stdout," <desc>%s</desc>\n",rowmsg->desc);
fprintf(stdout,"</hdf5error>\n");
}
int main(int argc, char** argv)
{
HL_NodeList* nodelist;
HL_init(); /* Initialize the HL-HDF library */
HL_enableErrorReporting();
HL_setDebugFunction(hlhdf_error_handler);
HL_setHdf5ErrorFunction(hdf5_error_handler);
nodelist = HLNodeList_read("thisdoesnotexist.xxx");
return 0;
}