OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimHdf5Info.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: David Burken
8 //
9 // Description: HDF5 Info class.
10 //
11 //----------------------------------------------------------------------------
12 // $Id$
13 
15 #include <ossim/base/ossimCommon.h>
16 #include <ossim/base/ossimEndian.h>
17 #include <ossim/base/ossimNotify.h>
18 #include <ossim/base/ossimTrace.h>
20 #include <ossim/hdf5/ossimHdf5.h>
21 
22 #include <fstream>
23 #include <iostream>
24 #include <iomanip>
25 #include <sstream>
26 
27 using namespace std;
28 using namespace H5;
29 
31 : ossimInfoBase()
32 {
33 }
34 
36 : ossimInfoBase(),
37  m_hdf5 (hdf5)
38 {
39 }
40 
42 {
43  m_hdf5 = 0;
44 }
45 
47 {
48  m_hdf5 = new ossimHdf5;
49  if (!m_hdf5->open(file))
50  {
51  m_hdf5 = 0;
52  return false;
53  }
54  return true;
55 }
56 
57 // Top level print from root
59 {
60  if (!m_hdf5.valid())
61  {
62  out<<"ossimHdf5Info: No HDF5 file has been opened! Nothing to print."<<endl;
63  return out;
64  }
65 
66  try
67  {
68  Group root;
69  if (!m_hdf5->getRoot(root))
70  return out;
71  print(out, root, "");
72  out<<endl;
73  }
74  catch (H5::Exception& h5x)
75  {
76  h5x.getDetailMsg();
77  }
78 
79  return out;
80 }
81 
82 // GROUP LIST
83 ostream& ossimHdf5Info::printSubGroups(std::ostream& out, const H5::Group& group,
84  const ossimString& lm) const
85 {
86  vector<Group> groups;
87  if (!m_hdf5->getChildGroups(group, groups))
88  return out;
89  if (!groups.empty())
90  {
91  for (ossim_uint32 i=0; i<groups.size(); ++i)
92  print(out, groups[i], lm);
93  }
94  return out;
95 }
96 
97 // ATTRIBUTE LIST
98 ostream& ossimHdf5Info::printAttributes(std::ostream& out, const H5::H5Object& obj,
99  const ossimString& lm) const
100 {
101  vector<Attribute> attributes;
102  if (!m_hdf5->getAttributes(obj, attributes))
103  return out;
104 
105  if (!attributes.empty())
106  {
107  for (ossim_uint32 i=0; i<attributes.size(); ++i)
108  print(out, attributes[i], lm);
109  }
110  return out;
111 }
112 
113 // DATASET LIST
114 ostream& ossimHdf5Info::printDatasets(std::ostream& out, const H5::Group& group,
115  const ossimString& lm) const
116 {
117  vector<DataSet> datasets;
118  if (!m_hdf5->getDatasets(group, datasets))
119  return out;
120 
121  if (!datasets.empty())
122  {
123  for (ossim_uint32 i=0; i<datasets.size(); ++i)
124  print(out, datasets[i], lm);
125  }
126  return out;
127 }
128 
129 // GROUP
130 ostream& ossimHdf5Info::print(ostream& out, const H5::Group& group, const ossimString& lm) const
131 {
132  try
133  {
134  out<<lm<<"GROUP: "<<group.getObjName()<<endl;
135 
136  // Set indent for children:
137  ossimString lm2 (lm + " ");
138 
139  // List attributes:
140  printAttributes(out, group, lm2);
141 
142  // List Datasets:
143  printDatasets(out, group, lm2);
144 
145  // List Child Groups:
146  printSubGroups(out, group, lm2);
147  }
148  catch( const H5::Exception& e )
149  {
150  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
151  }
152 
153  return out;
154 }
155 
156 // DATASET
157 ostream& ossimHdf5Info::print(ostream& out, const H5::DataSet& dataset, const ossimString& lm) const
158 {
159  try
160  {
161  out<<lm<<"DATASET: "<<dataset.getObjName()<<endl;
162 
163  // Dump its components:
164  int set_size = dataset.getSpace().getSimpleExtentNpoints();
165  ossimString lm2 (lm + " ");
166  print(out, dataset.getDataType(), lm2);
167  print(out, dataset.getSpace(), lm2);
168 
169  // Dump dataset values for small datasets:
170  H5T_class_t class_type = dataset.getDataType().getClass();
171  if ((set_size < 11) && (class_type == H5T_STRING))
172  {
173  string values;
174  dataset.read(values, dataset.getDataType());
175  out<<lm<<" values: "<<values<<endl;
176  }
177  }
178  catch( const H5::Exception& e )
179  {
180  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
181  }
182 
183  return out;
184 }
185 
186 // DATATYPE
187 ostream& ossimHdf5Info::print(ostream& out, const H5::DataType& datatype, const ossimString& lm) const
188 {
189  try
190  {
191  H5T_class_t class_type = datatype.getClass();
192  size_t size = datatype.getSize();
193  bool isAtomic = false;
194  switch (class_type)
195  {
196  case H5T_INTEGER:
197  isAtomic = true;
198  out<<lm<<"DATATYPE: integer, "<<size<<" bytes ";
199  break;
200  case H5T_FLOAT:
201  isAtomic = true;
202  out<<lm<<"DATATYPE: float, "<<size<<" bytes ";
203  break;
204  case H5T_TIME:
205  out<<lm<<"DATATYPE: date/time, "<<size<<" bytes "<<endl;
206  break;
207  case H5T_STRING:
208  out<<lm<<"DATATYPE: string, "<<size<<" bytes ";
209  break;
210  case H5T_BITFIELD:
211  out<<lm<<"DATATYPE: bit-field, "<<size<<" bytes "<<endl;
212  break;
213  case H5T_OPAQUE:
214  out<<lm<<"DATATYPE: opaque, "<<size<<" bytes "<<endl;
215  break;
216  case H5T_COMPOUND:
217  out<<lm<<"DATATYPE: compound, "<<size<<" bytes "<<endl;
218  break;
219  case H5T_REFERENCE:
220  out<<lm<<"DATATYPE: reference, "<<size<<" bytes "<<endl;
221  break;
222  case H5T_ENUM:
223  out<<lm<<"DATATYPE: enumeration, "<<size<<" bytes "<<endl;
224  break;
225  case H5T_VLEN:
226  out<<lm<<"DATATYPE: variable-length, "<<size<<" bytes "<<endl;
227  break;
228  case H5T_ARRAY:
229  out<<lm<<"DATATYPE: array, "<<size<<" bytes "<<endl;
230  break;
231  default:
232  out<<lm<<"DATATYPE: unknown, "<<size<<" bytes "<<endl;
233  }
234 
235  if (isAtomic)
236  {
237  H5T_order_t order = ((AtomType&) datatype).getOrder();
238  switch (order)
239  {
240  case H5T_ORDER_LE:
241  out<<"(Little Endian)"<<endl;
242  break;
243  case H5T_ORDER_BE:
244  out<<"(Big Endian)"<<endl;
245  break;
246  default:
247  out<<endl;
248  break;
249  }
250  }
251  }
252  catch( const H5::Exception& e )
253  {
254  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
255  }
256 
257 
258  return out;
259 }
260 
261 // DATASPACE
262 ostream& ossimHdf5Info::print(ostream& out, const H5::DataSpace& dataspace, const ossimString& lm) const
263 {
264  int rank = 0;
265  hsize_t* dim_sizes = 0;
266 
267  try
268  {
269  H5S_class_t classT = dataspace.getSimpleExtentType();
270  switch (classT)
271  {
272  case H5S_SCALAR:
273  out<<lm<<"DATASPACE: (scalar)"<<endl;
274  break;
275  case H5S_SIMPLE:
276  rank = dataspace.getSimpleExtentNdims();
277  dim_sizes = new hsize_t[rank];
278  dataspace.getSimpleExtentDims(dim_sizes);
279  out<<lm<<"DATASPACE: simple, rank: "<<rank<<" size: ";
280  for (int i=0; i<rank; i++)
281  {
282  int dim_size = dim_sizes[i];
283  if (i > 0)
284  out<<" x ";
285  out<<dim_size;
286  }
287  out<<endl;
288  delete dim_sizes;
289  break;
290  case H5S_NULL:
291  out<<lm<<"DATASPACE: (NULL)"<<endl;
292  break;
293  default:
294  out<<lm<<"DATASPACE: (Unknown Type)"<<endl;
295  }
296  }
297  catch( const H5::Exception& e )
298  {
299  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
300  }
301 
302  return out;
303 }
304 
305 // ATTRIBUTE
306 ostream& ossimHdf5Info::print(ostream& out, const H5::Attribute& attr, const ossimString& lm) const
307 {
308  out<<lm<<"ATTRIBUTE: "<<attr.getName();
309 
310  try
311  {
312  std::string str_value;
313  char buf[1024];
314  //int int_value = 0;
315  ossimString lm2 (lm + " ");
316  ossimByteOrder order = m_hdf5->getByteOrder(&attr);
317  ossimEndian endian;
318  bool swapOrder = (order!=ossim::byteOrder());
319 
320  H5T_class_t class_type = attr.getDataType().getClass();
321  ossim_uint32 dataSize = attr.getDataType().getSize();
322  switch (class_type)
323  {
324  case H5T_STRING:
325  attr.read(attr.getDataType(), str_value);
326  out <<" = "<<str_value<<endl;
327  break;
328  case H5T_INTEGER:
329  {
330  std::string strValue;
331  attr.read(attr.getDataType(), buf);
332  ossim_uint32 signType = H5Tget_sign(attr.getDataType().getId());
333  switch(dataSize)
334  {
335  case 1: // one byte integer
336  {
337  switch(signType)
338  {
339  case H5T_SGN_NONE:
340  {
341  ossim_uint8* intValue=0;
342  intValue = reinterpret_cast<ossim_uint8*>(buf);
343  strValue = ossimString::toString(*intValue).string();
344 
345  break;
346  }
347  case H5T_SGN_2:
348  {
349  ossim_int8* intValue=0;
350  intValue = reinterpret_cast<ossim_int8*>(buf);
351  strValue = ossimString::toString(*intValue).string();
352 
353  break;
354  }
355  default:
356  {
357  break;
358  }
359  }
360  break;
361  }
362  case 2: // 2 byte integer
363  {
364  switch(signType)
365  {
366  case H5T_SGN_NONE: // unsigned
367  {
368  ossim_uint16* intValue=0;
369  intValue = reinterpret_cast<ossim_uint16*>(buf);
370  if (swapOrder)
371  endian.swap(*intValue);
372  strValue = ossimString::toString(*intValue).string();
373 
374  break;
375  }
376  case H5T_SGN_2: // Signed
377  {
378  ossim_int16* intValue=0;
379  intValue = reinterpret_cast<ossim_int16*>(buf);
380  if (swapOrder)
381  endian.swap(*intValue);
382  strValue = ossimString::toString(*intValue).string();
383  break;
384  }
385  default:
386  {
387  break;
388  }
389 
390  }
391  break;
392  }
393  case 4: // 4 byte integer
394  {
395  switch(signType)
396  {
397  case H5T_SGN_NONE:
398  {
399  ossim_uint32* intValue=0;
400  intValue = reinterpret_cast<ossim_uint32*>(buf);
401  if (swapOrder)
402  endian.swap(*intValue);
403  strValue = ossimString::toString(*intValue).string();
404 
405  break;
406  }
407  case H5T_SGN_2:
408  {
409  ossim_int32* intValue=0;
410  intValue = reinterpret_cast<ossim_int32*>(buf);
411  if (swapOrder)
412  endian.swap(*intValue);
413  strValue = ossimString::toString(*intValue).string();
414  break;
415  }
416  default:
417  {
418  break;
419  }
420  }
421  break;
422  }
423  case 8: // 8 byte integer
424  {
425  switch(signType)
426  {
427  case H5T_SGN_NONE:
428  {
429  ossim_uint64* intValue=0;
430  intValue = reinterpret_cast<ossim_uint64*>(buf);
431  if (swapOrder)
432  endian.swap(*intValue);
433  strValue = ossimString::toString(*intValue).string();
434 
435  break;
436  }
437  case H5T_SGN_2:
438  {
439  ossim_int64* intValue=0;
440  intValue = reinterpret_cast<ossim_int64*>(buf);
441  if (swapOrder)
442  endian.swap(*intValue);
443  strValue = ossimString::toString(*intValue).string();
444  break;
445  }
446  }
447  break;
448  }
449 
450  }
451  out <<" = "<<strValue<<endl;
452  break;
453  }
454  case H5T_FLOAT:
455  {
456  std::string strValue;
457  attr.read(attr.getDataType(), buf);
458  switch(dataSize)
459  {
460  // we will use a buf pointer. There is something going on with some datasets
461  // and the attribute reader core dumping when providing the address of a float
462  // To fix this we will use a char* buf and reinterpret the cast.
463  case 4:
464  {
465  ossim_float32* float_value=0;
466  float_value = reinterpret_cast<ossim_float32*>(buf);
467  if (swapOrder)
468  endian.swap(*float_value);
469  strValue = ossimString::toString(*float_value).string();
470  break;
471  }
472  case 8:
473  {
474  ossim_float64* float_value=0;
475  float_value = reinterpret_cast<ossim_float64*>(buf);
476  if (swapOrder)
477  endian.swap(*float_value);
478  strValue = ossimString::toString(*float_value).string();
479  break;
480  }
481  }
482  out <<" = "<<strValue<<endl;
483  break;
484  }
485  default:
486  out <<" (value not handled type) "<<endl;
487  print(out, attr.getDataType(), lm2);
488  print(out, attr.getSpace(), lm2);
489  }
490  }
491  catch( const H5::Exception& e )
492  {
493  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
494  }
495 
496  return out;
497 }
498 
500 {
501  m_kwl.clear();
502 
503  try
504  {
505  if (!m_hdf5.valid())
506  return false;
507 
508  string groupName = "/";
509  string prefix = "hdf5.";
510 
511  Group root;
512  if (!m_hdf5->getRoot(root))
513  return false;
514 
515  ossim_uint32 recurseCount = 0;
516  dumpGroup(root, prefix, recurseCount);
517 
518  // Dump daset names:
519  vector<DataSet> datasets;
520  vector<std::string> datasetNames;
521  m_hdf5->getDatasets(root, datasets, true );
522  ostringstream value;
523  value << "(";
524  for (ossim_uint32 i=0; i<datasets.size(); ++i)
525  {
526  if (i == 0)
527  value << datasets[i].getObjName();
528  else
529  value << ", "<< datasets[i].getObjName();
530  }
531  value<<")";
532  m_kwl.addPair(prefix, string("datasetnames"), value.str());
533  }
534  catch( const H5::Exception& e )
535  {
536  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
537  }
538 
539 
540  kwl = m_kwl;
541  return true;
542 }
543 
544 bool ossimHdf5Info::getKeywordlistDataset(ossimKeywordlist& kwl, const std::string& datasetName) const
545 {
546  bool returnValue = false;
547  m_kwl.clear();
548  Group root;
549  if (m_hdf5->getRoot(root))
550  {
551  H5::DataSet* dataset = m_hdf5->findDatasetByName(datasetName, &root, true);
552  if(dataset)
553  {
554  try{
555  dumpDataset(*dataset, "");
556  returnValue = true;
557  kwl = m_kwl;
558 
559  }
560  catch(...)
561  {
562 
563  }
564  delete dataset;
565  }
566  }
567  return returnValue;
568 }
569 
570 bool ossimHdf5Info::getKeywordlistGroup(ossimKeywordlist& kwl, const std::string& groupName) const
571 {
572  bool returnValue = false;
573  m_kwl.clear();
574  Group root;
575  ossim_uint32 recurseCount = 0;
576 
577  if (m_hdf5->getRoot(root))
578  {
579  H5::Group* group = m_hdf5->findGroupByName(groupName, &root, true);
580  if(group)
581  {
582  try{
583  dumpGroup(*group, "", recurseCount);
584  returnValue = true;
585  kwl = m_kwl;
586 
587  }
588  catch(...)
589  {
590 
591  }
592  delete group;
593  }
594  }
595  return returnValue;
596 }
597 
598 void ossimHdf5Info::dumpGroup(const Group& group,
599  const string& prefix,
600  ossim_uint32& recursedCount) const
601 {
602  ++recursedCount;
603 
604  try
605  {
606  ossimString groupPrefix = getObjectPrefix(prefix, group.getObjName());
607  m_kwl.addPair(groupPrefix, string("type"), string("Group"));
608 
609  // Dump all attributes for this group:
610  dumpAttributes(group, groupPrefix);
611 
612  // Dump all datasets under this group:
613  vector<DataSet> datasets;
614  m_hdf5->getDatasets(group, datasets);
615  for (ossim_uint32 i=0; i<datasets.size(); ++i)
616  {
617  dumpDataset(datasets[i], groupPrefix);
618  }
619 
620  // Dump child Groups:
621  vector<Group> childGroups;
622  m_hdf5->getChildGroups(group, childGroups, false);
623  for (ossim_uint32 i=0; i<childGroups.size(); ++i)
624  {
625  dumpGroup(childGroups[i], groupPrefix, recursedCount);
626  }
627  }
628  catch( const H5::Exception& e )
629  {
630  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
631  }
632 
633  --recursedCount;
634 }
635 
637  const ossimString& fullPathName) const
638 {
639  vector<ossimString> items;
640  fullPathName.split(items, "/");
641  ossimString objectName (items.back());
642 
643  ostringstream objectPrefix;
644  if (objectName.empty())
645  objectPrefix << prefix;
646  else
647  objectPrefix << prefix << objectName<<".";
648 
649  return objectPrefix.str();
650 }
651 
652 void ossimHdf5Info::dumpAttributes(const H5Object& obj, const std::string& prefix) const
653 {
654  try
655  {
656  vector<H5::Attribute> attrList;
657  m_hdf5->getAttributes(obj, attrList);
658  for ( ossim_uint32 i = 0; i < attrList.size(); ++i )
659  {
660  ostringstream attrPrefix;
661  attrPrefix << prefix;//<<"attribute"<<i<<".";
662  dumpAttribute( attrList[i], attrPrefix.str());
663  }
664  }
665  catch( const H5::Exception& e )
666  {
667  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
668  }
669 }
670 
671 void ossimHdf5Info::dumpAttribute(const H5::Attribute& attr,
672  const std::string& prefix) const
673 {
674  std::string strValue;
675  char buf[1024];
676  try
677  {
678  ossimByteOrder order = m_hdf5->getByteOrder(&attr);
679  ossimEndian endian;
680  // bool swapOrder = (order!=ossim::byteOrder());
681 
682  H5T_class_t class_type = attr.getDataType().getClass();
683  // ossim_uint32 dataSize = attr.getDataType().getSize();
684  switch (class_type)
685  {
686  case H5T_STRING:
687  {
688  attr.read(attr.getDataType(), strValue);
689  break;
690  }
691  case H5T_INTEGER:
692  {
693  H5::DataType dataType = attr.getDataType();
694  H5::IntType* dataTypePtr = (H5::IntType*)(&dataType);
695 
696  attr.read(attr.getDataType(), buf);
697  ossimHdf5::intTypeToString(strValue, *dataTypePtr, buf);
698  break;
699  }
700  case H5T_FLOAT:
701  {
702  H5::DataType dataType = attr.getDataType();
703  H5::FloatType* dataTypePtr = (H5::FloatType*)(&dataType);
704 
705  attr.read(attr.getDataType(), buf);
706  ossimHdf5::floatTypeToString(strValue, *dataTypePtr, buf);
707  break;
708  }
709  case H5T_COMPOUND:
710  {
711  //H5::DataType dataType = attr.getDataType();
712  //H5::FloatType* dataTypePtr = (H5::FloatType*)(&dataType);
713 
714  //H5::CompType compType(dataset);
715  //dumpCompoundTypeInfo(compType, datasetPrefix);
716  //dumpCompound(dataset, compType, datasetPrefix);
717  // ostringstream tempOut;
718 
719  // tempOut << "(" <<"H5T_COMPOUND not a handled type)";
720  // strValue = tempOut.str();
721 
722  }
723  default:
724  {
725  ostringstream tempOut;
726 
727  tempOut << "(" << ossimHdf5::getDatatypeClassType(class_type) <<" not a handled type)";
728  strValue = tempOut.str();
729  }
730  }
731 
732  ossimString attrKey (getObjectPrefix(prefix, attr.getName()));
733  m_kwl.addPair(prefix, attr.getName(), strValue);
734  }
735  catch( const H5::Exception& e )
736  {
737  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
738  }
739 }
740 
741 
742 void ossimHdf5Info::dumpDataset(const H5::DataSet& dataset,
743  const std::string& prefix) const
744 {
745 #if 0
746  std::cout << "printObject entered..."
747  << "\nobjectName: " << objectName
748  << "\nprefix: " << prefix
749  << std::endl;
750 #endif
751 
752  try
753  {
754  string datasetPrefix = getObjectPrefix(prefix, dataset.getObjName());
755  m_kwl.addPair(datasetPrefix, string("type"), string("DataSet"));
756 
757  // Dump all attributes for this dataset:
758  dumpAttributes(dataset, datasetPrefix);
759 
760  // Get the class of the datatype that is used by the dataset.
761  H5T_class_t type_class = dataset.getTypeClass();
762  m_kwl.addPair(datasetPrefix, "class_type", m_hdf5->getDatatypeClassType(type_class));
763 
764  // Dump specific datatypes:
765  switch(type_class)
766  {
767  case H5T_COMPOUND:
768  {
769  H5::CompType compType(dataset);
770  dumpCompoundTypeInfo(compType, datasetPrefix);
771  dumpCompound(dataset, compType, datasetPrefix);
772  break;
773  }
774  case H5T_ENUM:
775  {
776  H5::EnumType enumType (dataset);
777  dumpEnumTypeInfo(enumType, datasetPrefix);
778  break;
779  }
780  case H5T_ARRAY:
781  {
782  H5::ArrayType arrayType (dataset.getId());
783  dumpArrayTypeInfo(arrayType, datasetPrefix);
784  break;
785  }
786  case H5T_INTEGER:
787  case H5T_FLOAT:
788  {
790  dumpNumericalTypeInfo(dataset, byteOrder, datasetPrefix);
791  break;
792  }
793  default:
794  {
795  m_kwl.addPair(datasetPrefix, string(ossimKeywordNames::SCALAR_TYPE_KW),
796  string("OSSIM_SCALAR_UNKNOWN"));
797  break;
798  }
799  }
800 
801 // Dump Extents:
802  vector<ossim_uint32> extents;
803  m_hdf5->getExtents( dataset, extents );
804  ostringstream value;
805  if(!extents.empty())
806  {
807  value <<extents[0];
808  for ( ossim_uint32 i = 1; i < extents.size(); ++i )
809  {
810  value << ", " << extents[i];
811  }
812  m_kwl.addPair(datasetPrefix, "extents", value.str());
813  }
814 
815 #if 0
816  // Attributes:
817  int numberOfAttrs = dataset.getNumAttrs();
818  cout << "numberOfAttrs: " << numberOfAttrs << endl;
819  for ( ossim_int32 attrIdx = 0; attrIdx < numberOfAttrs; ++attrIdx )
820  {
821  H5::Attribute attribute = dataset.openAttribute( attrIdx );
822  cout << "attribute.from class: " << attribute.fromClass() << endl;
823  }
824 #endif
825  }
826  catch( const H5::Exception& e )
827  {
828  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
829  }
830 
831 }
832 
833 void ossimHdf5Info::dumpCompound(const H5::DataSet& dataset,
834  const H5::CompType& compound,
835  const std::string& prefix)const
836 {
837  H5::DataSpace dataspace = dataset.getSpace();
838  ossim_uint32 dimensions = dataspace.getSimpleExtentNdims();
839  ossim_uint32 nElements = dataspace.getSimpleExtentNpoints();
840  ossim_int32 nMembers = compound.getNmembers();
841  ossim_uint64 size = compound.getSize();
842  ossim_int32 memberIdx = 0;
843  ossim_int32 elementIdx = 0;
844  H5::DataType compType = dataset.getDataType();
845  std::vector<char> compData(size*nElements);
846  dataset.read((void*)&compData.front(),compType);
847  char* compDataPtr = &compData.front();
848 
849  if(dimensions!=1)
850  {
851  return;
852  }
853 
854  for(;elementIdx<nElements;++elementIdx)
855  {
856  std::string elementPrefix = prefix;//+"."+"element"+ossimString::toString(elementIdx);
857  //std::cout << "ELEMENTS: " << elements << std::endl;
858  for(memberIdx=0;memberIdx < nMembers;++memberIdx)
859  {
860  H5::DataType dataType = compound.getMemberDataType(memberIdx);
861  H5std_string memberName = compound.getMemberName(memberIdx);
862  ossim_uint32 memberOffset = compound.getMemberOffset(memberIdx) ;
863  std::string newPrefix = elementPrefix + memberName;
864 
865  switch(dataType.getClass())
866  {
867  case H5T_COMPOUND:
868  {
869  H5::CompType compoundType(dataset);
870  // dumpCompoundTypeInfo(compoundType, newPrefix);
871  dumpCompound(dataset, compoundType, newPrefix);
872  break;
873  }
874  case H5T_INTEGER:
875  {
876  H5::IntType dataType = compound.getMemberIntType(memberIdx);
877  dumpIntType(dataType, &compDataPtr[memberOffset], newPrefix);
878  //ossim_hdf5::printIntType(dataset, dataType, &compDataPtr[memberOffset], newPrefix, out);
879  break;
880  }
881  case H5T_FLOAT:
882  {
883  H5::FloatType dataType = compound.getMemberFloatType(memberIdx);
884  dumpFloatType(dataType, &compDataPtr[memberOffset], newPrefix);
885  break;
886  }
887  case H5T_TIME:
888  case H5T_STRING:
889  {
890  H5::StrType dataType = compound.getMemberStrType(memberIdx);
891  dumpStringType(dataType, &compDataPtr[memberOffset], newPrefix);
892 // ossim_hdf5::printStrType(dataset, dataType, &compDataPtr[memberOffset], newPrefix, out);
893  break;
894  }
895  case H5T_BITFIELD:
896  {
897 // out << newPrefix << ": <H5T_BITFIELD NOT HANDLED>\n";
898  break;
899  }
900  case H5T_OPAQUE:
901  {
902 // out << newPrefix << ": <H5T_OPAQUE NOT HANDLED>\n";
903  break;
904  }
905  case H5T_REFERENCE:
906  {
907 // out << newPrefix << ": <H5T_REFERENCE NOT HANDLED>\n";
908  break;
909  }
910  case H5T_ENUM:
911  {
912  H5::EnumType dataType = compound.getMemberEnumType(memberIdx);
913  dumpEnumTypeInfo(dataType, newPrefix);
914 // ossim_hdf5::printEnumType(dataset, dataType, newPrefix, out);
915  break;
916  }
917  case H5T_VLEN:
918  {
919 // out << newPrefix << ": <H5T_VLEN NOT HANDLED>\n";
920  break;
921  }
922  case H5T_ARRAY:
923  {
924  H5::ArrayType dataType = compound.getMemberArrayType(memberIdx);
925  dumpArrayType(dataType, &compDataPtr[memberOffset], newPrefix);
926  break;
927  }
928  case H5T_NO_CLASS:
929  default:
930  {
931  break;
932  }
933  }
934  }
935  compDataPtr+=size;
936  }
937 
938 }
939 
940 void ossimHdf5Info::dumpCompoundTypeInfo(const H5::CompType& compound,
941  const std::string& prefix) const
942 {
943  #if 0
944  try
945  {
946  // H5::CompType compound(dataset);
947  ossim_int32 nMembers = compound.getNmembers();
948  ossim_int32 memberIdx = 0;
949  ostringstream typePrefix;
950  typePrefix << prefix << "compound_type.";
951  m_kwl.addPair(prefix, string("type"), string("compound"));
952 
953  for(memberIdx=0;memberIdx < nMembers;++memberIdx)
954  {
955  H5::DataType dataType (compound.getMemberDataType(memberIdx));
956  H5std_string memberName (compound.getMemberName(memberIdx));
957  ostringstream newPrefix;
958  newPrefix<<typePrefix.str() <<memberName<< ".";
959 
960  H5T_class_t class_type = dataType.getClass();
961  m_kwl.addPair(newPrefix.str(), string("class_type"), m_hdf5->getDatatypeClassType(class_type));
962 
963  switch(class_type)
964  {
965  case H5T_INTEGER:
966  {
967  H5::IntType dataType = compound.getMemberIntType(memberIdx);
968  //dumpIntType(dataset, dataType, &compDataPtr[memberOffset], newPrefix, out);
969 
970  break;
971  }
972  case H5T_FLOAT:
973  {
974  H5::FloatType dataType = compound.getMemberFloatType(memberIdx);
975  break;
976  }
977  case H5T_ENUM:
978  {
979  H5::EnumType enudataType = compound.getMemberEnumType(memberIdx);
980  dumpEnumTypeInfo(enudataType, newPrefix.str());
981  break;
982  }
983  case H5T_ARRAY:
984  {
985  H5::ArrayType arrdataType = compound.getMemberArrayType(memberIdx);
986  dumpArrayTypeInfo(arrdataType, newPrefix.str());
987  break;
988  }
989  default:
990  {
991  break;
992  }
993  }
994  }
995  }
996  catch( const H5::Exception& e )
997  {
998  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
999  }
1000  #endif
1001 }
1002 
1003 void ossimHdf5Info::dumpEnumTypeInfo(H5::EnumType enumType,
1004  const std::string& prefix) const
1005 {
1006  try
1007  {
1008  ossim_int32 nEnumMembers = enumType.getNmembers();
1009  ossim_int32 enumTypeSize = enumType.getSize();
1010  if (!nEnumMembers || !enumTypeSize)
1011  return;
1012 
1013  char* enum_value = new char [enumTypeSize];
1014  ostringstream kwl_value;
1015 
1016  for(ossim_int32 i=0;i<nEnumMembers;++i)
1017  {
1018  enumType.getMemberValue(i, &enum_value);
1019  H5std_string name = enumType.nameOf(&enum_value, enumTypeSize);
1020  if (i==0)
1021  kwl_value << name;
1022  else
1023  kwl_value << ", " << name;
1024  }
1025  m_kwl.addPair(prefix, string("enumerations"), kwl_value.str());
1026  delete [] enum_value;
1027  }
1028  catch( const H5::Exception& e )
1029  {
1030  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
1031  }
1032 }
1033 
1034 
1035 void ossimHdf5Info::dumpArrayTypeInfo(H5::ArrayType arrayType,
1036  const std::string& prefix) const
1037 {
1038  try
1039  {
1040  ossim_uint32 arrayNdims = arrayType.getArrayNDims();
1041  string ndimsstr = ossimString::toString(arrayNdims);
1042  m_kwl.addPair(prefix, "rank", ndimsstr);
1043 
1044  if (arrayNdims)
1045  {
1046  std::vector<hsize_t> dims(arrayNdims);
1047  arrayType.getArrayDims(&dims.front());
1048  ostringstream kwl_value;
1049  for(ossim_uint32 i=0;i<arrayNdims;++i)
1050  {
1051  if (i==0)
1052  kwl_value << dims[i];
1053  else
1054  kwl_value << ", " << dims[i];
1055  }
1056  m_kwl.addPair(prefix, string("dimensions"), kwl_value.str());
1057  }
1058  }
1059  catch( const H5::Exception& e )
1060  {
1061  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
1062  }
1063 }
1064 
1065 void ossimHdf5Info::dumpNumericalTypeInfo(const H5::DataSet& dataset,
1067  const std::string& prefix) const
1068 {
1069  try
1070  {
1071  ossimScalarType stype = m_hdf5->getScalarType(dataset);
1073  m_kwl.addPair(prefix, string(ossimKeywordNames::SCALAR_TYPE_KW), sct.string());
1074 
1075  std::string byteOrderString = "little_endian";
1076  if ( byteOrder == OSSIM_BIG_ENDIAN )
1077  byteOrderString = "big_endian";
1078  m_kwl.addPair(prefix, string(ossimKeywordNames::BYTE_ORDER_KW), byteOrderString);
1079  }
1080  catch( const H5::Exception& e )
1081  {
1082  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
1083  }
1084 }
1085 
1086 void ossimHdf5Info::dumpIntType(const H5::IntType& dataType,
1087  const char* dataPtr,
1088  const std::string& prefix)const
1089 {
1090  std::string strValue;
1091  if(ossimHdf5::intTypeToString(strValue, dataType, dataPtr))
1092  {
1093  m_kwl.addPair(prefix, strValue);
1094  }
1095 
1096 }
1097 
1098 void ossimHdf5Info::dumpFloatType(const H5::FloatType& dataType,
1099  const char* dataPtr,
1100  const std::string& prefix)const
1101 {
1102  std::string strValue;
1103 
1104  if(ossimHdf5::floatTypeToString(strValue, dataType, dataPtr))
1105  {
1106  m_kwl.addPair(prefix, strValue);
1107  }
1108 }
1109 
1110 void ossimHdf5Info::dumpStringType(const H5::StrType& dataType,
1111  const char* dataPtr,
1112  const std::string& prefix)const
1113 {
1114  std::string strValue;
1115  if(ossimHdf5::stringTypeToString(strValue, dataType, dataPtr))
1116  {
1117  m_kwl.addPair(prefix, strValue);
1118  }
1119 }
1120 
1121 void ossimHdf5Info::dumpArrayType( H5::ArrayType& dataType,
1122  const char* dataPtr,
1123  const std::string& prefix)const
1124 {
1125  ossim_uint32 arrayNdims = dataType.getArrayNDims();
1126 // ossimByteOrder order = m_hdf5->getByteOrder(dataType);
1127 // ossimEndian endian;
1128 // bool swapOrder = (order!=ossim::byteOrder());
1129  H5::DataType superType = dataType.getSuper();
1130  //out << prefix<<".class_type: " << ossim_hdf5::getDatatypeClassType( dataType.getClass() ) << "\n";
1131  if(arrayNdims)
1132  {
1133  std::vector<hsize_t> dims(arrayNdims);
1134  dataType.getArrayDims(&dims.front());
1135  if(dims.size() > 0)
1136  {
1137  std::stringstream dimOut;
1138  ossimString dimString;
1139  ossim_uint32 idx = 1;
1140  ossim_uint32 nArrayElements = dims[0];
1141  std::copy(dims.begin(), --dims.end(),
1142  std::ostream_iterator<hsize_t>(dimOut,","));
1143  for(;idx<dims.size();++idx)
1144  {
1145  nArrayElements*=dims[idx];
1146  }
1147 
1148  dimString = ossimString("(") + dimOut.str() + ossimString::toString(dims[dims.size()-1])+")";
1149  m_kwl.addPair(prefix+".dimensions", dimString);
1150 
1151  ossim_uint32 typeSize = superType.getSize();
1152  switch(superType.getClass())
1153  {
1154  case H5T_STRING:
1155  {
1156  std::ostringstream out;
1157  ossimString newPrefix = prefix+".values";
1158  out<<"(";
1159  const char* startPtr = 0;
1160  const char* endPtr = 0;
1161  const char* mem = 0;
1162  H5T_str_t pad;
1163  ossim_int32 strSize = 0;
1164  for(idx=0;idx<nArrayElements;++idx)
1165  {
1166  mem = ((const char*)dataPtr) + (idx * typeSize);
1167  if(superType.isVariableStr())
1168  {
1169  startPtr = *(char**) mem;
1170  if(startPtr) strSize = std::strlen(startPtr);
1171  else strSize = 0;
1172  }
1173  else
1174  {
1175  startPtr = mem;
1176  }
1177  if(startPtr)
1178  {
1179  ossim_uint32 charIdx = 0;
1180  endPtr = startPtr;
1181  for (; ((charIdx < strSize) && (*endPtr)); ++charIdx,++endPtr);
1182 
1183  }
1184  ossimString value = ossimString(startPtr, endPtr);
1185  if(idx == 0)
1186  {
1187  out << "\""<<value<< "\"";
1188  }
1189  else
1190  {
1191  out << ", \""<<value<< "\"";
1192  }
1193  }
1194  out << ")";
1195  //out<<prefix<<".array_type: H5T_STRING\n";
1196 // out<<prefix<<".values: <NOT SUPPORTED>";
1197  m_kwl.addPair(newPrefix, out.str());
1198  m_kwl.addPair(prefix+".array_type", "H5T_STRING");
1199 
1200  break;
1201  }
1202  case H5T_INTEGER:
1203  {
1204  ostringstream out;
1205  H5::IntType* dataTypePtr = (H5::IntType*)(&superType);
1206  ossimByteOrder order = m_hdf5->getByteOrder(*dataTypePtr);
1207  ossimEndian endian;
1208  bool swapOrder = (order!=ossim::byteOrder());
1209  ossimString newPrefix = prefix+".values";
1210  out<<"(";
1211  for(idx=0;idx<nArrayElements;++idx)
1212  {
1213  std::string value;
1214  ossimHdf5::intTypeToString(value, *dataTypePtr, dataPtr);
1215  if((idx + 1) <nArrayElements)
1216  {
1217  out << value << ", ";
1218  }
1219  else
1220  {
1221  out << value;
1222  }
1223  dataPtr+=typeSize;
1224  }
1225  out << ")";
1226  m_kwl.addPair(newPrefix, out.str());
1227  m_kwl.addPair(prefix+".array_type", "H5T_INTEGER");
1228  break;
1229  }
1230  case H5T_FLOAT:
1231  {
1232  ostringstream out;
1233  H5::FloatType* dataTypePtr = (H5::FloatType*)(&superType);
1234  ossimByteOrder order = m_hdf5->getByteOrder(*dataTypePtr);
1235  ossimEndian endian;
1236  bool swapOrder = (order!=ossim::byteOrder());
1237 
1238  //out<<prefix<<".array_type: H5T_INTEGER\n";
1239  ossimString newPrefix = prefix+".values";
1240  out<<"(";
1241  for(idx=0;idx<nArrayElements;++idx)
1242  {
1243  std::string value;
1244  ossimHdf5::floatTypeToString(value, *dataTypePtr, dataPtr);
1245  if((idx + 1) <nArrayElements)
1246  {
1247  out << value << ", ";
1248  }
1249  else
1250  {
1251  out << value;
1252  }
1253  dataPtr+=typeSize;
1254  }
1255  out << ")";
1256  m_kwl.addPair(newPrefix, out.str());
1257  m_kwl.addPair(prefix+".array_type", "H5T_FLOAT");
1258  break;
1259  }
1260  default:
1261  {
1262  break;
1263  }
1264  }
1265 
1266  }
1267  }
1268 
1269 }
1270 
1271 
1272 void ossimHdf5Info::dumpNumerical(const H5::DataSet& dataset,
1273  const char* dataPtr,
1274  const std::string& prefix) const
1275 {
1276  try
1277  {
1278  H5::IntType dataType = dataset.getIntType();
1279  ossimByteOrder order = m_hdf5->getByteOrder(&dataset);
1280  ossimEndian endian;
1281  bool swapOrder = (order!=ossim::byteOrder());
1282 
1283  ossimString valueStr;
1284  ossimScalarType scalarType = m_hdf5->getScalarType(dataset);
1285  switch(scalarType)
1286  {
1287  case OSSIM_UINT8:
1288  {
1289  ossim_uint8 value = *reinterpret_cast<const ossim_uint8*>(dataPtr);
1290  valueStr = ossimString::toString(value).string();
1291  break;
1292  }
1293  case OSSIM_SINT8:
1294  {
1295  ossim_int8 value = *reinterpret_cast<const ossim_int8*>(dataPtr);
1296  valueStr = ossimString::toString(value);
1297  break;
1298  }
1299  case OSSIM_UINT16:
1300  {
1301  ossim_uint16 value = *reinterpret_cast<const ossim_uint16*>(dataPtr);
1302  if(swapOrder)
1303  endian.swap(value);
1304  valueStr = ossimString::toString(value);
1305  break;
1306  }
1307  case OSSIM_SINT16:
1308  {
1309  ossim_int16 value = *reinterpret_cast<const ossim_int16*>(dataPtr);
1310  if(swapOrder)
1311  endian.swap(value);
1312  valueStr = ossimString::toString(value);
1313  break;
1314  }
1315  case OSSIM_UINT32:
1316  {
1317  ossim_uint32 value = *reinterpret_cast<const ossim_uint32*>(dataPtr);
1318  if(swapOrder)
1319  endian.swap(value);
1320  valueStr = ossimString::toString(value);
1321  break;
1322  }
1323  case OSSIM_SINT32:
1324  {
1325  ossim_int32 value = *reinterpret_cast<const ossim_int32*>(dataPtr);
1326  if(swapOrder)
1327  endian.swap(value);
1328  valueStr = ossimString::toString(value);
1329  break;
1330  }
1331  case OSSIM_UINT64:
1332  {
1333  ossim_uint64 value = *reinterpret_cast<const ossim_uint64*>(dataPtr);
1334  if(swapOrder)
1335  endian.swap(value);
1336  valueStr = ossimString::toString(value);
1337  break;
1338  }
1339  case OSSIM_FLOAT32:
1340  {
1341  ossim_float32 value = *reinterpret_cast<const ossim_int64*>(dataPtr);
1342  if(swapOrder)
1343  endian.swap(value);
1344  valueStr = ossimString::toString(value);
1345  break;
1346  }
1347  case OSSIM_FLOAT64:
1348  {
1349  ossim_float64 value = *reinterpret_cast<const ossim_int64*>(dataPtr);
1350  if(swapOrder)
1351  endian.swap(value);
1352  valueStr = ossimString::toString(value);
1353  break;
1354  }
1355  default:
1356  {
1357  valueStr = "<UNHANDLED SCALAR TYPE>";
1358  break;
1359  }
1360  }
1361 
1362  m_kwl.addPair(prefix, string("value"), valueStr.string());
1363  }
1364  catch( const H5::Exception& e )
1365  {
1366  ossimNotify(ossimNotifyLevel_WARN)<<e.getDetailMsg();
1367  }
1368 }
1369 
1370 
1371 
8 bit signed integer
void dumpGroup(const H5::Group &group, const std::string &prefix, ossim_uint32 &recursedCount) const
static const char * BYTE_ORDER_KW
char ossim_int8
Previous DLL import export section.
std::ostream & printSubGroups(std::ostream &out, const H5::Group &obj, const ossimString &lm=ossimString()) const
void dumpDataset(const H5::DataSet &dataset, const std::string &prefix) const
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
virtual std::ostream & print(std::ostream &out) const
std::basic_stringstream< char > stringstream
Class for char mixed input and output memory streams.
Definition: ossimIosFwd.h:38
64 bit floating point
void dumpArrayTypeInfo(H5::ArrayType datatype, const std::string &prefix) const
bool getRoot(H5::Group &root) const
Assigns the root group.
Definition: ossimHdf5.cpp:93
16 bit unsigned integer
void dumpCompound(const H5::DataSet &dataset, const H5::CompType &compound, const std::string &prefix) const
void dumpAttribute(const H5::Attribute &attr, const std::string &prefix) const
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
float ossim_float32
virtual ossimString getEntryString(ossim_int32 entry_number) const
std::ostream & printDatasets(std::ostream &out, const H5::Group &obj, const ossimString &lm=ossimString()) const
static ossimString toString(bool aValue)
Numeric to string methods.
16 bit signed integer
void dumpFloatType(const H5::FloatType &dataType, const char *dataPtr, const std::string &prefix) const
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
void addPair(const std::string &key, const std::string &value, bool overwrite=true)
OSSIM_DLL ossimByteOrder byteOrder()
Definition: ossimCommon.cpp:54
32 bit floating point
void dumpArrayType(H5::ArrayType &dataType, const char *dataPtr, const std::string &prefix) const
ossimHdf5Info()
default constructor
void dumpCompoundTypeInfo(const H5::CompType &compound, const std::string &prefix) const
unsigned short ossim_uint16
32 bit unsigned integer
ossimString getObjectPrefix(const ossimString &prefix, const ossimString &fullPathName) const
bool open(const ossimFilename &hdf5File)
Opens specified HDF5 file.
Definition: ossimHdf5.cpp:29
void dumpAttributes(const H5::H5Object &container, const std::string &prefix) const
static bool getDatasets(H5::Group group, std::vector< H5::DataSet > &datasetList, bool recursive=false)
Assigns list of datasets under specified group.
Definition: ossimHdf5.cpp:150
ossimRefPtr< ossimHdf5 > m_hdf5
void dumpEnumTypeInfo(H5::EnumType datatype, const std::string &prefix) const
void dumpNumericalTypeInfo(const H5::DataSet &dataset, ossimByteOrder order, const std::string &prefix) const
double ossim_float64
static ossimScalarTypeLut * instance()
Returns the static instance of an ossimScalarTypeLut object.
static ossimByteOrder getByteOrder(const H5::AbstractDs *obj)
Definition: ossimHdf5.cpp:337
void dumpIntType(const H5::IntType &dataType, const char *dataPtr, const std::string &prefix) const
virtual bool getKeywordlist(ossimKeywordlist &kwl) const
Method to dump info to a keyword list.
static ossimScalarType getScalarType(const H5::DataSet &dataset)
Definition: ossimHdf5.cpp:475
yy_size_t size
H5::Group * findGroupByName(const std::string &group_name, const H5::Group *parent_group=0, bool recursive=false) const
Finds a group by name.
Definition: ossimHdf5.cpp:251
32 bit signed integer
static std::string getDatatypeClassType(ossim_int32 type)
Definition: ossimHdf5.cpp:395
unsigned long long ossim_uint64
unsigned int ossim_uint32
static bool getChildGroups(H5::Group group, std::vector< H5::Group > &groupList, bool recursive=false)
Assigns list of groups under specified group.
Definition: ossimHdf5.cpp:112
static bool stringTypeToString(std::string &result, const H5::StrType &dataType, const char *dataPtr)
Definition: ossimHdf5.cpp:760
Info Base.
Definition: ossimInfoBase.h:32
ossimByteOrder
ossimKeywordlist m_kwl
static bool floatTypeToString(std::string &result, const H5::FloatType &dataType, const char *dataPtr)
Definition: ossimHdf5.cpp:577
virtual ~ossimHdf5Info()
virtual destructor
static bool getAttributes(const H5::H5Object &obj, std::vector< H5::Attribute > &attrList)
Definition: ossimHdf5.cpp:227
ossimScalarType
Low-level OSSIM interface to HDF5 libraries.
Definition: ossimHdf5.h:27
short ossim_int16
virtual bool getKeywordlistGroup(ossimKeywordlist &kwl, const std::string &groupName) const
H5::DataSet * findDatasetByName(const std::string &dataset_name, const H5::Group *group=0, bool recursive=false) const
Finds a dataset by name.
Definition: ossimHdf5.cpp:295
64 bit unsigned integer
void dumpStringType(const H5::StrType &dataType, const char *dataPtr, const std::string &prefix) const
std::ostream & printAttributes(std::ostream &out, const H5::H5Object &obj, const ossimString &lm=ossimString()) const
virtual bool getKeywordlistDataset(ossimKeywordlist &kwl, const std::string &datasetName) const
static void getExtents(const H5::DataSet &dataset, std::vector< ossim_uint32 > &extents)
Definition: ossimHdf5.cpp:444
void dumpNumerical(const H5::DataSet &dataset, const char *dataPtr, const std::string &prefix) const
long long ossim_int64
static const char * SCALAR_TYPE_KW
8 bit unsigned integer
ossimRefPtr< ossimHdf5 > m_hdf5
void swap(ossim_sint8 &)
Definition: ossimEndian.h:26
virtual bool open(const ossimFilename &file)
unsigned char ossim_uint8
static bool intTypeToString(std::string &result, const H5::IntType &dataType, const char *dataPtr)
Definition: ossimHdf5.cpp:616
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
int ossim_int32
const std::string & string() const
Definition: ossimString.h:414