[svn-r17238] Purpose: Fix bug and improve readability
Description:
- Revised DataSet::write to pass in correct string buffer
- Added member function DataSet::getInMemDataSize() to simplify
getting the dataset's data size in memory.
- Added private functions for reading fixed- and variable-length
string data: p_read_fixed_len and p_read_variable_len.
- Added tests to write/read array of strings to datasets.
Platforms tested:
Linux/32 2.6 (jam)
FreeBSD/64 6.3 (liberty)
SunOS 5.10 (linew)
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include "H5File.h"
|
||||
#include "H5Attribute.h"
|
||||
#include "H5DataSet.h"
|
||||
#include "H5private.h" // for HDfree
|
||||
|
||||
#ifndef H5_NO_NAMESPACE
|
||||
namespace H5 {
|
||||
@@ -219,6 +220,53 @@ hsize_t DataSet::getStorageSize() const
|
||||
return(storage_size);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Function: DataSet::getInMemDataSize
|
||||
///\brief Gets the size in memory of the dataset's data.
|
||||
///\return Size of data (in memory)
|
||||
///\exception H5::DataSetIException
|
||||
// Programmer Binh-Minh Ribler - Apr 2009
|
||||
//--------------------------------------------------------------------------
|
||||
size_t DataSet::getInMemDataSize() const
|
||||
{
|
||||
char *func = "DataSet::getInMemDataSize";
|
||||
|
||||
// Get the data type of this dataset
|
||||
hid_t mem_type_id = H5Dget_type(id);
|
||||
if( mem_type_id < 0 )
|
||||
{
|
||||
throw DataSetIException(func, "H5Dget_type failed");
|
||||
}
|
||||
|
||||
// Get the data type's size
|
||||
hid_t native_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT);
|
||||
if (native_type < 0)
|
||||
{
|
||||
throw DataSetIException(func, "H5Tget_native_type failed");
|
||||
}
|
||||
size_t type_size = H5Tget_size(native_type);
|
||||
if (type_size == 0)
|
||||
{
|
||||
throw DataSetIException(func, "H5Tget_size failed");
|
||||
}
|
||||
|
||||
// Get number of elements of the dataset
|
||||
hid_t space_id = H5Dget_space(id); // first get its data space
|
||||
if (space_id < 0)
|
||||
{
|
||||
throw DataSetIException(func, "H5Dget_space failed");
|
||||
}
|
||||
hssize_t num_elements = H5Sget_simple_extent_npoints(space_id);
|
||||
if (num_elements < 0)
|
||||
{
|
||||
throw DataSetIException(func, "H5Sget_simple_extent_npoints failed");
|
||||
}
|
||||
|
||||
// Calculate and return the size of the data
|
||||
size_t data_size = type_size * num_elements;
|
||||
return(data_size);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Function: DataSet::getOffset
|
||||
///\brief Returns the address of this dataset in the file.
|
||||
@@ -364,20 +412,45 @@ void DataSet::read( void* buf, const DataType& mem_type, const DataSpace& mem_sp
|
||||
// Function: DataSet::read
|
||||
///\brief This is an overloaded member function, provided for convenience.
|
||||
/// It takes a reference to a \c std::string for the buffer.
|
||||
///\param buf - IN: Buffer for read data
|
||||
///\param mem_type - IN: Memory datatype
|
||||
///\param mem_space - IN: Memory dataspace
|
||||
///\param file_space - IN: Dataset's dataspace in the file
|
||||
///\param xfer_plist - IN: Transfer property list for this I/O operation
|
||||
///\exception H5::DataSetIException
|
||||
// Programmer Binh-Minh Ribler - 2000
|
||||
// Modification
|
||||
// Jul 2009
|
||||
// Follow the change to Attribute::read and use the following
|
||||
// private functions to read datasets with fixed- and
|
||||
// variable-length string:
|
||||
// DataSet::p_read_fixed_len and
|
||||
// DataSet::p_read_variable_len
|
||||
//--------------------------------------------------------------------------
|
||||
void DataSet::read( H5std_string& strg, const DataType& mem_type, const DataSpace& mem_space, const DataSpace& file_space, const DSetMemXferPropList& xfer_plist ) const
|
||||
void DataSet::read(H5std_string& strg, const DataType& mem_type, const DataSpace& mem_space, const DataSpace& file_space, const DSetMemXferPropList& xfer_plist) const
|
||||
{
|
||||
// Allocate C character string for reading
|
||||
size_t size = mem_type.getSize();
|
||||
char* strg_C = new char[size+1]; // temporary C-string for C API
|
||||
// Check if this dataset has variable-len string or fixed-len string and
|
||||
// proceed appropriately.
|
||||
htri_t is_variable_len = H5Tis_variable_str(mem_type.getId());
|
||||
if (is_variable_len < 0)
|
||||
{
|
||||
throw DataSetIException("DataSet::read", "H5Tis_variable_str failed");
|
||||
}
|
||||
|
||||
// Use the overloaded member to read
|
||||
read(strg_C, mem_type, mem_space, file_space, xfer_plist);
|
||||
// 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();
|
||||
|
||||
// Get the String and clean up
|
||||
strg = strg_C;
|
||||
delete []strg_C;
|
||||
if (!is_variable_len) // only allocate for fixed-len string
|
||||
{
|
||||
p_read_fixed_len(mem_type_id, mem_space_id, file_space_id, xfer_plist_id, strg);
|
||||
}
|
||||
else
|
||||
{
|
||||
p_read_variable_len(mem_type_id, mem_space_id, file_space_id, xfer_plist_id, strg);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -416,15 +489,46 @@ void DataSet::write( const void* buf, const DataType& mem_type, const DataSpace&
|
||||
///\brief This is an overloaded member function, provided for convenience.
|
||||
/// It takes a reference to a \c std::string for the buffer.
|
||||
// Programmer Binh-Minh Ribler - 2000
|
||||
// Modification
|
||||
// Jul 2009
|
||||
// Modified to pass the buffer into H5Dwrite properly depending
|
||||
// whether the dataset has variable- or fixed-length string.
|
||||
//--------------------------------------------------------------------------
|
||||
void DataSet::write( const H5std_string& strg, const DataType& mem_type, const DataSpace& mem_space, const DataSpace& file_space, const DSetMemXferPropList& xfer_plist ) const
|
||||
{
|
||||
// Convert string to C-string
|
||||
const char* strg_C;
|
||||
strg_C = strg.c_str(); // strg_C refers to the contents of strg as a C-str
|
||||
// Check if this attribute has variable-len string or fixed-len string and
|
||||
// proceed appropriately.
|
||||
htri_t is_variable_len = H5Tis_variable_str(mem_type.getId());
|
||||
if (is_variable_len < 0)
|
||||
{
|
||||
throw DataSetIException("DataSet::write", "H5Tis_variable_str failed");
|
||||
}
|
||||
|
||||
// Use the overloaded member
|
||||
write(strg_C, mem_type, mem_space, file_space, xfer_plist);
|
||||
// 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();
|
||||
|
||||
// Convert string to C-string
|
||||
const char* strg_C;
|
||||
strg_C = strg.c_str(); // strg_C refers to the contents of strg as a C-str
|
||||
herr_t ret_value = 0;
|
||||
|
||||
// Pass string in differently depends on variable or fixed length
|
||||
if (!is_variable_len)
|
||||
{
|
||||
ret_value = H5Dwrite( id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, strg_C );
|
||||
}
|
||||
else
|
||||
{
|
||||
// passing string argument by address
|
||||
ret_value = H5Dwrite( id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, &strg_C );
|
||||
}
|
||||
if (ret_value < 0)
|
||||
{
|
||||
throw DataSetIException("DataSet::write", "H5Dwrite failed");
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -586,7 +690,74 @@ hid_t DataSet::getId() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Function: DataSet::p_setId
|
||||
// Function: DataSet::p_read_fixed_len (private)
|
||||
// brief Reads a fixed length \a H5std_string from an dataset.
|
||||
// param mem_type - IN: DataSet datatype (in memory)
|
||||
// param strg - IN: Buffer for read string
|
||||
// exception H5::DataSetIException
|
||||
// Programmer Binh-Minh Ribler - Jul, 2009
|
||||
// Modification
|
||||
// Jul 2009
|
||||
// Added in follow to the change in Attribute::read
|
||||
//--------------------------------------------------------------------------
|
||||
void DataSet::p_read_fixed_len(const hid_t mem_type_id, const hid_t mem_space_id, const hid_t file_space_id, const hid_t xfer_plist_id, H5std_string& strg) const
|
||||
{
|
||||
// Only allocate for fixed-len string.
|
||||
|
||||
// Get the size of the dataset's data
|
||||
size_t attr_size = getInMemDataSize();
|
||||
|
||||
// If there is data, allocate buffer and read it.
|
||||
if (attr_size > 0)
|
||||
{
|
||||
char *strg_C = NULL;
|
||||
|
||||
strg_C = new char [(size_t)attr_size+1];
|
||||
herr_t ret_value = H5Dread(id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, strg_C);
|
||||
|
||||
if( ret_value < 0 )
|
||||
{
|
||||
delete []strg_C; // de-allocate for fixed-len string
|
||||
throw DataSetIException("DataSet::read", "H5Dread failed for fixed length string");
|
||||
}
|
||||
|
||||
// Get string from the C char* and release resource allocated locally
|
||||
strg = strg_C;
|
||||
delete []strg_C;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Function: DataSet::p_read_variable_len (private)
|
||||
// brief Reads a variable length \a H5std_string from an dataset.
|
||||
// param mem_type - IN: DataSet datatype (in memory)
|
||||
// param strg - IN: Buffer for read string
|
||||
// exception H5::DataSetIException
|
||||
// Programmer Binh-Minh Ribler - Jul, 2009
|
||||
// Modification
|
||||
// Jul 2009
|
||||
// Added in follow to the change in Attribute::read
|
||||
//--------------------------------------------------------------------------
|
||||
void DataSet::p_read_variable_len(const hid_t mem_type_id, const hid_t mem_space_id, const hid_t file_space_id, const hid_t xfer_plist_id, H5std_string& strg) const
|
||||
{
|
||||
// Prepare and call C API to read dataset.
|
||||
char *strg_C;
|
||||
|
||||
// Read dataset, no allocation for variable-len string; C library will
|
||||
herr_t ret_value = H5Dread(id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, &strg_C);
|
||||
|
||||
if( ret_value < 0 )
|
||||
{
|
||||
throw DataSetIException("DataSet::read", "H5Dread failed for variable length string");
|
||||
}
|
||||
|
||||
// Get string from the C char* and release resource allocated by C API
|
||||
strg = strg_C;
|
||||
HDfree(strg_C);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Function: DataSet::p_setId (private)
|
||||
///\brief Sets the identifier of this object to a new value.
|
||||
///
|
||||
///\exception H5::IdComponentException when the attempt to close the HDF5
|
||||
|
||||
Reference in New Issue
Block a user