aboutsummaryrefslogtreecommitdiff
path: root/src/xmlview.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmlview.cc')
-rw-r--r--src/xmlview.cc272
1 files changed, 272 insertions, 0 deletions
diff --git a/src/xmlview.cc b/src/xmlview.cc
new file mode 100644
index 0000000..bad9443
--- /dev/null
+++ b/src/xmlview.cc
@@ -0,0 +1,272 @@
+/*-------------------< >---------------------------
+
+Currently missing markup for EXTENTS and DIMSCALES
+If an attribute is a text string, then it will print the attribute
+with a tag of <DATA>. 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
+----------------------
+<!ELEMENT HDF4 (FILENAME?,SDS*,ANNOTATION*,ATTRIBUTE*,ERROR?)>
+<!ELEMENT ERROR (#PCDATA)>
+<!ELEMENT FILENAME (#PCDATA)>
+<!ELEMENT SDS (DIMS,TYPE,UNITS?,NAME?,RANGE?,EXTENTS?,ANNOTATION*,ATTRIBUTE*)>
+<!ELEMENT NAME (#PCDATA)>
+<!ELEMENT DIMS (#PCDATA)>
+<!ATTRIBUTE RANK CDATA "3">
+<!ELEMENT TYPE (#PCDATA)>
+<!ELEMENT ANNOTATION (#PCDATA)>
+<!ELEMENT EXTENTS (#PCDATA)>
+<!ELEMENT RANGE (#PCDATA)>
+<!ELEMENT ATTRIBUTE (LENGTH,TYPE,NAME,RANGE?,EXTENTS?)>
+
+ ----------------------------------------------------*/
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef WITH_HDF4
+#include <HDFIO.hh>
+#endif
+#ifdef WITH_HDF5
+#include <H5IO.hh>
+#endif
+#include <IEEEIO.hh>
+
+char filedrivername[128];
+
+#define FindMinMax(dt) { \
+ dt *data = (dt*)buffer; \
+ min = max = (double)(data[0]); \
+ for(int i=1;i<nelem;i++){ \
+ double v = (double)(data[i]); \
+ if(v<min) min=v; \
+ if(v>max) max=v; \
+ } \
+ }
+
+// Print an XML tag for the name of the data element
+// tabover<NAME>name</NAME>
+void PrintNameXML(char *tab,// leading whitespace (for formating)
+ char *name);
+// Print an XML tag for the dimensions of an array
+// tabover <DIMS RANK=rank>dim1,dim2..dimN</DIMS>
+void PrintDimsXML(char *tab,// leading whitespace (for formating)
+ int rank,
+ int *dims);
+// Print an XML tag for the length of an array
+// tabover <LENGTH>length</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 <TYPE>datatype</TYPE>
+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 <RANGE>min,max</RANGE>
+// 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("<ERROR>missing filename</ERROR>\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("<ERROR>could not open file %s</ERROR>\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<ndatasets;n++){ // for each dataset
+ int rank,dims[5];
+ char name[128];
+ IObase::DataType datatype;
+ puts("\t<SDS>");// 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();an<nannotations;an++){
+ int length;
+ file->readAnnotationInfo(an,length);
+ printf("\t\t <ANNOTATION>%u</ANNOTATION>\n",length);
+ }
+ // cycle through each of the attributes
+ for(int a=0,nattribs=file->nAttributes();a<nattribs;a++){
+ int length;
+ printf("\t\t<ATTRIBUTE>\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 <DATA>%s</DATA>\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</ATTRIBUTE>\n");
+ }
+ puts("\t</SDS>");
+ }
+ printf("</%s>\n",filedrivername);
+ delete file;
+ return 0;
+}
+
+
+void PrintNameXML(char *tab,char *name){
+ printf("%s<NAME>%s</NAME>\n",tab,name);
+}
+
+void PrintDimsXML(char *tab,int rank,int *dims){
+ printf("%s<DIMS RANK=\"%u\">",tab,rank);
+ printf("%u",dims[0]); for(int i=1;i<rank;i++) printf(",%u",dims[i]);
+ puts("</DIMS>");
+}
+
+void PrintLengthXML(char *tab,int length){
+ printf("%s<LENGTH>%u</LENGTH>\n",tab,length);
+}
+
+void PrintTypeXML(char *tab,IObase::DataType datatype){
+ printf("%s<TYPE>",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("</TYPE>");
+}
+
+
+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<RANGE>%lf,%lf</RANGE>\n",tab,min,max);
+}