From f148ff3caf533e9f6029798617f0a8087bcd6c05 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Wed, 6 Dec 2000 19:04:08 -0500 Subject: [svn-r3080] Purpose: Support portability Description: I forgot that source file extension .C will not work on Windows. Solution: Changed all source file from *.C to *.cpp for portability. Platforms tested: arabica (sparc-sun-solaris 2.7) --- c++/src/H5AbstractDs.cpp | 132 +++++++++++++ c++/src/H5AtomType.cpp | 146 ++++++++++++++ c++/src/H5Attribute.cpp | 122 ++++++++++++ c++/src/H5CommonFG.cpp | 285 ++++++++++++++++++++++++++++ c++/src/H5CompType.cpp | 225 ++++++++++++++++++++++ c++/src/H5DataSet.cpp | 207 ++++++++++++++++++++ c++/src/H5DataSpace.cpp | 323 +++++++++++++++++++++++++++++++ c++/src/H5DataType.cpp | 341 +++++++++++++++++++++++++++++++++ c++/src/H5DcreatProp.cpp | 173 +++++++++++++++++ c++/src/H5DxferProp.cpp | 183 ++++++++++++++++++ c++/src/H5EnumType.cpp | 128 +++++++++++++ c++/src/H5Exception.cpp | 195 +++++++++++++++++++ c++/src/H5FaccProp.cpp | 244 ++++++++++++++++++++++++ c++/src/H5FcreatProp.cpp | 120 ++++++++++++ c++/src/H5File.cpp | 474 ++++++++++++++++++++++++++++++++++++++++++++++ c++/src/H5FloatType.cpp | 153 +++++++++++++++ c++/src/H5Group.cpp | 382 +++++++++++++++++++++++++++++++++++++ c++/src/H5IdComponent.cpp | 136 +++++++++++++ c++/src/H5IntType.cpp | 78 ++++++++ c++/src/H5Library.cpp | 67 +++++++ c++/src/H5Object.cpp | 168 ++++++++++++++++ c++/src/H5PredType.cpp | 192 +++++++++++++++++++ c++/src/H5PropList.cpp | 103 ++++++++++ c++/src/H5RefCounter.cpp | 35 ++++ c++/src/H5StrType.cpp | 103 ++++++++++ 25 files changed, 4715 insertions(+) create mode 100644 c++/src/H5AbstractDs.cpp create mode 100644 c++/src/H5AtomType.cpp create mode 100644 c++/src/H5Attribute.cpp create mode 100644 c++/src/H5CommonFG.cpp create mode 100644 c++/src/H5CompType.cpp create mode 100644 c++/src/H5DataSet.cpp create mode 100644 c++/src/H5DataSpace.cpp create mode 100644 c++/src/H5DataType.cpp create mode 100644 c++/src/H5DcreatProp.cpp create mode 100644 c++/src/H5DxferProp.cpp create mode 100644 c++/src/H5EnumType.cpp create mode 100644 c++/src/H5Exception.cpp create mode 100644 c++/src/H5FaccProp.cpp create mode 100644 c++/src/H5FcreatProp.cpp create mode 100644 c++/src/H5File.cpp create mode 100644 c++/src/H5FloatType.cpp create mode 100644 c++/src/H5Group.cpp create mode 100644 c++/src/H5IdComponent.cpp create mode 100644 c++/src/H5IntType.cpp create mode 100644 c++/src/H5Library.cpp create mode 100644 c++/src/H5Object.cpp create mode 100644 c++/src/H5PredType.cpp create mode 100644 c++/src/H5PropList.cpp create mode 100644 c++/src/H5RefCounter.cpp create mode 100644 c++/src/H5StrType.cpp diff --git a/c++/src/H5AbstractDs.cpp b/c++/src/H5AbstractDs.cpp new file mode 100644 index 0000000..5424bdb --- /dev/null +++ b/c++/src/H5AbstractDs.cpp @@ -0,0 +1,132 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5AbstractDs.h" +#include "H5Alltypes.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Default constructor +AbstractDs::AbstractDs() : H5Object() {} + +// Constructor that takes an id +AbstractDs::AbstractDs( const hid_t ds_id ) : H5Object( ds_id ) {} + +// Copy constructor: makes copy of the original object; simply invokes +// base-class copy constructor. +AbstractDs::AbstractDs( const AbstractDs& original ) : H5Object( original ) {} + +// Returns the class of the datatype that is used by this dataset +H5T_class_t AbstractDs::getTypeClass() const +{ + // Gets the datatype used by this dataset or attribute. + // p_getType calls either H5Dget_type or H5Aget_type depending on + // which object invokes getTypeClass + DataType datatype( p_getType()); + + // Gets the class of the datatype and validate it before returning + H5T_class_t type_class = H5Tget_class( datatype.getId()); + if( type_class != H5T_NO_CLASS ) + return( type_class ); + else + { + throw DataTypeIException(); + } +} + +// Returns the generic datatype of this abstract dataset which +// can be a dataset or an attribute. +DataType AbstractDs::getDataType() const +{ + // Gets the id of the datatype used by this dataset or attribute. + // p_getType calls either H5Dget_type or H5Aget_type depending on + // which object invokes getTypeClass + hid_t datatype_id = p_getType(); // returned value is already validated + + // Create and return the DataType object + DataType datatype( datatype_id ); + return( datatype ); +} + +// Returns the enumeration datatype of this abstract dataset which +// can be a dataset or an attribute. +EnumType AbstractDs::getEnumType() const +{ + EnumType enumtype( p_getType()); + return( enumtype ); +} + +// Returns the compound datatype of this abstract dataset which +// can be a dataset or an attribute. +CompType AbstractDs::getCompType() const +{ + CompType comptype( p_getType()); + return( comptype ); +} + +// Returns the integer datatype of this abstract dataset which +// can be a dataset or an attribute. +IntType AbstractDs::getIntType() const +{ + IntType inttype( p_getType()); + return( inttype ); +} + +// Returns the floating-point datatype of this abstract dataset which +// can be a dataset or an attribute. +FloatType AbstractDs::getFloatType() const +{ + FloatType floatype( p_getType()); + return( floatype ); +} + +// Returns the string datatype of this abstract dataset which +// can be a dataset or an attribute. +StrType AbstractDs::getStrType() const +{ + StrType strtype( p_getType()); + return( strtype ); +} + +/* This version of getDataType is older style. New style above doesn't +use overloading. Remove it when knowing for sure that the other way +is prefered +// Gets the specific datatype of this abstract dataset which can be a +// dataset or an attribute. Several overloaded getDataType's below +// are for specific sub-datatypes. +void AbstractDs::getDataType( EnumType& enumtype ) const +{ + enumtype.setId( p_getType()); +} + +void AbstractDs::getDataType( CompType& comptype ) const +{ + comptype.setId( p_getType()); +} + +void AbstractDs::getDataType( IntType& inttype ) const +{ + inttype.setId( p_getType()); +} + +void AbstractDs::getDataType( FloatType& floatype ) const +{ + floatype.setId( p_getType()); +} + +void AbstractDs::getDataType( StrType& strtype ) const +{ + strtype.setId( p_getType()); +} +end of old style of getDataType */ + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5AtomType.cpp b/c++/src/H5AtomType.cpp new file mode 100644 index 0000000..bdd98b0 --- /dev/null +++ b/c++/src/H5AtomType.cpp @@ -0,0 +1,146 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5DataType.h" +#include "H5AtomType.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Default constructor +AtomType::AtomType() : DataType() {} + +// Constructor that takes an existing id +AtomType::AtomType( const hid_t existing_id ) : DataType( existing_id ) {} + +// Copy constructor: makes a copy of the original AtomType object. +AtomType::AtomType( const AtomType& original ) : DataType( original ) {} + +// Sets the total size for an atomic datatype. +void AtomType::setSize( size_t size ) const +{ + // Call C routine H5Tset_size to set the total size + herr_t ret_value = H5Tset_size( id, size ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Returns the byte order of an atomic datatype. Inheritance class??? +H5T_order_t AtomType::getOrder( string& order_string ) const +{ + // Call C routine to get the byte ordering + H5T_order_t type_order = H5Tget_order( id ); + + // return a byte order constant if successful + if( type_order == H5T_ORDER_ERROR ) + { + throw DataTypeIException(); + } + if( type_order == H5T_ORDER_LE ) + order_string = "Little endian byte ordering (0)"; + else if( type_order == H5T_ORDER_BE ) + order_string = "Big endian byte ordering (1)"; + else if( type_order == H5T_ORDER_VAX ) + order_string = "VAX mixed byte ordering (2)"; + return( type_order ); +} + +// Sets the byte ordering of an atomic datatype. Inheritance class??? +void AtomType::setOrder( H5T_order_t order ) const +{ + // Call C routine to set the byte ordering + herr_t ret_value = H5Tset_order( id, order ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Returns the precision of an atomic datatype. +size_t AtomType::getPrecision() const +{ + size_t num_signi_bits = H5Tget_precision( id ); // C routine + + // returns number of significant bits if successful + if( num_signi_bits == 0 ) + { + throw DataTypeIException(); + } + return( num_signi_bits ); +} + +// Sets the precision of an atomic datatype. +void AtomType::setPrecision( size_t precision ) const +{ + // Call C routine to set the datatype precision + herr_t ret_value = H5Tset_precision( id, precision ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Retrieves the bit offset of the first significant bit. +// 12/05/00: due to C API change +// - return type changed from size_t to int +// - offset = -1 when failure occurs vs. 0 +int AtomType::getOffset() const +{ + int offset = H5Tget_offset( id ); // C routine + + // returns a non-negative offset value if successful + if( offset == -1 ) + { + throw DataTypeIException(); + } + return( offset ); +} + +// Sets the bit offset of the first significant bit. +void AtomType::setOffset( size_t offset ) const +{ + // Call C routine to set the bit offset + herr_t ret_value = H5Tset_offset( id, offset ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Retrieves the padding type of the least and most-significant bit padding. +// these two are for Opaque type +//void AtomType::getPad( H5T_pad_t& lsb, H5T_pad_t& msb ) const +//{ + // Call C routine to get the padding type + //herr_t ret_value = H5Tget_pad( id, &lsb, &msb ); + //if( ret_value < 0 ) + //{ + //throw DataTypeIException(); + //} +//} + +// Sets the least and most-significant bits padding types +//void AtomType::setPad( H5T_pad_t lsb, H5T_pad_t msb ) const +//{ + // Call C routine to set the padding type + //herr_t ret_value = H5Tset_pad( id, lsb, msb ); + //if( ret_value < 0 ) + //{ + //throw DataTypeIException(); + //} +//} + +// This destructor terminates access to the datatype; it calls ~DataType +AtomType::~AtomType() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp new file mode 100644 index 0000000..03b50b9 --- /dev/null +++ b/c++/src/H5Attribute.cpp @@ -0,0 +1,122 @@ +#include + +#include "H5Include.h" +#include "H5Exception.h" +#include "H5RefCounter.h" +#include "H5IdComponent.h" +#include "H5Idtemplates.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5AbstractDs.h" +#include "H5Attribute.h" +#include "H5DataType.h" +#include "H5DataSpace.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Copy constructor: makes a copy of the original object; simply invokes +// the base class copy constructor. +Attribute::Attribute( const Attribute& original ) : AbstractDs( original ) {} + +// Creates a copy of an existing attribute using an id +Attribute::Attribute( const hid_t attr_id ) : AbstractDs( attr_id ) {} + +// Writes data to this attribute. +void Attribute::write( const DataType& mem_type, void *buf ) const +{ + herr_t ret_value = H5Awrite( id, mem_type.getId(), buf ); + if( ret_value < 0 ) + { + throw AttributeIException(); + } +} + +// Reads data from this attribute. +void Attribute::read( const DataType& mem_type, void *buf ) const +{ + herr_t ret_value = H5Aread( id, mem_type.getId(), buf ); + if( ret_value < 0 ) + { + throw AttributeIException(); + } +} + +// Gets a copy of the dataspace for this attribute. +DataSpace Attribute::getSpace() const +{ + // Calls C function H5Aget_space to get the id of the dataspace + hid_t dataspace_id = H5Aget_space( id ); + + // If the dataspace id is valid, create and return the DataSpace object + if( dataspace_id > 0 ) + { + DataSpace dataspace( dataspace_id ); + return( dataspace ); + } + else + { + throw AttributeIException(); + } +} + +// This private member function calls the C API to get the generic datatype +// of the datatype that is used by this attribute. This function is used +// by the overloaded functions getDataType defined in AbstractDs for the +// generic datatype and specific sub-types. +hid_t Attribute::p_getType() const +{ + hid_t type_id = H5Aget_type( id ); + if( type_id > 0 ) + return( type_id ); + else + { + throw AttributeIException(); + } +} + +// Gets the name of this attribute. +string Attribute::getName( size_t buf_size ) const +{ + char* name_C = new char[buf_size+1]; // temporary C-string for C API + + // Calls C routine H5Aget_name to get the name of the attribute + herr_t name_size = H5Aget_name( id, buf_size, name_C ); + + // If H5Aget_name returns a negative value, raise an exception, + if( name_size < 0 ) + { + throw AttributeIException(); + } + // otherwise, create the string to hold the attribute name and return it + string name = string( name_C ); + delete name_C; + return( name ); +} + +// This private function calls the C API H5Aclose to close this attribute. +// Used by the IdComponent::reset. +void Attribute::p_close() const +{ + herr_t ret_value = H5Aclose( id ); + if( ret_value < 0 ) + { + throw AttributeIException(); + } +} + +// The destructor of this instance calls IdComponent::reset to +// reset its identifier - no longer true +// Older compilers (baldric) don't support template member functions +// and IdComponent::reset is one; so at this time, the resetId is not +// a member function so it can be template to work around that problem. +Attribute::~Attribute() +{ + // The attribute id will be closed properly + resetIdComponent( this ); +} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5CommonFG.cpp b/c++/src/H5CommonFG.cpp new file mode 100644 index 0000000..6ece682 --- /dev/null +++ b/c++/src/H5CommonFG.cpp @@ -0,0 +1,285 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5FaccProp.h" +#include "H5FcreatProp.h" +#include "H5DxferProp.h" +#include "H5DcreatProp.h" +#include "H5Group.h" +#include "H5AbstractDs.h" +#include "H5DataSpace.h" +#include "H5DataSet.h" +#include "H5File.h" +#include "H5Alltypes.h" + +// Since several compilers do not have support template functions, the +// code in H5templates.h are modified to become the common code defined +// in this file. The common functions use the hdf5 id that is provided +// by the appropriate objects. +// October 2000 + +// There are a few comments that are common to most of the functions +// defined in this file so they are listed here. +// - when a failure returned by the C API, the functions will +// throw an exception, called File_GroupException, so Group or File can +// catch it and throw the appropriate exception to the user's application, +// i.e., GroupInterfaceException or FileInterfaceException. +// June 2000 + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif +// Creates a new group at this location which can be a file or another group. +Group createGroupT( const hid_t loc_id, const string name, size_t size_hint ) +{ + // Convert string to C-string + const char* name_C; + name_C = name.c_str(); // name_C refers to the contents of name as a C-str + + // Call C routine H5Gcreate to create the named group, giving the + // location id which can be a file id or a group id + hid_t group_id = H5Gcreate( loc_id, name_C, size_hint ); + + // If the group id is valid, create and return the Group object + if( group_id > 0 ) + { + Group group( group_id ); + return( group ); + } + else + { + throw File_GroupException(); + } +} + +// Opens an existing group in a location which can be a file or another group +Group openGroupT( const hid_t loc_id, const string name ) +{ + // Convert string to C-string + const char* name_C; + name_C = name.c_str(); // name_C refers to the contents of name as a C-str + + // Call C routine H5Gopen to open the named group, giving the + // location id which can be a file id or a group id + hid_t group_id = H5Gopen( loc_id, name_C ); + + // If the group id is valid, create and return the Group object + if( group_id > 0 ) + { + Group group( group_id ); + return( group ); + } + else + { + throw File_GroupException(); + } +} + +// Creates a new dataset at this location. +DataSet createDataSetT( const hid_t loc_id, const string name, const DataType& data_type, const DataSpace& data_space, const DSetCreatPropList& create_plist ) +{ + // Convert the dataset's name in C++ string to C-string + const char* name_C; + name_C = name.c_str(); // name_C refers to the contents of name as a C-str + + // Obtain identifiers for C API + hid_t type_id = data_type.getId(); + hid_t space_id = data_space.getId(); + hid_t create_plist_id = create_plist.getId(); + + // Call C routine H5Dcreate to create the named dataset + hid_t dataset_id = H5Dcreate( loc_id, name_C, type_id, space_id, create_plist_id ); + + // If the dataset id is valid, create and return the DataSet object + if( dataset_id > 0 ) + { + DataSet dataset( dataset_id ); + return( dataset ); + } + else + { + throw File_GroupException(); + } +} + +// Opens an existing dataset at this location. +DataSet openDataSetT( const hid_t loc_id, const string name ) +{ + // Convert the dataset's name in C++ string to C-string + const char* name_C; + name_C = name.c_str(); // name_C refers to the contents of name as a C-str + + // Call C function H5Dopen to open the specified dataset, giving + // the location id and the dataset's name + hid_t dataset_id = H5Dopen( loc_id, name_C ); + + // If the dataset id is valid, create and return the DataSet object + if( dataset_id > 0 ) + { + DataSet dataset( dataset_id ); + return( dataset ); + } + else + { + throw File_GroupException(); + } +} + +// Creates a link of the specified type from new_name to current_name; +// both names are interpreted relative to the specified location id +void linkT( const hid_t loc_id, H5G_link_t link_type, const string curr_name, const string new_name ) +{ + // Convert string to C-string + const char* curr_name_C, *new_name_C; + curr_name_C = curr_name.c_str(); // refers to contents of curr_name as a C-str + new_name_C = new_name.c_str(); // refers to contents of new_name as a C-str + + herr_t ret_value = H5Glink( loc_id, link_type, curr_name_C, new_name_C ); + if( ret_value < 0 ) + { + throw File_GroupException(); + } +} + +// Removes the specified name at this location. +void unlinkT( const hid_t loc_id, const string name ) +{ + // Convert string to C-string + const char* name_C; + name_C = name.c_str(); // name_C refers to the contents of name as a C-str + + herr_t ret_value = H5Gunlink( loc_id, name_C ); + if( ret_value < 0 ) + { + throw File_GroupException(); + } +} + +// Renames an object at this location. +void moveT( const hid_t loc_id, const string src, const string dst ) +{ + // Convert string to C-string + const char* src_C, *dst_C; + src_C = src.c_str(); // refers to contents of src as a C-str + dst_C = dst.c_str(); // refers to contents of dst as a C-str + + herr_t ret_value = H5Gmove( loc_id, src_C, dst_C ); + if( ret_value < 0 ) + { + throw File_GroupException(); + } +} + +// Returns information about an object +void getObjinfoT( const hid_t loc_id, const string name, hbool_t follow_link, H5G_stat_t& statbuf ) +{ + // Convert string to C-string + const char* name_C; + name_C = name.c_str(); // name_C refers to the contents of name as a C-str + + herr_t ret_value = H5Gget_objinfo( loc_id, name_C, follow_link, &statbuf ); + if( ret_value < 0 ) + { + throw File_GroupException(); + } +} + +// Returns the name of the object that the symbolic link points to. +string getLinkvalT( const hid_t loc_id, const string name, size_t size ) +{ + // Convert string to C-string - name_C refers to the contents of name + // as a C string + const char* name_C = name.c_str(); + + char* value_C = new char[size+1]; // temporary C-string for C API + + herr_t ret_value = H5Gget_linkval( loc_id, name_C, size, value_C ); + if( ret_value < 0 ) + { + throw File_GroupException(); + } + string value = string( value_C ); + delete value_C; + return( value ); +} + +// Sets the comment for an object specified by its name +void setCommentT( const hid_t loc_id, const string name, const string comment ) +{ + // Convert strings to C-strings + const char* name_C, *comment_C; + name_C = name.c_str(); // refers to the contents of name as a C-str + comment_C = comment.c_str(); // refers to the contents of comment as a C-str + herr_t ret_value = H5Gset_comment( loc_id, name_C, comment_C ); + if( ret_value < 0 ) + { + throw File_GroupException(); + } +} + +// Retrieves comment for specified object +string getCommentT( const hid_t loc_id, const string name, size_t bufsize ) +{ + // Convert string to C-string - name_C refers to the contents of name + // as a C string + const char* name_C = name.c_str(); + + // temporary C-string for the object's comment + char* comment_C = new char[bufsize+1]; + + herr_t ret_value = H5Gget_comment( loc_id, name_C, bufsize, comment_C ); + + // if H5Gget_comment returns SUCCEED, return the string comment + if( ret_value < 0 ) + { + throw File_GroupException(); + } + string comment = string( comment_C ); + delete comment_C; + return( comment ); +} + +// Mounts the file 'child' onto this group +void mountT( const hid_t loc_id, const string name, hid_t child_id, PropList& plist ) +{ + // Obtain identifiers for C API + hid_t plist_id = plist.getId(); + + // Convert string to C-string + const char* name_C; + name_C = name.c_str(); // name_C refers to the contents of name as a C-str + + // Call C routine H5Fmount to do the mouting + herr_t ret_value = H5Fmount( loc_id, name_C, child_id, plist_id ); + + // Raise exception if H5Fmount returns negative value + if( ret_value < 0 ) + { + throw File_GroupException(); + } +} + +// Unmounts the file named 'name' from this parent group +void unmountT( const hid_t loc_id, const string name ) +{ + // Convert string to C-string + const char* name_C; + name_C = name.c_str(); // name_C refers to the contents of name as a C-str + + // Call C routine H5Fmount to do the mouting + herr_t ret_value = H5Funmount( loc_id, name_C ); + + // Raise exception if H5Funmount returns negative value + if( ret_value < 0 ) + { + throw File_GroupException(); + } +} +#ifndef H5_NO_NAMESPACE +} +#endif diff --git a/c++/src/H5CompType.cpp b/c++/src/H5CompType.cpp new file mode 100644 index 0000000..634d817 --- /dev/null +++ b/c++/src/H5CompType.cpp @@ -0,0 +1,225 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5Alltypes.h" +#include "H5AbstractDs.h" +#include "H5DxferProp.h" +#include "H5DataSpace.h" +#include "H5DataSet.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Creates a new compound datatype +CompType::CompType( size_t size ) : DataType( H5T_COMPOUND, size ) {} + +// Creates a compound datatype using an existing id +CompType::CompType( const hid_t existing_id ) : DataType( existing_id ) {} + +// Default constructor +CompType::CompType() : DataType() {} + +// Copy constructor: makes copy of the original CompType object +CompType::CompType( const CompType& original ) : DataType( original ) {} + +// Gets the compound datatype of the specified dataset - reimplement this +CompType::CompType( const DataSet& dataset ) : DataType() +{ + // Calls C function H5Dget_type to get the id of the datatype + id = H5Dget_type( dataset.getId() ); + + // If the datatype id is invalid, throw exception + if( id <= 0 ) + { + throw DataSetIException(); + } +} + +// Retrieves the number of members in this compound datatype. +int CompType::getNmembers() const +{ + int num_members = H5Tget_nmembers( id ); + if( num_members < 0 ) + { + throw DataTypeIException(); + } + return( num_members ); +} + +// Retrieves the name of a member of this compound datatype. +string CompType::getMemberName( int member_num ) const +{ + char* member_name_C = H5Tget_member_name( id, member_num ); + if( member_name_C == NULL ) // should this be returned also??? + { + throw DataTypeIException(); + } + string member_name = string( member_name_C ); + return( member_name ); +} + +// Retrieves the offset of a member of a compound datatype. +size_t CompType::getMemberOffset( int member_num ) const +{ + size_t offset = H5Tget_member_offset( id, member_num ); + // Q. said: for now, 0 is not a failure + //if( offset == 0 ) + //{ + //throw DataTypeIException(); + //} + return( offset ); +} + +// Returns the dimensionality of the member. +int CompType::getMemberDims( int member_num, size_t* dims, int* perm ) const +{ + throw DataTypeIException( "Error: getMemberDims is no longer supported." ); +} + +// Gets the type class of the specified member. +H5T_class_t CompType::getMemberClass( int member_num ) const +{ + // get the member datatype first + hid_t member_type_id = H5Tget_member_type( id, member_num ); + if( member_type_id <= 0 ) + { + throw DataTypeIException(); + } + + // then get its class + H5T_class_t member_class = H5Tget_class( member_type_id ); + if( member_class == H5T_NO_CLASS ) + { + throw DataTypeIException(); + } + return( member_class ); +} + +// This private member function calls the C API to get the identifier +// of the specified member. It is used by the getMemberXxxType +// below for the sub-types. +hid_t CompType::p_getMemberType( int member_num ) const +{ + hid_t member_type_id = H5Tget_member_type( id, member_num ); + if( member_type_id > 0 ) + return( member_type_id ); + else + { + throw DataTypeIException(); + } +} + +// Returns the datatype of the specified member in this compound datatype. +DataType CompType::getMemberDataType( int member_num ) const +{ + DataType datatype( p_getMemberType( member_num )); + return( datatype ); +} + +EnumType CompType::getMemberEnumType( int member_num ) const +{ + EnumType enumtype( p_getMemberType( member_num )); + return( enumtype ); +} + +CompType CompType::getMemberCompType( int member_num ) const +{ + CompType comptype( p_getMemberType( member_num )); + return( comptype ); +} + +IntType CompType::getMemberIntType( int member_num ) const +{ + IntType inttype( p_getMemberType( member_num )); + return( inttype ); +} + +FloatType CompType::getMemberFloatType( int member_num ) const +{ + FloatType floatype( p_getMemberType( member_num )); + return( floatype ); +} + +StrType CompType::getMemberStrType( int member_num ) const +{ + StrType strtype( p_getMemberType( member_num )); + return( strtype ); +} + +/* old style of getMemberType - using overloads; new style above + returns the appropriate datatypes but has different named functions. +// Returns the datatype of the specified member in this compound datatype. +// Several overloading of getMemberType are for different datatypes +void CompType::getMemberType( int member_num, EnumType& enumtype ) const +{ + p_getMemberType( member_num, enumtype ); +} + +void CompType::getMemberType( int member_num, CompType& comptype ) const +{ + p_getMemberType( member_num, comptype ); +} + +void CompType::getMemberType( int member_num, IntType& inttype ) const +{ + p_getMemberType( member_num, inttype ); +} + +void CompType::getMemberType( int member_num, FloatType& floatype ) const +{ + p_getMemberType( member_num, floatype ); +} + +void CompType::getMemberType( int member_num, StrType& strtype ) const +{ + p_getMemberType( member_num, strtype ); +} +// end of overloading of getMemberType +*/ + +// Adds a new member to a compound datatype +void CompType::insertMember( const string name, size_t offset, const DataType& new_member ) const +{ + // Convert string to C-string + const char* name_C; + name_C = name.c_str(); // name_C refers to the contents of name as a C-str + + hid_t new_member_id = new_member.getId(); // get new_member id for C API + + // Call C routine H5Tinsert to add the new member + herr_t ret_value = H5Tinsert( id, name_C, offset, new_member_id ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Adds an array member to this compound datatype. +void CompType::insertMember( const string member_name, size_t offset, int ndims, const size_t* dim, const int* perm, const DataType& new_member ) const +{ + throw DataTypeIException( "Error: insertMember is no longer supported."); +} + +// Recursively removes padding from within a compound datatype. +void CompType::pack() const +{ + // Calls C routine H5Tpack to remove padding + herr_t ret_value = H5Tpack( id ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// This destructor just invokes the base-class' destructor +CompType::~CompType() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5DataSet.cpp b/c++/src/H5DataSet.cpp new file mode 100644 index 0000000..1cc66a2 --- /dev/null +++ b/c++/src/H5DataSet.cpp @@ -0,0 +1,207 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5Idtemplates.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5PropList.h" +#include "H5DxferProp.h" +#include "H5DataType.h" +#include "H5DcreatProp.h" +#include "H5DataSpace.h" +#include "H5AbstractDs.h" +#include "H5DataSet.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Default constructor +DataSet::DataSet() : AbstractDs() {} + +// Creates a copy of DataSet using an existing id +DataSet::DataSet( const hid_t dataset_id ) : AbstractDs( dataset_id ) {} + +// Copy constructor makes a copy of the original object by using base +// class' copy constructors +DataSet::DataSet( const DataSet& original ) : AbstractDs( original ) {} + +// Gets a copy of the dataspace of this dataset +DataSpace DataSet::getSpace() const +{ + // Calls C function H5Dget_space to get the id of the dataspace + hid_t dataspace_id = H5Dget_space( id ); + + // If the dataspace id is invalid, throw an exception + if( dataspace_id <= 0 ) + { + throw DataSetIException(); + } + //create dataspace object using the existing id then return the object + DataSpace data_space( dataspace_id ); + return( data_space ); +} + +// This private member function calls the C API to get the identifier +// of the datatype that is used by this dataset. It is used +// by the various AbstractDs functions to get the specific datatype. +hid_t DataSet::p_getType() const +{ + hid_t type_id = H5Dget_type( id ); + if( type_id > 0 ) + return( type_id ); + else + { + throw DataSetIException(); + } +} + +// Gets the dataset creation property list +DSetCreatPropList DataSet::getCreatePlist() const +{ + hid_t create_plist_id = H5Dget_create_plist( id ); + if( create_plist_id <= 0 ) + { + throw DataSetIException(); + } + // create and return the DSetCreatPropList object + DSetCreatPropList create_plist( create_plist_id ); + return( create_plist ); +} + +// Returns the amount of storage required for a dataset. +hsize_t DataSet::getStorageSize() const +{ + hsize_t storage_size = H5Dget_storage_size( id ); + + if( storage_size > 0 ) + return( storage_size ); + else + { + throw DataSetIException(); + } +} + +// Returns the number of bytes required to store VL data. +hsize_t DataSet::getVlenBufSize( DataType& type, DataSpace& space ) const +{ + //herr_t ret_value; + // Obtain identifiers for C API + //hid_t type_id = type.getId(); + //hid_t space_id = space.getId(); + //hsize_t size; + + throw DataSetIException( "getVlenBufSize: Currently not implemented yet."); + //ret_value = H5Dget_vlen_buf_size( id, type_id, space_id, &size ); + //if( ret_value >= 0 ) + // return( size ); + //else + //{ + //throw DataSetIException(); + //} +} + +// Reclaims VL datatype memory buffers. +void DataSet::vlenReclaim( DataType& type, DataSpace& space, DSetMemXferPropList& xfer_plist, void* buf ) const +{ + herr_t ret_value; + // Obtain identifiers for C API + hid_t type_id = type.getId(); + hid_t space_id = space.getId(); + hid_t xfer_plist_id = xfer_plist.getId(); + + ret_value = H5Dvlen_reclaim( type_id, space_id, xfer_plist_id, buf ); + if( ret_value < 0 ) + { + throw DataSetIException(); + } +} + +// Reads raw data from the specified dataset into buf, converting from +// file datatype and dataspace to memory datatype and dataspace. +void DataSet::read( void* buf, const DataType& mem_type, const DataSpace& mem_space, const DataSpace& file_space, const DSetMemXferPropList& xfer_plist ) const +{ + // Obtain identifiers for C API + hid_t mem_type_id = mem_type.getId(); + hid_t mem_space_id = mem_space.getId(); + hid_t file_space_id = file_space.getId(); + hid_t xfer_plist_id = xfer_plist.getId(); + + herr_t ret_value = H5Dread( id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, buf ); + if( ret_value < 0 ) + { + throw DataSetIException(); + } +} + +// Writes raw data from an application buffer buffer to a dataset, +// converting from memory datatype and dataspace to file datatype +// and dataspace. +void DataSet::write( const void* buf, const DataType& mem_type, const DataSpace& mem_space, const DataSpace& file_space, const DSetMemXferPropList& xfer_plist ) const +{ + // Obtain identifiers for C API + hid_t mem_type_id = mem_type.getId(); + hid_t mem_space_id = mem_space.getId(); + hid_t file_space_id = file_space.getId(); + hid_t xfer_plist_id = xfer_plist.getId(); + + herr_t ret_value = H5Dwrite( id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, buf ); + if( ret_value < 0 ) + { + throw DataSetIException(); + } +} + +// Iterates over all selected elements in a dataspace. +int DataSet::iterateElems( void* buf, const DataType& type, const DataSpace& space, H5D_operator_t op, void* op_data ) +{ + // Obtain identifiers for C API + hid_t type_id = type.getId(); + hid_t space_id = space.getId(); + herr_t ret_value = H5Diterate( buf, type_id, space_id, op, op_data ); + if( ret_value >= 0 ) + return( ret_value ); + else // raise exception when H5Diterate returns a negative value + { + throw DataSetIException(); + } +} + +// Extends a dataset with unlimited dimension. +void DataSet::extend( const hsize_t* size ) const +{ + herr_t ret_value = H5Dextend( id, size ); + if( ret_value < 0 ) // raise exception when H5Dextend returns a neg value + { + throw DataSetIException(); + } +} + +// This private function calls the C API H5Dclose to close this dataset. +// Used by IdComponent::reset +void DataSet::p_close() const +{ + herr_t ret_value = H5Dclose( id ); + if( ret_value < 0 ) + { + throw DataSetIException(); + } +} + +// The destructor of this instance calls IdComponent::reset to +// reset its identifier - no longer true +// Older compilers (baldric) don't support template member functions +// and IdComponent::reset is one; so at this time, the resetId is not +// a member function so it can be template to work around that problem. +DataSet::~DataSet() +{ + // The dataset id will be closed properly + resetIdComponent( this ); +} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5DataSpace.cpp b/c++/src/H5DataSpace.cpp new file mode 100644 index 0000000..746dc39 --- /dev/null +++ b/c++/src/H5DataSpace.cpp @@ -0,0 +1,323 @@ +#include + +#include "H5Include.h" +#include "H5Exception.h" +#include "H5RefCounter.h" +#include "H5IdComponent.h" +#include "H5Idtemplates.h" +#include "H5DataSpace.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +const DataSpace DataSpace::ALL( H5S_ALL ); + +// Default constructor +DataSpace::DataSpace() : IdComponent() {} + +// This constructor creates a DataSpace instance, given a dataspace type +DataSpace::DataSpace( H5S_class_t type ) : IdComponent() +{ + id = H5Screate( type ); + if( id <= 0 ) + { + throw DataSpaceIException(); + } +} + +// Creates a new simple data space and opens it for access. +DataSpace::DataSpace( int rank, const hsize_t * dims, const hsize_t * maxdims) : IdComponent() +{ + id = H5Screate_simple( rank, dims, maxdims ); + if( id <= 0 ) + { + throw DataSpaceIException(); + } +} + +/* Constructor that takes an existing dataspace id +Description: + Uses an HDF5 id to create a DataSpace identifier instance. This id can be either an existing dataspace id or a default dataspace id. Design note: in the case of default dataspace, the identifier still has reference counter; the p_close function will take care of not to call H5Sclose on the default id. +*/ +DataSpace::DataSpace( const hid_t space_id ) : IdComponent( space_id ) {} + +// Copy constructor: makes a copy of the original DataSpace instance +DataSpace::DataSpace( const DataSpace& original ) : IdComponent( original ) {} + +// Makes a copy of an existing dataspace +void DataSpace::copy( const DataSpace& like_space ) +{ + // reset the identifier of this instance - send 'this' in so that + // H5Sclose can be called appropriately + resetIdComponent( this ); + + // call C routine to copy the dataspace + id = H5Scopy( like_space.getId() ); + + // points to the same ref counter + ref_count = like_space.ref_count; + + // increment ref counter to indicate additional references to this id + ref_count->increment(); + + if( id <= 0 ) + { + throw DataSpaceIException(); + } +} + +// Determines whether this dataspace is a simple dataspace. +bool DataSpace::isSimple () const +{ + htri_t simple = H5Sis_simple( id ); + if( simple > 0 ) + return true; + else if( simple == 0 ) + return false; + else + { + throw DataSpaceIException(); + } +} + +// Sets the offset of this simple dataspace. +void DataSpace::offsetSimple ( const hssize_t* offset ) const +{ + herr_t ret_value = H5Soffset_simple( id, offset ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Retrieves dataspace dimension size and maximum size +int DataSpace::getSimpleExtentDims ( hsize_t *dims, hsize_t *maxdims ) const +{ + int ndims = H5Sget_simple_extent_dims( id, dims, maxdims ); + if( ndims < 0 ) + { + throw DataSpaceIException(); + } + return( ndims ); +} + +// Determines the dimensionality of a dataspace +int DataSpace::getSimpleExtentNdims () const +{ + int ndims = H5Sget_simple_extent_ndims( id ); + if( ndims < 0 ) + { + throw DataSpaceIException(); + } + return( ndims ); +} + +// Determines the number of elements in a dataspace +// 12/05/00: due to C API change +// return type hssize_t vs. hsize_t +// num_elements = -1 when failure occurs vs. 0 +hssize_t DataSpace::getSimpleExtentNpoints () const +{ + hssize_t num_elements = H5Sget_simple_extent_npoints( id ); + + if( num_elements > -1 ) + return( num_elements ); + else + { + throw DataSpaceIException(); + } +} + +// Determine the current class of a dataspace +H5S_class_t DataSpace::getSimpleExtentType () const +{ + H5S_class_t class_name = H5Sget_simple_extent_type( id ); + if( class_name == H5S_NO_CLASS ) + { + throw DataSpaceIException(); + } + return( class_name ); +} + +// Copies the extent of a dataspace +void DataSpace::extentCopy ( DataSpace& dest_space ) const +{ + hid_t dest_space_id = dest_space.getId(); + herr_t ret_value = H5Sextent_copy( dest_space_id, id ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Sets or resets the size of an existing dataspace +void DataSpace::setExtentSimple( int rank, const hsize_t *current_size, const hsize_t *maximum_size ) const +{ + herr_t ret_value; + ret_value = H5Sset_extent_simple( id, rank, current_size, maximum_size ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Removes the extent from a dataspace +void DataSpace::setExtentNone () const +{ + herr_t ret_value = H5Sset_extent_none( id ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Determines the number of elements in a dataspace selection +hssize_t DataSpace::getSelectNpoints () const +{ + hssize_t num_elements = H5Sget_select_npoints( id ); + if( num_elements < 0 ) + { + throw DataSpaceIException(); + } + return( num_elements ); +} + +// Get number of hyperslab blocks +hssize_t DataSpace::getSelectHyperNblocks () const +{ + hssize_t num_blocks = H5Sget_select_hyper_nblocks( id ); + if( num_blocks < 0 ) + { + throw DataSpaceIException(); + } + return( num_blocks ); +} + +// Gets the list of hyperslab blocks currently selected +void DataSpace::getSelectHyperBlocklist( hsize_t startblock, hsize_t numblocks, hsize_t *buf ) const +{ + herr_t ret_value; + ret_value = H5Sget_select_hyper_blocklist( id, startblock, numblocks, buf ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Gets the number of element points in the current selection +hssize_t DataSpace::getSelectElemNpoints () const +{ + hssize_t num_points = H5Sget_select_elem_npoints( id ); + if( num_points < 0 ) + { + throw DataSpaceIException(); + } + return( num_points ); +} + +// Gets the list of element points currently selected +void DataSpace::getSelectElemPointlist ( hsize_t startpoint, hsize_t numpoints, hsize_t *buf ) const +{ + herr_t ret_value; + ret_value = H5Sget_select_elem_pointlist( id, startpoint, numpoints, buf ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Gets the bounding box containing the current selection +void DataSpace::getSelectBounds ( hsize_t* start, hsize_t* end ) const +{ + herr_t ret_value = H5Sget_select_bounds( id, start, end ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Selects array elements to be included in the selection for a dataspace +void DataSpace::selectElements ( H5S_seloper_t op, const size_t num_elements, const hssize_t *coord[ ] ) const +{ + herr_t ret_value; + ret_value = H5Sselect_elements( id, op, num_elements, coord ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Selects the entire dataspace +void DataSpace::selectAll () const +{ + herr_t ret_value = H5Sselect_all( id ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +//Resets the selection region to include no elements +void DataSpace::selectNone () const +{ + herr_t ret_value = H5Sselect_none( id ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Verifies that the selection is within the extent of the dataspace +bool DataSpace::selectValid () const +{ + htri_t ret_value = H5Sselect_valid( id ); + if( ret_value > 0 ) + return true; + else if( ret_value == 0 ) + return false; + else + { + throw DataSpaceIException(); + } +} + +// Selects a hyperslab region to add to the current selected region +void DataSpace::selectHyperslab( H5S_seloper_t op, const hsize_t *count, const hssize_t *start, const hsize_t *stride, const hsize_t *block ) const +{ + herr_t ret_value; + ret_value = H5Sselect_hyperslab( id, op, start, stride, count, block ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } +} + +// Closes the dataspace if it is not a constant +void DataSpace::p_close() const +{ + hid_t space_id = id; + if( space_id != H5S_ALL ) // not a constant, should call H5Sclose + { + herr_t ret_value = H5Sclose( space_id ); + if( ret_value < 0 ) + { + throw DataSpaceIException(); + } + } +} + +// The destructor of this instance calls IdComponent::reset to +// reset its identifier - no longer true +// Older compilers (baldric) don't support template member functions +// and IdComponent::reset is one; so at this time, the resetId is not +// a member function so it can be template to work around that problem. +DataSpace::~DataSpace() +{ + // The dataspace id will be closed properly + resetIdComponent( this ); +} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5DataType.cpp b/c++/src/H5DataType.cpp new file mode 100644 index 0000000..b376f61 --- /dev/null +++ b/c++/src/H5DataType.cpp @@ -0,0 +1,341 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5Idtemplates.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5DataType.h" +#include "H5AtomType.h" +#include "H5PredType.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Constructor creates a copy of an existing DataType using its id. +// 'predefined' is default to false; when a default datatype is +// created, this argument is set to true so H5Tclose will not be +// called on it later. +DataType::DataType( const hid_t existing_id, bool predefined ) : H5Object( existing_id ), is_predtype( predefined ) { +} + +// Creates a datatype given its class and size +DataType::DataType( const H5T_class_t type_class, size_t size ) : H5Object(), is_predtype( false ) +{ + // Call C routine to create the new datatype + id = H5Tcreate( type_class, size ); + if( id <= 0 ) + { + throw DataTypeIException(); + } +} + +// Default constructor +DataType::DataType() : H5Object(), is_predtype( false ) +{ +} + +// Copy constructor: makes a copy of this DataType object. +DataType::DataType( const DataType& original ) : H5Object( original ) +{ + is_predtype = original.is_predtype; // copy data member from original +} + +// Copies an existing datatype to this datatype object +void DataType::copy( const DataType& like_type ) +{ + // reset the identifier of this instance, H5Tclose will be called + // if needed + resetIdComponent( this ); + + // call C routine to copy the datatype + id = H5Tcopy( like_type.getId() ); + ref_count = like_type.ref_count; + + // increment ref counter to indicate additional references to this id + ref_count->increment(); + + if( id <= 0 ) + { + throw DataTypeIException(); + } +} + +// Determines whether two datatypes are the same. ??? +bool DataType::operator==(const DataType& compared_type ) const +{ + // Call C routine H5Tequal to determines whether two datatype + // identifiers refer to the same datatype + htri_t ret_value = H5Tequal( id, compared_type.getId() ); + if( ret_value > 0 ) + return true; + else if( ret_value == 0 ) + return false; + else + { + throw DataTypeIException(); + } +} + +// Operates a user's function on each attribute of an object - commented +// out because it should use the one from H5Object; need to check +// the parameter list??? +//int DataType::iterate( unsigned * idx, H5A_operator_t op, void *op_data ) +//{ + // Call C routine H5Aiterate to iterate the object's attributes + //int ret_value = H5Aiterate( id, idx, op, op_data ); + //if( ret_value >= 0 ) + //return( ret_value ); + //else + //{ + //throw DataTypeIException(); + //} +//} + +// Creates a new variable-length datatype - Note: make it inheritance??? +//DataType DataType::vlenCreate( const DataType& base_type ) +//{ + // Call C routine to create a new VL datatype + //hid_t type_id = H5Tvlen_create( id ); + //if( type_id > 0 ) + //id_obj->setId( type_id ); + //else + //{ + //throw DataTypeIException(); + //} +//} + +// Commits a transient datatype to a file, creating a new named datatype +void DataType::commit( H5Object& loc, const string& name ) const +{ + commit( loc, name.c_str() ); +} +void DataType::commit( H5Object& loc, const char* name ) const +{ + hid_t loc_id = loc.getId(); // get location id for C API + + // Call C routine to commit the transient datatype + herr_t ret_value = H5Tcommit( loc_id, name, id ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Determines whether a datatype is a named type or a transient type. +bool DataType::committed() const +{ + // Call C function to determine if a datatype is a named one + htri_t committed = H5Tcommitted( id ); + if( committed > 0 ) + return true; + else if( committed == 0 ) + return false; + else + { + throw DataTypeIException(); + } +} + +// Finds a conversion function. +H5T_conv_t DataType::find( const DataType& dest, H5T_cdata_t **pcdata ) const +{ + // Call C routine to find the conversion function + H5T_conv_t func = H5Tfind( id, dest.getId(), pcdata ); + if( func == NULL ) + { + throw DataTypeIException(); + } + return( func ); +} + +// Converts data from between specified datatypes. +void DataType::convert( const DataType& dest, size_t nelmts, void *buf, void *background, PropList& plist ) const +{ + // Get identifiers for C API + hid_t dest_id = dest.getId(); + hid_t plist_id = plist.getId(); + + // Call C routine H5Tconvert to convert the data + herr_t ret_value; + ret_value = H5Tconvert( id, dest_id, nelmts, buf, background, plist_id ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Sets the overflow handler to a specified function. +void DataType::setOverflow( H5T_overflow_t func ) const +{ + // Call C routine H5Tset_overflow to set the overflow handler + herr_t ret_value = H5Tset_overflow( func ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Returns a pointer to the current global overflow function. +H5T_overflow_t DataType::getOverflow(void) const +{ + return( H5Tget_overflow()); // C routine + // NULL can be returned as well +} + +// Locks a datatype. +void DataType::lock() const +{ + // Call C routine to lock the datatype + herr_t ret_value = H5Tlock( id ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Returns the datatype class identifier. +H5T_class_t DataType::getClass() const +{ + H5T_class_t type_class = H5Tget_class( id ); + + // Return datatype class identifier if successful + if( type_class == H5T_NO_CLASS ) + { + throw DataTypeIException(); + } + return( type_class ); +} + +// Returns the size of a datatype. +size_t DataType::getSize() const +{ + // Call C routine to get the datatype size + size_t type_size = H5Tget_size( id ); + if( type_size <= 0 ) // Is 0 valid value ??? + { + throw DataTypeIException(); + } + return( type_size ); +} + +// Returns the base datatype from which a datatype is derived. +// - just for DataType? +DataType DataType::getSuper() const +{ + // Call C routine to get the base datatype from which the specified + // datatype is derived. + hid_t base_type_id = H5Tget_super( id ); + + // If H5Tget_super returns a valid datatype id, create and return + // the base type, otherwise, raise exception + if( base_type_id > 0 ) + { + DataType base_type( base_type_id ); + return( base_type ); + } + else {} + { + throw DataTypeIException(); + } +} + +// Registers the specified conversion function. +void DataType::registerFunc( H5T_pers_t pers, const string& name, const DataType& dest, H5T_conv_t func ) const +{ + registerFunc( pers, name.c_str(), dest, func ); +} +void DataType::registerFunc( H5T_pers_t pers, const char* name, const DataType& dest, H5T_conv_t func ) const +{ + hid_t dest_id = dest.getId(); // get id of the destination datatype + + // Call C routine H5Tregister to register the conversion function + herr_t ret_value = H5Tregister( pers, name, id, dest_id, func ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Removes a conversion function from all conversion paths. +void DataType::unregister( H5T_pers_t pers, const string& name, const DataType& dest, H5T_conv_t func ) const +{ + unregister( pers, name.c_str(), dest, func ); +} +void DataType::unregister( H5T_pers_t pers, const char* name, const DataType& dest, H5T_conv_t func ) const +{ + hid_t dest_id = dest.getId(); // get id of the dest datatype for C API + + // Call C routine H5Tunregister to remove the conversion function + herr_t ret_value = H5Tunregister( pers, name, id, dest_id, func ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Tags an opaque datatype. +void DataType::setTag( const string& tag ) const +{ + setTag( tag.c_str()); +} +void DataType::setTag( const char* tag ) const +{ + // Call C routine H5Tset_tag to tag an opaque datatype. + herr_t ret_value = H5Tset_tag( id, tag ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Gets the tag associated with an opaque datatype. +string DataType::getTag() const +{ + char* tag_Cstr = H5Tget_tag( id ); + + // if the tag C-string returned is not NULL, convert it to C++ string + // and return it, otherwise, raise an exception + if( tag_Cstr != NULL ) + { + string tag = string( tag_Cstr ); + return( tag ); + } + else + { + throw DataTypeIException(); + } +} + +// This private function calls the C API H5Tclose to close this datatype. +// Used by H5Object::p_reset. +void DataType::p_close() const +{ + // If this datatype is not a predefined type, call H5Tclose on it. + if( is_predtype == false ) + { + herr_t ret_value = H5Tclose( id ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } + } +} + +// The destructor of this instance calls IdComponent::reset to +// reset its identifier - no longer true +// Older compilers (baldric) don't support template member functions +// and IdComponent::reset is one; so at this time, the resetId is not +// a member function so it can be template to work around that problem. +DataType::~DataType() +{ + // The datatype id will be closed properly + resetIdComponent( this ); +} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5DcreatProp.cpp b/c++/src/H5DcreatProp.cpp new file mode 100644 index 0000000..adaa046 --- /dev/null +++ b/c++/src/H5DcreatProp.cpp @@ -0,0 +1,173 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5DataType.h" +#include "H5DcreatProp.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +const DSetCreatPropList DSetCreatPropList::DEFAULT( H5P_DEFAULT ); + +// Copy constructor: makes a copy of the original DSetCreatPropList object; +DSetCreatPropList::DSetCreatPropList( const DSetCreatPropList& orig ) : PropList( orig ) {} + +// Copies a dataset creation property list using assignment statement +DSetCreatPropList& DSetCreatPropList::operator=( const DSetCreatPropList& rhs ) +{ + copy (rhs); + return( *this ); +} + +// Sets the size of the chunks used to store a chunked layout dataset. +void DSetCreatPropList::setChunk( int ndims, const hsize_t* dim ) const +{ + herr_t ret_value = H5Pset_chunk( id, ndims, dim ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Gets the layout of the raw data storage of the data that uses this +// property list +H5D_layout_t DSetCreatPropList::getLayout() const +{ + H5D_layout_t layout = H5Pget_layout( id ); + if( layout == H5D_LAYOUT_ERROR ) + { + throw PropListIException(); + } + return( layout ); +} + +// Retrieves the size of the chunks used to store a chunked layout dataset. +int DSetCreatPropList::getChunk( int max_ndims, hsize_t* dim ) const +{ + int chunk_size = H5Pget_chunk( id, max_ndims, dim ); + if( chunk_size < 0 ) + { + throw PropListIException(); + } + return( chunk_size ); +} + +// Sets the type of storage used store the raw data for a dataset. +void DSetCreatPropList::setLayout(hid_t plist, H5D_layout_t layout ) const +{ + herr_t ret_value = H5Pset_layout( id, layout ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Sets compression method and compression level +void DSetCreatPropList::setDeflate( int level ) const +{ + herr_t ret_value = H5Pset_deflate( id, level ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Sets a dataset fill value +void DSetCreatPropList::setFillValue( DataType& fvalue_type, const void* value ) const +{ + herr_t ret_value = H5Pset_fill_value( id, fvalue_type.getId(), value ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Retrieves a dataset fill value +void DSetCreatPropList::getFillValue( DataType& fvalue_type, void* value ) const +{ + herr_t ret_value = H5Pget_fill_value( id, fvalue_type.getId(), value ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Adds a filter to the filter pipeline +void DSetCreatPropList::setFilter( H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[] ) const +{ + herr_t ret_value = H5Pset_filter( id, filter, flags, cd_nelmts, cd_values ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Returns the number of filters in the pipeline +int DSetCreatPropList::getNfilters() const +{ + int num_filters = H5Pget_nfilters( id ); + if( num_filters < 0 ) + { + throw PropListIException(); + } + else + return( num_filters ); +} + +// Returns information about a filter in a pipeline +H5Z_filter_t DSetCreatPropList::getFilter( int filter_number, unsigned int& flags, size_t& cd_nelmts, unsigned int* cd_values, size_t namelen, char name[] ) const +{ + H5Z_filter_t filter; + filter = H5Pget_filter( id, filter_number, &flags, &cd_nelmts, cd_values, namelen, name ); + if( filter == H5Z_FILTER_ERROR ) + { + throw PropListIException(); + } + else + return( filter ); +} + +// Adds an external file to the list of external files +void DSetCreatPropList::setExternal( const char* name, off_t offset, hsize_t size ) const +{ + herr_t ret_value = H5Pset_external( id, name, offset, size ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Returns the number of external files for a dataset +int DSetCreatPropList::getExternalCount() const +{ + int num_ext_files = H5Pget_external_count( id ); + if( num_ext_files < 0 ) + { + throw PropListIException(); + } + else + return( num_ext_files ); +} + +// Returns information about an external file +void DSetCreatPropList::getExternal( int idx, size_t name_size, char* name, off_t& offset, hsize_t& size ) const +{ + herr_t ret_value = H5Pget_external( id, idx, name_size, name, &offset, &size ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Default destructor +DSetCreatPropList::~DSetCreatPropList () {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5DxferProp.cpp b/c++/src/H5DxferProp.cpp new file mode 100644 index 0000000..ff96b66 --- /dev/null +++ b/c++/src/H5DxferProp.cpp @@ -0,0 +1,183 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5DxferProp.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +const DSetMemXferPropList DSetMemXferPropList::DEFAULT( H5P_DEFAULT ); + +// Creates a dataset memory and transfer property list +DSetMemXferPropList::DSetMemXferPropList() : PropList( H5P_DATASET_XFER ) {} + +// Copy constructor: makes a copy of the original DSetMemXferPropList object; +DSetMemXferPropList::DSetMemXferPropList( const DSetMemXferPropList& orig ) : PropList( orig ) {} + +// Copies a dataset transfer property list using assignment statement +// Notes: can this be inherited from PropList??? and copy or operator=??? +DSetMemXferPropList& DSetMemXferPropList::operator=( const DSetMemXferPropList& rhs ) +{ + copy (rhs); + return( *this ); +} + +// Sets type conversion and background buffers +void DSetMemXferPropList::setBuffer( size_t size, void* tconv, void* bkg ) const +{ + herr_t ret_value = H5Pset_buffer( id, size, tconv, bkg ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Reads buffer settings +size_t DSetMemXferPropList::getBuffer( void** tconv, void** bkg ) const +{ + size_t buffer_size = H5Pget_buffer( id, tconv, bkg ); + if( buffer_size == 0 ) + { + throw PropListIException(); + } + return( buffer_size ); +} + +// Sets the dataset transfer property list status to TRUE or FALSE +void DSetMemXferPropList::setPreserve( bool status ) const +{ + herr_t ret_value = H5Pset_preserve( id, (hbool_t) status ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Checks status of the dataset transfer property list +bool DSetMemXferPropList::getPreserve() const +{ + int ret_value = H5Pget_preserve( id ); + if( ret_value > 0 ) + return true; + else if( ret_value == 0 ) + return false; + else + { + throw PropListIException(); + } +} + +// Indicates whether to cache hyperslab blocks during I/O +void DSetMemXferPropList::setHyperCache( bool cache, unsigned limit ) const +{ + herr_t ret_value = H5Pset_hyper_cache( id, cache, limit ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Returns information regarding the caching of hyperslab blocks during I/O +void DSetMemXferPropList::getHyperCache( bool& cache, unsigned& limit ) const +{ + unsigned temp_cache; // C routine takes hid_t, unsigned*, unsigned* + herr_t ret_value = H5Pget_hyper_cache( id, &temp_cache, &limit ); + if( ret_value < 0 ) + { + throw PropListIException(); + } + if( temp_cache > 0 ) + cache = true; + else + cache = false; +} + +// Sets B-tree split ratios for a dataset transfer property list +void DSetMemXferPropList::setBtreeRatios( double left, double middle, double right ) const +{ + herr_t ret_value = H5Pset_btree_ratios( id, left, middle, right ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Gets B-tree split ratios for a dataset transfer property list +void DSetMemXferPropList::getBtreeRatios( double& left, double& middle, double& right ) const +{ + herr_t ret_value = H5Pget_btree_ratios( id, &left, &middle, &right ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Sets the memory manager for variable-length datatype allocation +void DSetMemXferPropList::setVlenMemManager( H5MM_allocate_t alloc_func, void* alloc_info, H5MM_free_t free_func, void* free_info ) const +{ + herr_t ret_value = H5Pset_vlen_mem_manager( id, alloc_func, alloc_info, + free_func, free_info ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// alloc_func and free_func are set to NULL, indicating that system malloc and +// free are to be used +void DSetMemXferPropList::setVlenMemManager() const +{ + setVlenMemManager( NULL, NULL, NULL, NULL ); + //herr_t ret_value = H5Pset_vlen_mem_manager( id, NULL, NULL, NULL, NULL ); + //if( ret_value < 0 ) + //{ + //throw PropListIException(); + //} +} + +// Gets the memory manager for variable-length datatype allocation +void DSetMemXferPropList::getVlenMemManager( H5MM_allocate_t& alloc_func, void** alloc_info, H5MM_free_t& free_func, void** free_info ) const +{ + herr_t ret_value = H5Pget_vlen_mem_manager( id, &alloc_func, alloc_info, &free_func, free_info ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +/* these two functions are in parallel mode only - not supported at this time. +// Sets the transfer mode +void DSetMemXferPropList::setXfer( H5D_transfer_t data_xfer_mode = H5D_XFER_INDEPENDENT ) const +{ + herr_t ret_value = H5Pset_xfer( ... ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +// Gets the transfer mode +H5D_transfer_t DSetMemXferPropList::getXfer() const +{ + H5D_transfer_t xfer = H5Pget_xfer( id ); +// remove when done - find out what the value is for ?? + if( xfer == ?? ) + { + throw PropListIException(); + } + return( xfer ); +} + +*/ + +// Default destructor +DSetMemXferPropList::~DSetMemXferPropList() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5EnumType.cpp b/c++/src/H5EnumType.cpp new file mode 100644 index 0000000..303bac5 --- /dev/null +++ b/c++/src/H5EnumType.cpp @@ -0,0 +1,128 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5AbstractDs.h" +#include "H5DxferProp.h" +#include "H5DataSpace.h" +#include "H5DataType.h" +#include "H5DataSet.h" +#include "H5AtomType.h" +#include "H5IntType.h" +#include "H5EnumType.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Creates an empty enumeration datatype based on a native signed +// integer type. +EnumType::EnumType( size_t size ) : DataType( H5T_ENUM, size ) {} + +// Default constructor +EnumType::EnumType() : DataType() {} + +// Creates a enumeration datatype using an existing id +EnumType::EnumType( const hid_t existing_id ) : DataType( existing_id ) {} + +// Copy constructor: makes a copy of the original EnumType object. +EnumType::EnumType( const EnumType& original ) : DataType( original ) {} + +// Gets the enum datatype of the specified dataset +EnumType::EnumType( const DataSet& dataset ) : DataType() +{ + // Calls C function H5Dget_type to get the id of the datatype + id = H5Dget_type( dataset.getId() ); + + // If the datatype id is not valid, throw an exception + if( id <= 0 ) + { + throw DataSetIException("Getting datatype fails..."); + } +} + +// Creates a new enum datatype based on an integer datatype +EnumType::EnumType( const IntType& data_type ) : DataType() +{ + // Calls C function H5Tenum_create to get the id of the datatype + id = H5Tenum_create( data_type.getId() ); + + // If the datatype id is not valid, throw an exception + if( id <= 0 ) + { + throw DataSetIException("Creating enumeration datatype fails..."); + } +} + +// Inserts a new member to this enumeration datatype. +void EnumType::insert( const string& name, void *value ) const +{ + insert( name.c_str(), value ); +} +void EnumType::insert( const char* name, void *value ) const +{ + // Calls C routine H5Tenum_insert to insert the new enum datatype member. + herr_t ret_value = H5Tenum_insert( id, name, value ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Returns the symbol name corresponding to a specified member of an enumeration datatype. +string EnumType::nameOf( void *value, size_t size ) const +{ + char* name_C = new char[size+1]; // temporary C-string for C API + + // Calls C routine H5Tenum_nameof to get the name of the specified enum type + herr_t ret_value = H5Tenum_nameof( id, value, name_C, size ); + + // If H5Tenum_nameof returns a negative value, raise an exception, + if( ret_value < 0 ) + { + throw DataTypeIException(); + } + // otherwise, create the string to hold the datatype name and return it + string name = string( name_C ); + delete name_C; + return( name ); +} + +// Retrieves the value corresponding to a member of an enumeration +// datatype, given the member's name. +void EnumType::valueOf( const string& name, void *value ) const +{ + valueOf( name.c_str(), value ); +} +void EnumType::valueOf( const char* name, void *value ) const +{ + // Calls C routine H5Tenum_valueof to get the enum datatype value + herr_t ret_value = H5Tenum_valueof( id, name, value ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Retrieves the value of a member in this enumeration datatype, given the +// member's index. +void EnumType::getMemberValue( int memb_no, void *value ) const +{ + // Call C routine H5Tget_member_value to get the datatype member's value + hid_t ret_value = H5Tget_member_value( id, memb_no, value ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Default destructor +EnumType::~EnumType() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5Exception.cpp b/c++/src/H5Exception.cpp new file mode 100644 index 0000000..ea4cb63 --- /dev/null +++ b/c++/src/H5Exception.cpp @@ -0,0 +1,195 @@ +#ifdef OLD_HEADER_FILENAME +#include +#else +#include +#endif + +#include "H5Include.h" +#include + +// Added this line for CC to work at this time. Will remove it when +// the problem is fixed. BMR - 10/30/00 + +#include "H5Exception.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +Exception::Exception() : detailMessage("") {} + +// digital alpha (gondolin) produces compilation error at static_cast +// so I replaced this constructor by the one below it +//Exception::Exception( const char* message) : detailMessage(static_cast(message)) {} + +Exception::Exception( const char* message) +{ + detailMessage = string( message ); +} + +Exception::Exception( const string& message ) : detailMessage( message ) {} + +// copy constructor +Exception::Exception( const Exception& orig ) +{ + detailMessage = orig.detailMessage; +} + +// Returns the character string that describes an error specified by +// a major error number. +string Exception::getMajorString( H5E_major_t major_num ) const +{ + // calls the C API routine to get the major string - Note: in the + // failure case, the string "Invalid major error number" will be returned. + string major_str( H5Eget_major( major_num )); + return( major_str ); +} + +// Returns the character string that describes an error specified by +// a minor error number. +string Exception::getMinorString( H5E_minor_t minor_num ) const +{ + // calls the C API routine to get the minor string - Note: in the + // failure case, the string "Invalid minor error number" will be returned. + string minor_str( H5Eget_minor( minor_num )); + return( minor_str ); +} + +// Turns on the automatic error printing. +void Exception::setAutoPrint( H5E_auto_t func, void* client_data ) const +{ + // calls the C API routine H5Eset_auto to set the auto printing to + // the specified function. + herr_t ret_value = H5Eset_auto( func, client_data ); + if( ret_value < 0 ) + throw Exception( "setAutoPrint: H5Eset_auto fails" ); +} + +// Turns off the automatic error printing. +void Exception::dontPrint() +{ + // calls the C API routine H5Eset_auto with NULL parameters to turn + // off the automatic error printing. + herr_t ret_value = H5Eset_auto( NULL, NULL ); + if( ret_value < 0 ) + throw Exception( "dontPrint: H5Eset_auto fails" ); +} + +// Retrieves the current settings for the automatic error stack traversal +// function and its data. +void Exception::getAutoPrint( H5E_auto_t& func, void** client_data ) const +{ + // calls the C API routine H5Eget_auto to get the current setting of + // the automatic error printing + herr_t ret_value = H5Eget_auto( &func, client_data ); + if( ret_value < 0 ) + throw Exception( "getAutoPrint: H5Eget_auto fails" ); +} + +// Clears the error stack for the current thread. +void Exception::clearErrorStack() const +{ + // calls the C API routine H5Eclear to clear the error stack + herr_t ret_value = H5Eclear(); + if( ret_value < 0 ) + throw Exception( "clearErrorStack: H5Eclear fails" ); +} + +// Walks the error stack for the current thread, calling the specified function. +void Exception::walkErrorStack( H5E_direction_t direction, H5E_walk_t func, void* client_data ) const +{ + // calls the C API routine H5Ewalk to walk the error stack + herr_t ret_value = H5Ewalk( direction, func, client_data ); + if( ret_value < 0 ) + throw Exception( "walkErrorStack: H5Ewalk fails" ); +} + +// Default error stack traversal callback function that prints error +// messages to the specified output stream. +void Exception::walkDefErrorStack( int n, H5E_error_t& err_desc, void* client_data ) const +{ + // calls the C API routine H5Ewalk_cb to walk the error stack + herr_t ret_value = H5Ewalk_cb( n, &err_desc, client_data ); + if( ret_value < 0 ) + throw Exception( "walkDefErrorStack: H5Ewalk_cb fails" ); +} + +// Returns the detailed message set at the time the exception is thrown +string Exception::getDetailMesg() const +{ + return( detailMessage ); +} + +// Prints the error stack in a default manner. +void Exception::printError( FILE* stream ) const +{ + herr_t ret_value = H5Eprint( NULL ); // print to stderr + if( ret_value < 0 ) + throw Exception( "printError: H5Eprint fails" ); +} + +FileIException::FileIException():Exception(){} +FileIException::FileIException( string message ): +Exception( message ){} + +GroupIException::GroupIException():Exception(){} +GroupIException::GroupIException( string message ): +Exception( message ){} + +ObjectHeaderException::ObjectHeaderException():Exception(){} +ObjectHeaderException::ObjectHeaderException( string message ): Exception( message ) {} + +DataSpaceIException::DataSpaceIException():Exception(){} +DataSpaceIException::DataSpaceIException( string message ): Exception( message ) {} + +DataTypeIException::DataTypeIException():Exception(){} +DataTypeIException::DataTypeIException( string message ): Exception( message ) {} + +PropListIException::PropListIException():Exception(){} +PropListIException::PropListIException( string message ): Exception( message ) {} + +DataSetIException::DataSetIException():Exception(){} +DataSetIException::DataSetIException( string message ): Exception( message ) {} + +AttributeIException::AttributeIException():Exception(){} +AttributeIException::AttributeIException( string message ): Exception( message ) {} + +FunctionArgumentException::FunctionArgumentException():Exception(){} +FunctionArgumentException::FunctionArgumentException( string message ): Exception( message ) {} + +ReferenceException::ReferenceException():Exception(){} +ReferenceException::ReferenceException( string message ): +Exception( message ) {} + +DataStorageException::DataStorageException():Exception(){} +DataStorageException::DataStorageException( string message ): +Exception( message ) {} + +LibraryIException::LibraryIException():Exception(){} +LibraryIException::LibraryIException( string message ): +Exception( message ) {} + +IdComponentException::IdComponentException(): Exception() {} +IdComponentException::IdComponentException( string message ): Exception( message ) {} + +// The following are from Java API but not done here: +// AtomException, BtreeException, DataFiltersException, +// ExternalFileListException, FunctionEntryExitException, +// HeapException, InternalErrorException, LowLevelIOException, +// MetaDataCacheException, ResourceUnavailableException, +// SymbolTableException + +File_GroupException::File_GroupException() +{ + // for now, do nothing +} + +File_GroupException::File_GroupException( string message ) +{ + // for now, do nothing +} + + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5FaccProp.cpp b/c++/src/H5FaccProp.cpp new file mode 100644 index 0000000..a59173d --- /dev/null +++ b/c++/src/H5FaccProp.cpp @@ -0,0 +1,244 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5FaccProp.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +const FileAccPropList FileAccPropList::DEFAULT( H5P_DEFAULT ); + +// Creates a file access property list +FileAccPropList::FileAccPropList() : PropList( H5P_FILE_ACCESS ) {} + +// Copy constructor: makes a copy of the original FileAccPropList object; +FileAccPropList::FileAccPropList( const FileAccPropList& orig ) : PropList( orig ) {} + +// Copies a file access property list using assignment statement +// Notes: can this be inherited from PropList??? and copy or operator=??? +FileAccPropList& FileAccPropList::operator=( const FileAccPropList& rhs ) +{ + copy (rhs); + return( *this ); +} + +/* commented out for 1.3.x, only in 1.2.x +void FileAccPropList::setStdio() const +{ + herr_t ret_value = H5Pset_stdio( id ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +bool FileAccPropList::getStdio() const +{ + herr_t ret_value = H5Pget_stdio( id ); + if( ret_value < 0 ) + return( false ); + else + return( true ); +} + +H5F_driver_t FileAccPropList::getDriver() const +{ + H5F_driver_t driver = H5Pget_driver( id ); + if( driver == H5F_LOW_ERROR ) + { + throw PropListIException(); + } + return( driver ); +} + +void FileAccPropList::setSec2() const +{ + herr_t ret_value = H5Pset_sec2( id ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +bool FileAccPropList::getSec2() const +{ + herr_t ret_value = H5Pget_sec2( id ); + if( ret_value < 0 ) + return( false ); + else + return( true ); +} + +void FileAccPropList::setCore( size_t increment ) const +{ + herr_t ret_value = H5Pset_core( id, increment ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +bool FileAccPropList::getCore( size_t& increment) const +{ + herr_t ret_value = H5Pget_core( id, &increment ); + if( ret_value < 0 ) + return( false ); + else + return( true ); +} + +void FileAccPropList::setFamily( hsize_t memb_size, const FileAccPropList& memb_plist ) const +{ + herr_t ret_value = H5Pset_family( id, memb_size, memb_plist.getId() ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +//Note: working on this return value here. added copy constructor +//that uses PropList copy const. but din't work +// Determines whether the file access property list is set to the family +// driver then retrieves the family member's property list and returns +// true or false +bool FileAccPropList::getFamily( hsize_t& memb_size, FileAccPropList& memb_plist ) const +{ + hid_t memb_plist_id; + herr_t ret_value = H5Pget_family( id, &memb_size, &memb_plist_id ); + if( ret_value < 0 ) + { + memb_plist.setId( 0 ); + return( false ); + } + else + { + memb_plist.setId( memb_plist_id ); + return( true ); + } +} + +void FileAccPropList::setSplit( FileAccPropList& meta_plist, FileAccPropList& raw_plist, const char* meta_ext, const char* raw_ext ) const +{ + hid_t meta_pid = meta_plist.getId(); + hid_t raw_pid = raw_plist.getId(); + herr_t ret_value = H5Pset_split( id, meta_ext, meta_pid, raw_ext, raw_pid ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileAccPropList::setSplit( FileAccPropList& meta_plist, FileAccPropList& raw_plist, const string& meta_ext, const string& raw_ext ) const +{ + setSplit( meta_plist, raw_plist, meta_ext.c_str(), raw_ext.c_str() ); +} + +void FileAccPropList::getSplit( size_t meta_ext_size, string& meta_ext, FileAccPropList& meta_plist, size_t raw_ext_size, string& raw_ext, FileAccPropList& raw_plist ) const +{ + hid_t meta_plist_id, raw_plist_id; // meta-data and raw-data plist ids + char* meta_ext_C = new char[meta_ext_size]; // meta-data extension in C + char* raw_ext_C = new char[raw_ext_size]; // raw-data extension in C + herr_t ret_value = H5Pget_split( id, meta_ext_size, meta_ext_C, + &meta_plist_id, raw_ext_size, raw_ext_C, &raw_plist_id ); + if( ret_value < 0 ) + { + throw PropListIException(); + } + meta_plist.setId( meta_plist_id ); + raw_plist.setId( raw_plist_id ); + raw_ext = string( raw_ext_C ); + meta_ext = string( raw_ext_C ); + delete [] raw_ext_C; + delete [] meta_ext_C; +} +*/ + +void FileAccPropList::setAlignment( hsize_t threshold, hsize_t alignment ) const +{ + herr_t ret_value = H5Pset_alignment( id, threshold, alignment ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileAccPropList::getAlignment( hsize_t& threshold, hsize_t& alignment ) const +{ + herr_t ret_value = H5Pget_alignment( id, &threshold, &alignment ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +/* MPI_Comm and MPI_Info not declared in serial mode so leave these +routines out until C++ API needs to deal with parallel +void FileAccPropList::setMpi( MPI_Comm comm, MPI_Info info ) const +{ + herr_t ret_value = H5Pset_mpi( id, comm, info ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileAccPropList::getMpi( MPI_Comm& comm, MPI_Info& info ) const +{ + herr_t ret_value = H5Pget_mpi( id, &comm, &info ); + if( ret_value < 0 ) + return( false ); + else + return( true ); +} +*/ + +void FileAccPropList::setCache( int mdc_nelmts, int rdcc_nelmts, size_t rdcc_nbytes, double rdcc_w0 ) const +{ + herr_t ret_value = H5Pset_cache( id, mdc_nelmts, rdcc_nelmts, rdcc_nbytes, rdcc_w0 ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileAccPropList::getCache( int& mdc_nelmts, int& rdcc_nelmts, size_t& rdcc_nbytes, double& rdcc_w0 ) const +{ + herr_t ret_value = H5Pget_cache( id, &mdc_nelmts, &rdcc_nelmts, &rdcc_nbytes, &rdcc_w0 ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileAccPropList::setGcReferences( unsigned gc_ref ) const +{ + herr_t ret_value = H5Pset_gc_references( id, gc_ref ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +unsigned FileAccPropList::getGcReferences() const +{ + unsigned gc_ref; + + // the name of this routine will be changed to H5Pget_gc_references??? + herr_t ret_value = H5Pget_gc_references( id, &gc_ref ); + if( ret_value < 0 ) + { + throw PropListIException(); + } + return( gc_ref ); +} + +FileAccPropList::~FileAccPropList() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5FcreatProp.cpp b/c++/src/H5FcreatProp.cpp new file mode 100644 index 0000000..41ec360 --- /dev/null +++ b/c++/src/H5FcreatProp.cpp @@ -0,0 +1,120 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5FcreatProp.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +const FileCreatPropList FileCreatPropList::DEFAULT( H5P_DEFAULT ); + +// Creates a file create property list +FileCreatPropList::FileCreatPropList() : PropList( H5P_FILE_CREATE ) {} + +// Copy constructor: makes a copy of the original FileCreatPropList object; +FileCreatPropList::FileCreatPropList( const FileCreatPropList& orig ) : PropList( orig ) {} + +// Copies a file create property list using assignment statement +// Notes: can this be inherited from PropList??? and copy or operator=??? +FileCreatPropList& FileCreatPropList::operator=( const FileCreatPropList& rhs ) +{ + copy (rhs); + return( *this ); +} + +void FileCreatPropList::getVersion( + int& boot, int& freelist, int& stab, int& shhdr ) const +{ + herr_t ret_value = H5Pget_version( id, &boot, &freelist, &stab, &shhdr ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileCreatPropList::setUserblock( hsize_t size ) const +{ + herr_t ret_value = H5Pset_userblock( id, size); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +hsize_t FileCreatPropList::getUserblock() const +{ + hsize_t userblock_size; + herr_t ret_value = H5Pget_userblock( id, &userblock_size ); + if( ret_value < 0 ) + { + throw PropListIException(); + } + return( userblock_size ); +} + +void FileCreatPropList::setSizes( size_t sizeof_addr, size_t sizeof_size ) const +{ + herr_t ret_value = H5Pset_sizes( id, sizeof_addr, sizeof_size ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileCreatPropList::getSizes( size_t& sizeof_addr, size_t& sizeof_size ) const +{ + herr_t ret_value = H5Pget_sizes( id, &sizeof_addr, &sizeof_size ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileCreatPropList::setSymk( int ik, int lk ) const +{ + herr_t ret_value = H5Pset_sym_k( id, ik, lk ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileCreatPropList::getSymk( int& ik, int& lk ) const +{ + herr_t ret_value = H5Pget_sym_k( id, &ik, &lk ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} + +void FileCreatPropList::setIstorek( int ik ) const +{ + herr_t ret_value = H5Pset_istore_k( id, ik ); + if( ret_value < 0 ) + { + throw PropListIException(); + } +} +int FileCreatPropList::getIstorek() const +{ + int ik; + herr_t ret_value = H5Pget_istore_k( id, &ik ); + if( ret_value < 0 ) + { + throw PropListIException(); + } + return( ik ); +} + +// Default destructor +FileCreatPropList::~FileCreatPropList() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5File.cpp b/c++/src/H5File.cpp new file mode 100644 index 0000000..1ccea96 --- /dev/null +++ b/c++/src/H5File.cpp @@ -0,0 +1,474 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5Idtemplates.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5FaccProp.h" +#include "H5FcreatProp.h" +#include "H5DxferProp.h" +#include "H5DcreatProp.h" +#include "H5Group.h" +#include "H5AbstractDs.h" +#include "H5DataSpace.h" +#include "H5DataSet.h" +#include "H5File.h" +#include "H5Alltypes.h" +#include "H5CommonFG.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Creates or opens an HDF5 file depending on the parameter flags. +H5File::H5File( const string& name, unsigned int flags, const FileCreatPropList& create_plist, const FileAccPropList& access_plist ) : IdComponent() +{ + getFile( name.c_str(), flags, create_plist, access_plist ); +} + +H5File::H5File( const char* name, unsigned int flags, const FileCreatPropList& create_plist, const FileAccPropList& access_plist ) : IdComponent() +{ + getFile( name, flags, create_plist, access_plist ); +} + +// This function is private and contains common code between the +// constructors taking a string or a char* +void H5File::getFile( const char* name, unsigned int flags, const FileCreatPropList& create_plist, const FileAccPropList& access_plist ) +{ + // These bits only set for creation, so if any of them are set, + // create the file. + if( flags & (H5F_ACC_EXCL|H5F_ACC_TRUNC|H5F_ACC_DEBUG )) + { + hid_t create_plist_id = create_plist.getId(); + hid_t access_plist_id = access_plist.getId(); + id = H5Fcreate( name, flags, create_plist_id, access_plist_id ); + } + // Open the file if none of the bits above are set. + else + { + // use create_plist for access plist because of the default argument + hid_t access_plist_id = create_plist.getId(); + id = H5Fopen( name, flags, access_plist_id ); + } + + if( id <= 0 ) // throw an exception when open/create fail + { + throw FileIException(); + } +} + +// Copy constructor: makes a copy of the original H5File object. +H5File::H5File( const H5File& original ) : IdComponent( original ) {} + +// Determines whether a file specified by its name in HDF5 format +bool H5File::isHdf5(const string& name ) +{ + return( isHdf5( name.c_str()) ); +} +bool H5File::isHdf5(const char* name ) +{ + // Calls C routine H5Fis_hdf5 to determine whether the file is in + // HDF5 format. It returns positive value, 0, or negative value + htri_t ret_value = H5Fis_hdf5( name ); + if( ret_value > 0 ) + return true; + else if( ret_value == 0 ) + return false; + else // Raise exception when H5Fis_hdf5 returns a negative value + { + throw FileIException(); + } +} + +// Reopens this file +void H5File::reopen() +{ + // reset the identifier of this H5File - send 'this' in so that + // H5Fclose can be called appropriately + resetIdComponent( this ); + + // call C routine to reopen the file - Note: not sure about this + // does id need to be closed later? which id to be the parameter? + id = H5Freopen( id ); + if( id <= 0 ) // Raise exception when H5Freopen returns a neg value + { + throw FileIException(); + } +} + +// Creates a new group in this file using the template function provided +// in FGtemplates.h +Group H5File::createGroup( const string& name, size_t size_hint ) const +{ + return( createGroup( name.c_str(), size_hint )); +} + +Group H5File::createGroup( const char* name, size_t size_hint ) const +{ + try { + Group group = createGroupT( id, name, size_hint ); + return( group ); + } + catch( File_GroupException error ) + { + throw FileIException(); + } +} + +// Opens an existing group in this file using the template function provided +// in FGtemplates.h +Group H5File::openGroup( const string& name ) const +{ + return( openGroup( name.c_str() )); +} + +Group H5File::openGroup( const char* name ) const +{ + try { + Group group = openGroupT( id, name ); + return( group ); + } + catch( File_GroupException error ) + { + throw FileIException(); + } +} + +// Creates a dataset in this file using the template function +// provided in FGtemplates.h +DataSet H5File::createDataSet( const string& name, const DataType& data_type, const DataSpace& data_space, const DSetCreatPropList& create_plist ) const +{ + return( createDataSet( name.c_str(), data_type, data_space, create_plist )); +} + +DataSet H5File::createDataSet( const char* name, const DataType& data_type, const DataSpace& data_space, const DSetCreatPropList& create_plist ) const +{ + try { + DataSet dataset = createDataSetT( id, name, data_type, data_space, create_plist ); + return( dataset ); + } + catch( File_GroupException error ) + { + throw FileIException(); + } +} + +// Opens an existing dataset in this file using the template function +// provided in FGtemplates.h +DataSet H5File::openDataSet( const string& name ) const +{ + return( openDataSet( name.c_str() )); +} + +DataSet H5File::openDataSet( const char* name ) const +{ + try { + DataSet dataset = openDataSetT( id, name ); + return( dataset ); + } + catch( File_GroupException error ) + { + throw FileIException(); + } +} + +// This private member function calls the C API H5Topen to open the +// named datatype in this file, and returns the datatype's identifier. +// The function is used by the functions openXxxType's below for +// opening the sub-types +hid_t H5File::p_openDataType( const char* name ) const +{ + // Call C function H5Topen to open the named datatype in this group, + // giving the group id + hid_t datatype_id = H5Topen( id, name ); + + // If the datatype id is valid, return it, otherwise, throw an exception. + if( datatype_id > 0 ) + return( datatype_id ); + else + { + throw FileIException(); + } +} + +// +// The following member functions use the private function +// p_openDataType to open a named datatype in this group +// + +// Opens the named generic datatype in this group. +DataType H5File::openDataType( const string& name ) const +{ + return( openDataType( name.c_str()) ); +} +DataType H5File::openDataType( const char* name ) const +{ + DataType data_type( p_openDataType( name )); + return( data_type ); +} + +// Opens the named enumeration datatype in this group. +EnumType H5File::openEnumType( const string& name ) const +{ + return( openEnumType( name.c_str()) ); +} +EnumType H5File::openEnumType( const char* name ) const +{ + EnumType enum_type( p_openDataType( name )); + return( enum_type ); +} + +// Opens the named compound datatype in this group. +CompType H5File::openCompType( const string& name ) const +{ + return( openCompType( name.c_str()) ); +} +CompType H5File::openCompType( const char* name ) const +{ + CompType comp_type( p_openDataType( name )); + return( comp_type ); +} + +// Opens the named integer datatype in this group. +IntType H5File::openIntType( const string& name ) const +{ + return( openIntType( name.c_str()) ); +} +IntType H5File::openIntType( const char* name ) const +{ + IntType int_type( p_openDataType( name )); + return( int_type ); +} + +// Opens the named floating-point datatype in this group. +FloatType H5File::openFloatType( const string& name ) const +{ + return( openFloatType( name.c_str()) ); +} +FloatType H5File::openFloatType( const char* name ) const +{ + FloatType float_type( p_openDataType( name )); + return( float_type ); +} + +// Opens the named string datatype of this group +StrType H5File::openStrType( const string& name ) const +{ + return( openStrType( name.c_str()) ); +} +StrType H5File::openStrType( const char* name ) const +{ + StrType str_type( p_openDataType( name )); + return( str_type ); +} + +// Returns the creation property list of this file +FileCreatPropList H5File::getCreatePlist() const +{ + hid_t create_plist_id = H5Fget_create_plist( id ); + + // if H5Fget_create_plist returns a valid id, create and return + // the FileCreatPropList object for this property list + if( create_plist_id > 0 ) + { + FileCreatPropList create_plist( create_plist_id ); + return( create_plist ); + } + else + { + throw FileIException(); + } +} + +// Returns the access property list of this file +FileAccPropList H5File::getAccessPlist() const +{ + hid_t access_plist_id = H5Fget_access_plist( id ); + + // if H5Fget_access_plist returns a valid id, create and return + // the FileAccPropList object for this property list + if( access_plist_id > 0 ) + { + FileAccPropList access_plist( access_plist_id ); + return access_plist; + } + else // Raise an exception + { + throw FileIException(); + } +} + +// Creates a link of the specified type from new_name to current_name; +// both names are interpreted relative to this file +void H5File::link( H5G_link_t link_type, const string& curr_name, const string& new_name ) const +{ + link( link_type, curr_name.c_str(), new_name.c_str() ); +} + +void H5File::link( H5G_link_t link_type, const char* curr_name, const char* new_name ) const +{ + try { + linkT( id, link_type, curr_name, new_name ); + } + catch( File_GroupException error ) { + throw FileIException(); + } +} + +// Removes the specified name from this file. +void H5File::unlink( const string& name ) const +{ + unlink( name.c_str()); +} + +void H5File::unlink( const char* name ) const +{ + try { + unlinkT( id, name ); + } + catch( File_GroupException error ) { + throw FileIException(); + } +} + +// Renames an object from this file. +void H5File::move( const string& src, const string& dst ) const +{ + move( src.c_str(), dst.c_str()); +} + +void H5File::move( const char* src, const char* dst ) const +{ + try { + moveT( id, src, dst ); + } + catch( File_GroupException error ) { + throw FileIException(); + } +} + +// Returns information about an object +void H5File::getObjinfo( const string& name, hbool_t follow_link, H5G_stat_t& statbuf ) const +{ + getObjinfo( name, follow_link, statbuf ); +} + +void H5File::getObjinfo( const char* name, hbool_t follow_link, H5G_stat_t& statbuf ) const +{ + try { + getObjinfoT( id, name, follow_link, statbuf ); + } + catch( File_GroupException error ) { + throw FileIException(); + } +} + +// Returns the name of the object that the symbolic link points to. +string H5File::getLinkval( const string& name, size_t size ) const +{ + return( getLinkval( name.c_str(), size )); +} + +string H5File::getLinkval( const char* name, size_t size ) const +{ + try { + string value = getLinkvalT( id, name, size ); + return( value ); + } + catch( File_GroupException error ) { + throw FileIException(); + } +} + +// Sets comment for specified object. +void H5File::setComment( const string& name, const string& comment ) const +{ + setComment( name.c_str(), comment.c_str()); +} + +void H5File::setComment( const char* name, const char* comment ) const +{ + try { + setCommentT( id, name, comment ); + } + catch( File_GroupException error ) { + throw FileIException(); + } +} + +// Retrieves comment for specified object +string H5File::getComment( const string& name, size_t bufsize ) const +{ + return( getComment( name.c_str(), bufsize )); +} + +string H5File::getComment( const char* name, size_t bufsize ) const +{ + try { + string comment = getCommentT( id, name, bufsize ); + return( comment ); + } + catch( File_GroupException error ) { + throw FileIException(); + } +} + +// Mounts the file 'child' onto this file +void H5File::mount( const string& name, H5File& child, PropList& mount_plist ) const +{ + mount( name.c_str(), child, mount_plist ); +} + +void H5File::mount( const char* name, H5File& child, PropList& mount_plist ) const +{ + try { + mountT( id, name, child.getId(), mount_plist ); + } + catch( File_GroupException error ) { + throw FileIException(); + } +} + +// Unmounts the file named 'name' from this parent file +void H5File::unmount( const string& name ) const +{ + unmount( name.c_str() ); +} + +void H5File::unmount( const char* name ) const +{ + try { + unmountT( id, name ); + } + catch( File_GroupException error ) { + throw FileIException(); + } +} + +// Calls the C API H5Fclose to close this file. Used by IdComponent::reset +void H5File::p_close() const +{ + herr_t ret_value = H5Fclose( id ); + if( ret_value < 0 ) + { + throw FileIException(); + } +} + +// The destructor of this instance calls IdComponent::reset to +// reset its identifier - no longer true +// Older compilers (baldric) don't support template member functions +// and IdComponent::reset is one; so at this time, the resetId is not +// a member function so it can be template to work around that problem. +H5File::~H5File() +{ + // The HDF5 file id will be closed properly + resetIdComponent( this ); +} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5FloatType.cpp b/c++/src/H5FloatType.cpp new file mode 100644 index 0000000..34275f8 --- /dev/null +++ b/c++/src/H5FloatType.cpp @@ -0,0 +1,153 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5DataType.h" +#include "H5AbstractDs.h" +#include "H5DxferProp.h" +#include "H5DataSpace.h" +#include "H5AtomType.h" +#include "H5FloatType.h" +#include "H5DataSet.h" +#include "H5PredType.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Default constructor +FloatType::FloatType() {} + +// Creates a floating-point type using a predefined type +FloatType::FloatType( const PredType& pred_type ) : AtomType() +{ + // use DataType::copy to make a copy of this predefined type + copy( pred_type ); +} + +// Creates a floating-point datatype using an existing id +FloatType::FloatType( const hid_t existing_id ) : AtomType( existing_id ) {} + +// Copy constructor: makes a copy of the original FloatType object +FloatType::FloatType( const FloatType& original ) : AtomType( original ){} + +// Gets the floating-point datatype of the specified dataset - will reimplement +FloatType::FloatType( const DataSet& dataset ) : AtomType() +{ + // Calls C function H5Dget_type to get the id of the datatype + id = H5Dget_type( dataset.getId() ); + + if( id <= 0 ) + { + throw DataSetIException(); + } +} + +// Retrieves floating point datatype bit field information. +void FloatType::getFields( size_t& spos, size_t& epos, size_t& esize, size_t& mpos, size_t& msize ) const +{ + herr_t ret_value = H5Tget_fields( id, &spos, &epos, &esize, &mpos, &msize ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Sets locations and sizes of floating point bit fields. +void FloatType::setFields( size_t spos, size_t epos, size_t esize, size_t mpos, size_t msize ) const +{ + herr_t ret_value = H5Tset_fields( id, spos, epos, esize, mpos, msize ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Retrieves the exponent bias of a floating-point type. +size_t FloatType::getEbias() const +{ + size_t ebias = H5Tget_ebias( id ); + // Returns the bias if successful + if( ebias == 0 ) + { + throw DataTypeIException(); + } + return( ebias ); +} + +// Sets the exponent bias of a floating-point type. +void FloatType::setEbias( size_t ebias ) const +{ + herr_t ret_value = H5Tset_ebias( id, ebias ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Retrieves mantissa normalization of a floating-point datatype. +H5T_norm_t FloatType::getNorm( string& norm_string ) const +{ + H5T_norm_t norm = H5Tget_norm( id ); // C routine + // Returns a valid normalization type if successful + if( norm == H5T_NORM_ERROR ) + { + throw DataTypeIException(); + } + if( norm == H5T_NORM_IMPLIED ) + norm_string = "H5T_NORM_IMPLIED (0)"; + else if( norm == H5T_NORM_MSBSET ) + norm_string = "H5T_NORM_MSBSET (1)"; + else if( norm == H5T_NORM_NONE ) + norm_string = "H5T_NORM_NONE (2)"; + return( norm ); +} + +// Sets the mantissa normalization of a floating-point datatype. +void FloatType::setNorm( H5T_norm_t norm ) const +{ + herr_t ret_value = H5Tset_norm( id, norm ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Retrieves the internal padding type for unused bits in floating-point datatypes. +H5T_pad_t FloatType::getInpad( string& pad_string ) const +{ + H5T_pad_t pad_type = H5Tget_inpad( id ); + // Returns a valid padding type if successful + if( pad_type == H5T_PAD_ERROR ) + { + throw DataTypeIException(); + } + if( pad_type == H5T_PAD_ZERO ) + pad_string = "H5T_PAD_ZERO (0)"; + else if( pad_type == H5T_PAD_ONE ) + pad_string = "H5T_PAD_ONE (1)"; + else if( pad_type == H5T_PAD_BACKGROUND ) + pad_string = "H5T_PAD_BACKGROUD (2)"; + return( pad_type ); +} + +// Fills unused internal floating point bits. +void FloatType::setInpad( H5T_pad_t inpad ) const +{ + herr_t ret_value = H5Tset_inpad( id, inpad ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Default destructor +FloatType::~FloatType() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5Group.cpp b/c++/src/H5Group.cpp new file mode 100644 index 0000000..b65ba75 --- /dev/null +++ b/c++/src/H5Group.cpp @@ -0,0 +1,382 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5Idtemplates.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5AbstractDs.h" +#include "H5FaccProp.h" +#include "H5FcreatProp.h" +#include "H5DcreatProp.h" +#include "H5DxferProp.h" +#include "H5DataSpace.h" +#include "H5DataSet.h" +#include "H5CommonFG.h" +#include "H5Group.h" +#include "H5File.h" +#include "H5Alltypes.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Default constructor +Group::Group() : H5Object() {} + +// Copy constructor: makes a copy of the original Group object +Group::Group( const Group& original ) : H5Object( original ) {} + +// Creates a new group in this group using the common function +// provided in FGtemplates.h. +Group Group::createGroup( const string& name, size_t size_hint ) +{ + return( createGroup( name.c_str(), size_hint )); +} +Group Group::createGroup( const char* name, size_t size_hint ) +{ + try { + Group group = createGroupT( id, name, size_hint ); + return( group ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Creates a copy of an existing Group using its id +Group::Group( const hid_t group_id ) : H5Object( group_id ) {} + +// Opens an existing group in this group using the common function +// provided in FGtemplates.h. +Group Group::openGroup( const string& name ) +{ + return( openGroup( name.c_str() )); +} +Group Group::openGroup( const char* name ) +{ + try { + Group group = openGroupT( id, name ); + return( group ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Creates a dataset in this group using the common function +// provided in FGtemplates.h +DataSet Group::createDataSet( const string& name, const DataType& data_type, const DataSpace& data_space, const DSetCreatPropList& create_plist ) +{ + return( createDataSet( name.c_str(), data_type, data_space, create_plist )); +} +DataSet Group::createDataSet( const char* name, const DataType& data_type, const DataSpace& data_space, const DSetCreatPropList& create_plist ) +{ + try { + DataSet dataset = createDataSetT( id, name, data_type, data_space, create_plist ); + return( dataset ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Opens a dataset in this group using the common function +// provided in FGtemplates.h +DataSet Group::openDataSet( const string& name ) +{ + return( openDataSet( name.c_str() )); +} +DataSet Group::openDataSet( const char* name ) +{ + try { + DataSet dataset = openDataSetT( id, name ); + return( dataset ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// This private member function calls the C API H5Topen to open the +// named datatype and returns the datatype's identifier. The function +// is used by the functions openXxxType's below for opening the sub-types +hid_t Group::p_openDataType( const char* name ) const +{ + // Call C function H5Topen to open the named datatype in this group, + // giving the group id + hid_t datatype_id = H5Topen( id, name ); + + // If the datatype id is valid, return it, otherwise, throw an exception. + if( datatype_id > 0 ) + return( datatype_id ); + else + { + throw GroupIException(); + } +} + +// +// The following member functions use the private function +// p_openDataType to open a named datatype in this group +// + +// Opens the named generic datatype in this group. +DataType Group::openDataType( const string& name ) const +{ + return( openDataType( name.c_str()) ); +} +DataType Group::openDataType( const char* name ) const +{ + DataType data_type( p_openDataType( name )); + return( data_type ); +} + +// Opens the named enumeration datatype in this group. +EnumType Group::openEnumType( const string& name ) const +{ + return( openEnumType( name.c_str()) ); +} +EnumType Group::openEnumType( const char* name ) const +{ + EnumType enum_type( p_openDataType( name )); + return( enum_type ); +} + +// Opens the named compound datatype in this group. +CompType Group::openCompType( const string& name ) const +{ + return( openCompType( name.c_str()) ); +} +CompType Group::openCompType( const char* name ) const +{ + CompType comp_type( p_openDataType( name )); + return( comp_type ); +} + +// Opens the named integer datatype in this group. +IntType Group::openIntType( const string& name ) const +{ + return( openIntType( name.c_str()) ); +} +IntType Group::openIntType( const char* name ) const +{ + IntType int_type( p_openDataType( name )); + return( int_type ); +} + +// Opens the named floating-point datatype in this group. +FloatType Group::openFloatType( const string& name ) const +{ + return( openFloatType( name.c_str()) ); +} +FloatType Group::openFloatType( const char* name ) const +{ + FloatType float_type( p_openDataType( name )); + return( float_type ); +} + +// Opens the named string datatype of this group +StrType Group::openStrType( const string& name ) const +{ + return( openStrType( name.c_str()) ); +} +StrType Group::openStrType( const char* name ) const +{ + StrType str_type( p_openDataType( name )); + return( str_type ); +} + +// Iterates a user's function over the entries of a group. +int Group::iterateElems( const string& name, int *idx, H5G_iterate_t op , void *op_data ) +{ + return( iterateElems( name.c_str(), idx, op, op_data )); +} +int Group::iterateElems( const char* name, int *idx, H5G_iterate_t op , void *op_data ) +{ + int ret_value = H5Giterate( id, name, idx, op, op_data ); + if( ret_value >= 0 ) + return( ret_value ); + else // raise exception when H5Aiterate returns a negative value + { + throw GroupIException(); + } +} + +// Creates a link of the specified type from new_name to current_name; +// both names are interpreted relative to this group. +void Group::link( H5G_link_t link_type, const string& curr_name, const string& new_name ) +{ + link( link_type, curr_name.c_str(), new_name.c_str() ); +} +void Group::link( H5G_link_t link_type, const char* curr_name, const char* new_name ) +{ + try { + linkT( id, link_type, curr_name, new_name ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Removes the specified name from this group. +void Group::unlink( const string& name ) +{ + unlink( name.c_str() ); +} +void Group::unlink( const char* name ) +{ + try { + unlinkT( id, name ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Renames an object from this group. +void Group::move( const string& src, const string& dst ) +{ + move( src.c_str(), dst.c_str() ); +} +void Group::move( const char* src, const char* dst ) +{ + try { + moveT( id, src, dst ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Retrieves information about an object. +void Group::getObjinfo( const string& name, hbool_t follow_link, H5G_stat_t& statbuf ) +{ + getObjinfo( name.c_str(), follow_link, statbuf ); +} +void Group::getObjinfo( const char* name, hbool_t follow_link, H5G_stat_t& statbuf ) +{ + try { + getObjinfoT( id, name, follow_link, statbuf ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Returns the name of the object that the symbolic link points to. +string Group::getLinkval( const string& name, size_t size ) +{ + return( getLinkval( name.c_str(), size )); +} +string Group::getLinkval( const char* name, size_t size ) +{ + try { + string value = getLinkvalT( id, name, size ); + return( value ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Sets comment for an object specified by its name. +void Group::setComment( const string& name, const string& comment ) +{ + setComment( name.c_str(), comment ); +} +void Group::setComment( const char* name, const char* comment ) +{ + try { + setCommentT( id, name, comment ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Retrieves the comment of an object specified by its name +string Group::getComment( const string& name, size_t bufsize ) +{ + return( getComment( name.c_str(), bufsize )); +} +string Group::getComment( const char* name, size_t bufsize ) +{ + try { + string comment = getCommentT( id, name, bufsize ); + return( comment ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Mounts the file 'child' onto this group. +void Group::mount( const string& name, H5File& child, PropList& plist ) +{ + mount( name.c_str(), child, plist ); +} +void Group::mount( const char* name, H5File& child, PropList& plist ) +{ + try { + mountT( id, name, child.getId(), plist ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Unmounts the file named 'name' from this parent group. +void Group::unmount( const string& name ) +{ + unmount( name.c_str() ); +} +void Group::unmount( const char* name ) +{ + try { + unmountT( id, name ); + } + catch( File_GroupException error ) + { + throw GroupIException(); + } +} + +// Calls the C API H5Gclose to close this group. Used by IdComponent::reset +void Group::p_close() const +{ + herr_t ret_value = H5Gclose( id ); + if( ret_value < 0 ) + { + throw GroupIException(); + } +} + +// The destructor of this instance calls IdComponent::reset to +// reset its identifier - no longer true +// Older compilers (baldric) don't support template member functions +// and IdComponent::reset is one; so at this time, the resetId is not +// a member function so it can be template to work around that problem. +Group::~Group() +{ + // The group id will be closed properly + resetIdComponent( this ); +} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp new file mode 100644 index 0000000..2b7bff8 --- /dev/null +++ b/c++/src/H5IdComponent.cpp @@ -0,0 +1,136 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5Library.h" +#include "H5IdComponent.h" +#include "H5Idtemplates.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Default constructor - private +IdComponent::IdComponent() : id( 0 ) +{ + // starts counting object references + ref_count = new RefCounter; +} + +// Constructor that takes an HDF5 object id. It creates an instance +// of IdComponent to hold the HDF5 id +IdComponent::IdComponent( hid_t h5_id ) : id( h5_id ) +{ + // starts counting object references + ref_count = new RefCounter; +} + +// Copy constructor: makes a copy of the original object +IdComponent::IdComponent( const IdComponent& original ) +{ + id = original.id; + ref_count = original.ref_count; // points to the same ref counter + ref_count->increment(); // increment number of references to this id +} + +// Increment reference counter +void IdComponent::incRefCount() { ref_count->increment(); } + +// Decrement reference counter +void IdComponent::decRefCount() { ref_count->decrement(); } + +// Get the reference counter to this identifier +int IdComponent::getCounter() { return( ref_count->getCounter()); } + +// Decrements the reference counter then determines if there are no more +// reference to this object +bool IdComponent::noReference() +{ + if( ref_count->getCounter() > 0 ) + ref_count->decrement(); + return( ref_count->getCounter() == 0 ? true:false ); +} + +/* Assignment operator. + Description: + Reset the identifier of this object so that the HDF5 id can be properly + closed. Copy the new identifier to this object, then increment the + reference counter of the identifier to indicate that another object + is referencing the identifier. +*/ +IdComponent& IdComponent::operator=( const IdComponent& rhs ) +{ + // reset the identifier of this object - resetIdComponent will call the + // appropriate H5xclose to close the id + resetIdComponent( this ); + + // copy the data members from the rhs object + id = rhs.id; + ref_count = rhs.ref_count; // points to the same ref counter + + // increment the reference counter + ref_count->increment(); + + return( *this ); +} + +/* Sets the identifier of this object to a new value + Description: + Reset the current identifier of this object so that the HDF5 + id can be appropriately closed. If only this object references + its identifier, its reference counter will be deleted. A new + reference counter is created for the new HDF5 object id. +*/ +void IdComponent::setId( hid_t new_id ) +{ + // reset the identifier of this object, call appropriate H5Xclose + resetIdComponent( this ); + + id = new_id; + + // starts counting object references + ref_count = new RefCounter; +} + +// Gets the id of this object +hid_t IdComponent::getId () const +{ + return( id ); +} + +// Reset this object by deleting its RefCounter +void IdComponent::reset () +{ + delete ref_count; +} + +// Default destructor +IdComponent::~IdComponent() { + +/* uncomment this block when decide to use dontAtExit or fix the atexit/ + global destructor problem - BMR 11/14/00 + + if( id == NOTATEXIT ) + { + // Call H5Library::close to clean up - temporary solution to avoid the + // trouble of atexit/global destructors + try { + if( H5Library::need_cleanup == true ) + { + H5Library::close(); + H5Library::need_cleanup = false; // reset the boolean just in case + } + } + // catch failure caused by the H5Library operations + catch( LibraryIException error ) + { + error.printError(); + } + } +*/ +} + +#ifndef H5_NO_NAMESPACE +} +#endif diff --git a/c++/src/H5IntType.cpp b/c++/src/H5IntType.cpp new file mode 100644 index 0000000..bc1e1bc --- /dev/null +++ b/c++/src/H5IntType.cpp @@ -0,0 +1,78 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5DataType.h" +#include "H5AbstractDs.h" +#include "H5DxferProp.h" +#include "H5DataSpace.h" +#include "H5AtomType.h" +#include "H5IntType.h" +#include "H5DataSet.h" +#include "H5PredType.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Default constructor +IntType::IntType() {} + +// Copy constructor: makes copy of the original IntType object +IntType::IntType( const IntType& original ) : AtomType( original ) {} + +// Creates a integer type using a predefined type +IntType::IntType( const PredType& pred_type ) : AtomType() +{ + // use DataType::copy to make a copy of this predefined type + copy( pred_type ); +} + +// Creates a integer datatype using an existing id +IntType::IntType( const hid_t existing_id ) : AtomType( existing_id ) {} + +// Gets the integer datatype of the specified dataset - will reimplement +IntType::IntType( const DataSet& dataset ) : AtomType() +{ + // Calls C function H5Dget_type to get the id of the datatype + id = H5Dget_type( dataset.getId() ); + + if( id <= 0 ) + { + throw DataSetIException(); + } +} + +// Retrieves the sign type for an integer type +H5T_sign_t IntType::getSign() const +{ + H5T_sign_t type_sign = H5Tget_sign( id ); // C routine + // Returns a valid sign type if successful + if( type_sign == H5T_SGN_ERROR ) + { + throw DataTypeIException(); + } + return( type_sign ); +} + +// Sets the sign proprety for an integer type. +void IntType::setSign( H5T_sign_t sign ) const +{ + // Call C routine to set the sign property + herr_t ret_value = H5Tset_sign( id, sign ); + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// This destructor terminates access to the datatype +IntType::~IntType() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5Library.cpp b/c++/src/H5Library.cpp new file mode 100644 index 0000000..ffce037 --- /dev/null +++ b/c++/src/H5Library.cpp @@ -0,0 +1,67 @@ +#include + +#include "H5Include.h" +#include "H5Exception.h" +#include "H5Library.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// This static variable will be set to true when dontAtExit is called +bool H5Library::need_cleanup = false; + +// Initializes the HDF5 library. +void H5Library::open() +{ + herr_t ret_value = H5open(); + if( ret_value < 0 ) + { + throw LibraryIException(); + } +} + +// Flushes all data to disk, closes files, and cleans up memory. +void H5Library::close() +{ + herr_t ret_value = H5close(); + if( ret_value < 0 ) + { + throw LibraryIException(); + } +} + +// Instructs library not to install atexit cleanup routine +void H5Library::dontAtExit() +{ + herr_t ret_value = H5dont_atexit(); + if( ret_value < 0 ) + { + throw LibraryIException(); + } +} + +// Returns the HDF library release number. +void H5Library::getLibVersion( unsigned& majnum, unsigned& minnum, unsigned& relnum ) +{ + herr_t ret_value = H5get_libversion( &majnum, &minnum, &relnum ); + if( ret_value < 0 ) + { + throw LibraryIException(); + } +} + +// Verifies that the arguments match the version numbers compiled +// into the library +void H5Library::checkVersion( unsigned majnum, unsigned minnum, unsigned relnum ) +{ + herr_t ret_value = H5check_version( majnum, minnum, relnum ); + if( ret_value < 0 ) + { + throw LibraryIException(); + } +} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp new file mode 100644 index 0000000..82f7849 --- /dev/null +++ b/c++/src/H5Object.cpp @@ -0,0 +1,168 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5Idtemplates.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5DataType.h" +#include "H5DataSpace.h" +#include "H5AbstractDs.h" +#include "H5Attribute.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// userAttrOpWrpr simply interfaces between the user's function and the +// C library function H5Aiterate; used to resolve the different prototype +// problem. May be moved to Iterator later. +extern "C" herr_t userAttrOpWrpr( hid_t loc_id, const char* attr_name, void* op_data ) +{ + string s_attr_name = string( attr_name ); + UserData4Aiterate* myData = static_cast (op_data); + myData->op( *myData->object, s_attr_name, myData->opData ); + return 0; +} + +// Default constructor - set id to 0 by default here but may be set +// to a valid HDF5 id, if any, by a subclass constructor. +H5Object::H5Object() : IdComponent() {} + +// Constructs an object from an existing HDF5 id +H5Object::H5Object( hid_t object_id ) : IdComponent( object_id ) {} + +// Copy constructor: makes a copy of the original H5Object instance +H5Object::H5Object( const H5Object& original ) : IdComponent( original ) {} + +// Creates an attribute for a group, dataset, or named datatype. +Attribute H5Object::createAttribute( const char* name, const DataType& data_type, const DataSpace& data_space, const PropList& create_plist ) const +{ + hid_t type_id = data_type.getId(); + hid_t space_id = data_space.getId(); + hid_t plist_id = create_plist.getId(); + hid_t attr_id = H5Acreate( id, name, type_id, space_id, plist_id ); + + // If the attribute id is valid, create and return the Attribute object + if( attr_id > 0 ) + { + Attribute attr( attr_id ); + return( attr ); + } + else + { + throw AttributeIException(); + } +} + +// Creates an attribute for a group, dataset, or named datatype. +Attribute H5Object::createAttribute( const string& name, const DataType& data_type, const DataSpace& data_space, const PropList& create_plist ) const +{ + return( createAttribute( name.c_str(), data_type, data_space, create_plist )); +} + +// Opens an attribute given its name; name is given as char* +Attribute H5Object::openAttribute( const char* name ) const +{ + hid_t attr_id = H5Aopen_name( id, name ); + if( attr_id > 0 ) + { + Attribute attr( attr_id ); + return( attr ); + } + else + { + throw AttributeIException(); + } +} + +// Opens an attribute given its name; name is given as string +Attribute H5Object::openAttribute( const string& name ) const +{ + return( openAttribute( name.c_str()) ); +} + +// Opens an attribute given its index. +Attribute H5Object::openAttribute( unsigned int idx ) const +{ + hid_t attr_id = H5Aopen_idx( id, idx ); + if( attr_id > 0 ) + { + Attribute attr( attr_id ); + return( attr ); + } + else + { + throw AttributeIException(); + } +} + +// Iterates a user's function over all the attributes of the dataset +int H5Object::iterateAttrs( attr_operator_t user_op, unsigned * idx, void *op_data ) +{ + // store the user's function and data + UserData4Aiterate* userData = new UserData4Aiterate; + userData->opData = op_data; + userData->idx = idx; + userData->op = user_op; + userData->object = this; + + // call the C library routine H5Aiterate to iterate the attributes + int ret_value = H5Aiterate( id, idx, userAttrOpWrpr, (void *) userData ); + // release memory + delete userData; + + if( ret_value >= 0 ) + return( ret_value ); + else // raise exception when H5Aiterate returns a negative value + { + throw AttributeIException(); + } +} + +// Determines the number of attributes attached to +int H5Object::getNumAttrs() const +{ + int num_attrs = H5Aget_num_attrs( id ); + if( num_attrs < 0 ) + { + throw AttributeIException(); + } + else + return( num_attrs ); +} + +// Removes the named attribute from this object. +void H5Object::removeAttr( const char* name ) const +{ + herr_t ret_value = H5Adelete( id, name ); + if( ret_value < 0 ) + { + throw AttributeIException(); + } +} +void H5Object::removeAttr( const string& name ) const +{ + removeAttr( name.c_str() ); +} + +// Flushes all buffers associated with a file to disk. +void H5Object::flush(H5F_scope_t scope ) const +{ + herr_t ret_value = H5Fflush( id, scope ); + if( ret_value < 0 ) + { + throw FileIException(); + } +} + +// each subclass' destructor calls the template function resetIdComponent() +// to reset the corresponding IdComponent object and close the HDF5 object +// where appropriate. +H5Object::~H5Object() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5PredType.cpp b/c++/src/H5PredType.cpp new file mode 100644 index 0000000..deada00 --- /dev/null +++ b/c++/src/H5PredType.cpp @@ -0,0 +1,192 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5DataType.h" +#include "H5AtomType.h" +#include "H5Library.h" +#include "H5PredType.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Default constructor +PredType::PredType() : AtomType() {} + +// creates predefined datatype, so set DataType::is_predtype to true by default +PredType::PredType( const hid_t predtype_id ) : AtomType( predtype_id ) +{ + is_predtype = true; +} + +// Copy constructor: makes a copy of this PredType object. +PredType::PredType( const PredType& original ) : AtomType( original ) {} + +const PredType PredType::NotAtexit; // only for atexit/global dest. problem + +// Definition of pre-defined types +const PredType PredType::C_S1( H5T_C_S1 ); +const PredType PredType::FORTRAN_S1( H5T_FORTRAN_S1 ); + +const PredType PredType::STD_I8BE( H5T_STD_I8BE ); +const PredType PredType::STD_I8LE( H5T_STD_I8LE ); +const PredType PredType::STD_I16BE( H5T_STD_I16BE ); +const PredType PredType::STD_I16LE( H5T_STD_I16LE ); +const PredType PredType::STD_I32BE( H5T_STD_I32BE ); +const PredType PredType::STD_I32LE( H5T_STD_I32LE ); +const PredType PredType::STD_I64BE( H5T_STD_I64BE ); +const PredType PredType::STD_I64LE( H5T_STD_I64LE ); +const PredType PredType::STD_U8BE( H5T_STD_U8BE ); +const PredType PredType::STD_U8LE( H5T_STD_U8LE ); +const PredType PredType::STD_U16BE( H5T_STD_U16BE ); +const PredType PredType::STD_U16LE( H5T_STD_U16LE ); +const PredType PredType::STD_U32BE( H5T_STD_U32BE ); +const PredType PredType::STD_U32LE( H5T_STD_U32LE ); +const PredType PredType::STD_U64BE( H5T_STD_U64BE ); +const PredType PredType::STD_U64LE( H5T_STD_U64LE ); +const PredType PredType::STD_B8BE( H5T_STD_B8BE ); +const PredType PredType::STD_B8LE( H5T_STD_B8LE ); +const PredType PredType::STD_B16BE( H5T_STD_B16BE ); +const PredType PredType::STD_B16LE( H5T_STD_B16LE ); +const PredType PredType::STD_B32BE( H5T_STD_B32BE ); +const PredType PredType::STD_B32LE( H5T_STD_B32LE ); +const PredType PredType::STD_B64BE( H5T_STD_B64BE ); +const PredType PredType::STD_B64LE( H5T_STD_B64LE ); +const PredType PredType::STD_REF_OBJ( H5T_STD_REF_OBJ ); +const PredType PredType::STD_REF_DSETREG( H5T_STD_REF_DSETREG ); + +const PredType PredType::IEEE_F32BE( H5T_IEEE_F32BE ); +const PredType PredType::IEEE_F32LE( H5T_IEEE_F32LE ); +const PredType PredType::IEEE_F64BE( H5T_IEEE_F64BE ); +const PredType PredType::IEEE_F64LE( H5T_IEEE_F64LE ); + +const PredType PredType::UNIX_D32BE( H5T_UNIX_D32BE ); +const PredType PredType::UNIX_D32LE( H5T_UNIX_D32LE ); +const PredType PredType::UNIX_D64BE( H5T_UNIX_D64BE ); +const PredType PredType::UNIX_D64LE( H5T_UNIX_D64LE ); + +const PredType PredType::INTEL_I8( H5T_INTEL_I8 ); +const PredType PredType::INTEL_I16( H5T_INTEL_I16 ); +const PredType PredType::INTEL_I32( H5T_INTEL_I32 ); +const PredType PredType::INTEL_I64( H5T_INTEL_I64 ); +const PredType PredType::INTEL_U8( H5T_INTEL_U8 ); +const PredType PredType::INTEL_U16( H5T_INTEL_U16 ); +const PredType PredType::INTEL_U32( H5T_INTEL_U32 ); +const PredType PredType::INTEL_U64( H5T_INTEL_U64 ); +const PredType PredType::INTEL_B8( H5T_INTEL_B8 ); +const PredType PredType::INTEL_B16( H5T_INTEL_B16 ); +const PredType PredType::INTEL_B32( H5T_INTEL_B32 ); +const PredType PredType::INTEL_B64( H5T_INTEL_B64 ); +const PredType PredType::INTEL_F32( H5T_INTEL_F32 ); +const PredType PredType::INTEL_F64( H5T_INTEL_F64 ); + +const PredType PredType::ALPHA_I8( H5T_ALPHA_I8 ); +const PredType PredType::ALPHA_I16( H5T_ALPHA_I16 ); +const PredType PredType::ALPHA_I32( H5T_ALPHA_I32 ); +const PredType PredType::ALPHA_I64( H5T_ALPHA_I64 ); +const PredType PredType::ALPHA_U8( H5T_ALPHA_U8 ); +const PredType PredType::ALPHA_U16( H5T_ALPHA_U16 ); +const PredType PredType::ALPHA_U32( H5T_ALPHA_U32 ); +const PredType PredType::ALPHA_U64( H5T_ALPHA_U64 ); +const PredType PredType::ALPHA_B8( H5T_ALPHA_B8 ); +const PredType PredType::ALPHA_B16( H5T_ALPHA_B16 ); +const PredType PredType::ALPHA_B32( H5T_ALPHA_B32 ); +const PredType PredType::ALPHA_B64( H5T_ALPHA_B64 ); +const PredType PredType::ALPHA_F32( H5T_ALPHA_F32 ); +const PredType PredType::ALPHA_F64( H5T_ALPHA_F64 ); + +const PredType PredType::MIPS_I8( H5T_MIPS_I8 ); +const PredType PredType::MIPS_I16( H5T_MIPS_I16 ); +const PredType PredType::MIPS_I32( H5T_MIPS_I32 ); +const PredType PredType::MIPS_I64( H5T_MIPS_I64 ); +const PredType PredType::MIPS_U8( H5T_MIPS_U8 ); +const PredType PredType::MIPS_U16( H5T_MIPS_U16 ); +const PredType PredType::MIPS_U32( H5T_MIPS_U32 ); +const PredType PredType::MIPS_U64( H5T_MIPS_U64 ); +const PredType PredType::MIPS_B8( H5T_MIPS_B8 ); +const PredType PredType::MIPS_B16( H5T_MIPS_B16 ); +const PredType PredType::MIPS_B32( H5T_MIPS_B32 ); +const PredType PredType::MIPS_B64( H5T_MIPS_B64 ); +const PredType PredType::MIPS_F32( H5T_MIPS_F32 ); +const PredType PredType::MIPS_F64( H5T_MIPS_F64 ); + +const PredType PredType::NATIVE_CHAR( H5T_NATIVE_CHAR ); +const PredType PredType::NATIVE_INT( H5T_NATIVE_INT ); +const PredType PredType::NATIVE_FLOAT( H5T_NATIVE_FLOAT ); +const PredType PredType::NATIVE_SCHAR( H5T_NATIVE_SCHAR ); +const PredType PredType::NATIVE_UCHAR( H5T_NATIVE_UCHAR ); +const PredType PredType::NATIVE_SHORT( H5T_NATIVE_SHORT ); +const PredType PredType::NATIVE_USHORT( H5T_NATIVE_USHORT ); +const PredType PredType::NATIVE_UINT( H5T_NATIVE_UINT ); +const PredType PredType::NATIVE_LONG( H5T_NATIVE_LONG ); +const PredType PredType::NATIVE_ULONG( H5T_NATIVE_ULONG ); +const PredType PredType::NATIVE_LLONG( H5T_NATIVE_LLONG ); +const PredType PredType::NATIVE_ULLONG( H5T_NATIVE_ULLONG ); +const PredType PredType::NATIVE_DOUBLE( H5T_NATIVE_DOUBLE ); +const PredType PredType::NATIVE_LDOUBLE( H5T_NATIVE_LDOUBLE ); +const PredType PredType::NATIVE_B8( H5T_NATIVE_B8 ); +const PredType PredType::NATIVE_B16( H5T_NATIVE_B16 ); +const PredType PredType::NATIVE_B32( H5T_NATIVE_B32 ); +const PredType PredType::NATIVE_B64( H5T_NATIVE_B64 ); +const PredType PredType::NATIVE_OPAQUE( H5T_NATIVE_OPAQUE ); +const PredType PredType::NATIVE_HSIZE( H5T_NATIVE_HSIZE ); +const PredType PredType::NATIVE_HSSIZE( H5T_NATIVE_HSSIZE ); +const PredType PredType::NATIVE_HERR( H5T_NATIVE_HERR ); +const PredType PredType::NATIVE_HBOOL( H5T_NATIVE_HBOOL ); + +const PredType PredType::NATIVE_INT8( H5T_NATIVE_INT8 ); +const PredType PredType::NATIVE_UINT8( H5T_NATIVE_UINT8 ); +const PredType PredType::NATIVE_INT_LEAST8( H5T_NATIVE_INT_LEAST8 ); +const PredType PredType::NATIVE_UINT_LEAST8( H5T_NATIVE_UINT_LEAST8 ); +const PredType PredType::NATIVE_INT_FAST8( H5T_NATIVE_INT_FAST8 ); +const PredType PredType::NATIVE_UINT_FAST8( H5T_NATIVE_UINT_FAST8 ); + +const PredType PredType::NATIVE_INT16( H5T_NATIVE_INT16 ); +const PredType PredType::NATIVE_UINT16( H5T_NATIVE_UINT16 ); +const PredType PredType::NATIVE_INT_LEAST16( H5T_NATIVE_INT_LEAST16 ); +const PredType PredType::NATIVE_UINT_LEAST16( H5T_NATIVE_UINT_LEAST16 ); +const PredType PredType::NATIVE_INT_FAST16( H5T_NATIVE_INT_FAST16 ); +const PredType PredType::NATIVE_UINT_FAST16( H5T_NATIVE_UINT_FAST16 ); + +const PredType PredType::NATIVE_INT32( H5T_NATIVE_INT32 ); +const PredType PredType::NATIVE_UINT32( H5T_NATIVE_UINT32 ); +const PredType PredType::NATIVE_INT_LEAST32( H5T_NATIVE_INT_LEAST32 ); +const PredType PredType::NATIVE_UINT_LEAST32( H5T_NATIVE_UINT_LEAST32 ); +const PredType PredType::NATIVE_INT_FAST32( H5T_NATIVE_INT_FAST32 ); +const PredType PredType::NATIVE_UINT_FAST32( H5T_NATIVE_UINT_FAST32 ); + +const PredType PredType::NATIVE_INT64( H5T_NATIVE_INT64 ); +const PredType PredType::NATIVE_UINT64( H5T_NATIVE_UINT64 ); +const PredType PredType::NATIVE_INT_LEAST64( H5T_NATIVE_INT_LEAST64 ); +const PredType PredType::NATIVE_UINT_LEAST64( H5T_NATIVE_UINT_LEAST64 ); +const PredType PredType::NATIVE_INT_FAST64( H5T_NATIVE_INT_FAST64 ); +const PredType PredType::NATIVE_UINT_FAST64( H5T_NATIVE_UINT_FAST64 ); + +// These dummy functions do not inherit from DataType - they'll +// throw an DataTypeIException if invoked. +void PredType::commit( H5Object& loc, const char* name ) +{ + throw DataTypeIException( "Attempting to commit a predefined datatype. This operation is invalid" ); +} + +void PredType::commit( H5Object& loc, const string& name ) +{ + commit( loc, name.c_str()); +} + +bool PredType::committed() +{ + throw DataTypeIException( "Attempting to check for commit status on a predefined datatype. This operation is invalid" ); +} + +// Destructor: calls ~AtomType immediately +PredType::~PredType() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5PropList.cpp b/c++/src/H5PropList.cpp new file mode 100644 index 0000000..5279be0 --- /dev/null +++ b/c++/src/H5PropList.cpp @@ -0,0 +1,103 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5Idtemplates.h" +#include "H5PropList.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +const PropList PropList::DEFAULT( H5P_DEFAULT ); + +// Default constructor - set id to 0 by default here but may be set +// to a valid one, if any, by a subclass constructor. +PropList::PropList() : IdComponent( 0 ) +{ +// id_obj = new IdComponent( 0 ); // init default object's id to 0 +} + +// Creates a new property of specified type +PropList::PropList( H5P_class_t type ) : IdComponent( 0 ) +{ + // call C routine to create the new property + id = H5Pcreate(type ); + if( id <= 0 ) + { + throw PropListIException(); + } +} + +// Copy constructor: makes a copy of the original object +PropList::PropList( const PropList& original ) : IdComponent( original ) {} + +/* Constructor that takes an existing property list id. +Description: + Uses an HDF5 id to create a PropList identifier object. This id + can be either an existing property list id or a default property + list id. Design note: in the case of default property list, + the identifier still has reference counter; the p_close function + will take care of not to call H5Pclose on the default id. +*/ +PropList::PropList( const hid_t plist_id ) : IdComponent( plist_id ) { } + +// Makes a copy of an existing property list +void PropList::copy( const PropList& like_plist ) +{ + // reset the identifier of this PropList - send 'this' in so that + // H5Pclose can be called appropriately + resetIdComponent( this ); + + // call C routine to copy the property list + id = H5Pcopy( like_plist.getId() ); + + // points to the same ref counter + ref_count = like_plist.ref_count; + + // increment ref counter to indicate additional references to this id + ref_count->increment(); + + if( id <= 0 ) + { + throw PropListIException(); + } +} + +// Closes the property list if it is not a default one +void PropList::p_close() const +{ + if( id != H5P_DEFAULT ) // not a constant, should call H5Pclose + { + herr_t ret_value = H5Pclose( id ); + if( ret_value < 0 ) + { + throw PropListIException("PropList::p_close: unable to close the property list. Please report this bug to HDF." ); + } + } +} + +// Returns the class of this property list, i.e. H5P_FILE_CREATE... +H5P_class_t PropList::getClass() const +{ + H5P_class_t plist_class = H5Pget_class( id ); + if( plist_class == H5P_NO_CLASS ) + { + throw PropListIException(); + } + return( plist_class ); +} + +// The destructor of this instance calls the template resetIdComponent to +// reset its identifier +PropList::~PropList() +{ + // The property list id will be closed properly + resetIdComponent( this ); +} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5RefCounter.cpp b/c++/src/H5RefCounter.cpp new file mode 100644 index 0000000..6167642 --- /dev/null +++ b/c++/src/H5RefCounter.cpp @@ -0,0 +1,35 @@ +#include "H5RefCounter.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +using namespace std; +#endif + +// Creates a reference counter to be used by an HDF5 object +RefCounter::RefCounter() : counter(1) { } + +// Returns the current value of the reference counter +int RefCounter::getCounter () const { return counter; } + +// Increments the reference counter as a copy of the object that uses +// this counter is created. +void RefCounter::increment() { counter++; } + +// Decrements the reference counter as a copy of the object that uses +// this counter is destroyed. +void RefCounter::decrement() { counter--; } + +// Decrements the reference counter then determines if there are no more +// reference to the object that uses this counter +bool RefCounter::noReference() +{ + if( counter > 0 ) + counter--; + return( counter == 0 ? true:false ); +} + +RefCounter::~RefCounter() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif diff --git a/c++/src/H5StrType.cpp b/c++/src/H5StrType.cpp new file mode 100644 index 0000000..51840db --- /dev/null +++ b/c++/src/H5StrType.cpp @@ -0,0 +1,103 @@ +#include + +#include "H5Include.h" +#include "H5RefCounter.h" +#include "H5Exception.h" +#include "H5IdComponent.h" +#include "H5PropList.h" +#include "H5Object.h" +#include "H5DataType.h" +#include "H5AtomType.h" +#include "H5AbstractDs.h" +#include "H5DxferProp.h" +#include "H5DataSpace.h" +#include "H5StrType.h" +#include "H5DataSet.h" +#include "H5PredType.h" + +#ifndef H5_NO_NAMESPACE +namespace H5 { +#endif + +// Default constructor +StrType::StrType() : AtomType() {} + +// Creates a string type using a predefined type +StrType::StrType( const PredType& pred_type ) : AtomType() +{ + // use DataType::copy to make a copy of this predefined type + copy( pred_type ); +} + +// Creates a string datatype using an existing id +StrType::StrType( const hid_t existing_id ) : AtomType( existing_id ) {} + +// Copy constructor: makes copy of the original StrType object +StrType::StrType( const StrType& original ) : AtomType ( original ) {} + +// Gets the string datatype of the specified dataset - will reimplement +StrType::StrType( const DataSet& dataset ) : AtomType () +{ + // Calls C function H5Dget_type to get the id of the datatype + id = H5Dget_type( dataset.getId() ); + + if( id <= 0 ) + { + throw DataSetIException(); + } +} + +// Retrieves the character set type of a string datatype. +H5T_cset_t StrType::getCset() const +{ + H5T_cset_t cset = H5Tget_cset( id ); + + // Returns a valid character set type if successful + if( cset == H5T_CSET_ERROR ) + { + throw DataTypeIException(); + } + return( cset ); +} + +// Sets character set to be used. +void StrType::setCset( H5T_cset_t cset ) const +{ + herr_t ret_value = H5Tset_cset( id, cset ); + + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// Retrieves the string padding method for a string datatype. +H5T_str_t StrType::getStrpad() const +{ + H5T_str_t strpad = H5Tget_strpad( id ); + + // Returns a valid string padding type if successful + if( strpad == H5T_STR_ERROR ) + { + throw DataTypeIException(); + } + return( strpad ); +} + +// Defines the storage mechanism for character strings. +void StrType::setStrpad( H5T_str_t strpad ) const +{ + herr_t ret_value = H5Tset_strpad( id, strpad ); + + if( ret_value < 0 ) + { + throw DataTypeIException(); + } +} + +// This destructor terminates access to the datatype +StrType::~StrType() {} + +#ifndef H5_NO_NAMESPACE +} // end namespace +#endif -- cgit v0.12