/*-------------------< >--------------------------- Currently missing markup for EXTENTS and DIMSCALES If an attribute is a text string, then it will print the attribute with a tag of . Otherwise, it will just provide information about the attribute (the range, length, type, name... etc). Does not provide refs for data right now, but I don't think they are necessary (the query will need to be based on index anyways). DTD for HDF XML Markup ---------------------- ----------------------------------------------------*/ #include #include #ifdef WITH_HDF4 #include #endif #ifdef WITH_HDF5 #include #endif #include char filedrivername[128]; #define FindMinMax(dt) { \ dt *data = (dt*)buffer; \ min = max = (double)(data[0]); \ for(int i=1;imax) max=v; \ } \ } // Print an XML tag for the name of the data element // tabovername void PrintNameXML(char *tab,// leading whitespace (for formating) char *name); // Print an XML tag for the dimensions of an array // tabover dim1,dim2..dimN void PrintDimsXML(char *tab,// leading whitespace (for formating) int rank, int *dims); // Print an XML tag for the length of an array // tabover length void PrintLengthXML(char *tab,// leading whitespace (for formating) int length); // Print an XML tag for the data type of an array // Must be one of Float32,Float64,Int16,Int32,Int64,Byte,Char // Byte indicates data whereas Char indicates text (a string) // even though both ar 8 bits // tabover datatype void PrintTypeXML(char *tab, // OK, you get the picture... IObase::DataType datatype); // Compute the min and max for a data array. void GetRangeXML(IObase::DataType datatype, int nelem, char *buffer, double &min, double &max); // Print an XML tag for the Range of the data (the min/max) // Uses GetRangeXML. // tabover min,max // Problem is that this forces a load of the dataset into memory // which can be slow and memory intensive. Need to change this // so that it can load a subset of the data into RAM (load in // 8k blocks rather than the entire thing). void PrintRangeXML(char *tab, IObase::DataType datatype, int nelem, char *buffer); int main(int argc,char *argv[]){ sprintf(filedrivername,"ERROR"); if(argc<2){ printf("missing filename\n"); exit(0); } IObase *file = 0; IEEEIO *ifile = new IEEEIO(argv[1],IObase::Read); if(!ifile->isValid()){ delete ifile; ifile=0;} else { sprintf(filedrivername,"IEEEIO"); file = ifile; // success } #ifdef WITH_HDF4 HDFIO *hfile=0; if(!file){ hfile = new HDFIO(argv[1],IObase::Read); if(!hfile->isValid()) {delete hfile; hfile=0;} else { sprintf(filedrivername,"HDF4"); file = hfile; // success } } #else IObase *hfile=0; #endif #ifdef WITH_HDF5 H5IO *h5file=0; if(!file){ h5file = new H5IO(argv[1],IObase::Read); if(!h5file->isValid()) {delete h5file; h5file=0;} else { sprintf(filedrivername,"HDF5"); file = h5file; // success } } #endif if(!file){ printf("could not open file %s\n",argv[1]); exit(0); } printf("<%s>\n",filedrivername); // now say anything you want about the HDF file for(int n=0,ndatasets=file->nDatasets();n");// begin an sds if(hfile){ #ifdef WITH_HDF4 hfile->readInfo(name,datatype,rank,dims); #endif } else{ name[0]='\0'; file->readInfo(datatype,rank,dims); } if(strlen(name)>0) PrintNameXML("\t\t",name); PrintTypeXML("\t\t",datatype); PrintDimsXML("\t\t",rank,dims); if(datatype!=IObase::Char){ char *buffer = new char[IObase::nBytes(datatype,rank,dims)]; file->read(buffer); // read the data PrintRangeXML("\t\t",datatype,IObase::nElements(rank,dims),buffer); delete buffer; } // for now, skip the annotations for(int an=0,nannotations=file->nAnnotations();anreadAnnotationInfo(an,length); printf("\t\t %u\n",length); } // cycle through each of the attributes for(int a=0,nattribs=file->nAttributes();a\n"); file->readAttributeInfo(a,name,datatype,length); PrintNameXML("\t\t ",name); PrintTypeXML("\t\t ",datatype); PrintLengthXML("\t\t ",length); if(datatype==IObase::Char){ // its a string, so print it char *s = new char[length+1]; file->readAttribute(a,s); printf("\t\t %s\n",s); delete s; } else { char *buffer = new char[IObase::nBytes(datatype,1,&length)]; file->readAttribute(a,buffer); // read the data PrintRangeXML("\t\t",datatype,length,buffer); delete buffer; } printf("\t\t\n"); } puts("\t"); } printf("\n",filedrivername); delete file; return 0; } void PrintNameXML(char *tab,char *name){ printf("%s%s\n",tab,name); } void PrintDimsXML(char *tab,int rank,int *dims){ printf("%s",tab,rank); printf("%u",dims[0]); for(int i=1;i"); } void PrintLengthXML(char *tab,int length){ printf("%s%u\n",tab,length); } void PrintTypeXML(char *tab,IObase::DataType datatype){ printf("%s",tab); switch(datatype){ case IObase::Float32: printf("Float32"); break; case IObase::Float64: printf("Float64"); break; case IObase::Int16: printf("Int16"); break; case IObase::Int32: printf("Int32"); break; case IObase::Int64: printf("Int64"); break; case IObase::Byte: printf("Byte"); break; case IObase::Char: printf("Char"); break; default: printf("Unknown(%d)",(int)datatype); } puts(""); } void GetRangeXML(IObase::DataType datatype,int nelem,char *buffer, double &min,double &max){ switch(datatype){ case IObase::Float32: FindMinMax(float); break; case IObase::Float64: FindMinMax(double); break; case IObase::Int16: FindMinMax(short); break; case IObase::Int32: FindMinMax(int); break; case IObase::Int64: FindMinMax(long); // well. long long for 32bit compiles break; case IObase::Byte: case IObase::Char: FindMinMax(char); break; default: //printf("Unknown(%d)",(int)datatype); return; // don't print } } void PrintRangeXML(char *tab,IObase::DataType datatype,int nelem,char *buffer){ // now compute the range in a datatype-dependent manner double min,max; GetRangeXML(datatype,nelem,buffer,min,max); printf("%s%lf,%lf\n",tab,min,max); }