summaryrefslogtreecommitdiffstats
path: root/c++/src/H5DataSet.cpp
blob: 84bed5c333f1e72ffad126e31370a54a6b191f89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * Copyright by the Board of Trustees of the University of Illinois.         *
  * All rights reserved.                                                      *
  *                                                                           *
  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
  * terms governing use, modification, and redistribution, is contained in    *
  * the files COPYING and Copyright.html.  COPYING can be found at the root   *
  * of the source code distribution tree; Copyright.html can be found at the  *
  * root level of an installed copy of the electronic HDF5 document set and   *
  * is linked from the top-level documents page.  It can also be found at     *
  * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html.  If you do not have     *
  * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include <string>
#ifdef OLD_HEADER_FILENAME
#include <iostream.h>
#else
#include <iostream>
#endif

#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("DataSet::getSpace", "H5Dget_space failed");
   }
   //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(0, "H5Dget_type failed");
   }
}

// 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("DataSet::getCreatePlist", "H5Dget_create_plist failed");
   }
   // 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 )  // checking with Quincey for failure value - BMR
      return( storage_size );
   else
   {
      throw DataSetIException("DataSet::getStorageSize", "H5Dget_storage_size failed");
   }
}

// Returns the number of bytes required to store VL data.
hsize_t DataSet::getVlenBufSize( DataType& type, DataSpace& space ) const
{
   // Obtain identifiers for C API
   //hid_t type_id = type.getId();
   //hid_t space_id = space.getId();
   //hsize_t size;

   //herr_t ret_value = H5Dget_vlen_buf_size( id, type_id, space_id, &size );
   //if( ret_value >= 0 )
   //   return( size );
   //else
   //{
      //throw DataSetIException();
   //}
   throw DataSetIException( "DataSet::getVlenBufSize", 
		"Currently not implemented yet.");
   return (0);
}

// Reclaims VL datatype memory buffers. 
void DataSet::vlenReclaim( DataType& type, DataSpace& space, DSetMemXferPropList& xfer_plist, void* buf ) const
{
   // 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();

   herr_t ret_value = H5Dvlen_reclaim( type_id, space_id, xfer_plist_id, buf );
   if( ret_value < 0 )
   {
      throw DataSetIException("DataSet::vlenReclaim", "H5Dvlen_reclaim failed");
   }
}

// 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("DataSet::read", "H5Dread failed");
   }
}

void DataSet::read( 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

   // Use the overloaded member to read
   read(strg_C, mem_type, mem_space, file_space, xfer_plist);

   // Get the String and clean up
   strg = strg_C;
   delete strg_C;
}

// 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("DataSet::write", "H5Dwrite failed");
   }
}

void DataSet::write( const 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

   // Use the overloaded member
   write(strg_C, mem_type, mem_space, file_space, xfer_plist);
}

// 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("DataSet::iterateElems", "H5Diterate failed");
   }
}

// 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("DataSet::extend", "H5Dextend failed");
   }
}

/*--------------------------------------------------------------------------
 NAME
    fillMemBuf
 PURPOSE 
    Fills a selection in memory with a value
 USAGE
    fillMemBuf(fill, fill_type, buf, buf_type, space)
    fillMemBuf(buf, buf_type, space)
        void *buf;              IN/OUT: Memory buffer to fill selection within
        DataType& buf_type;     IN: Datatype of the elements in buffer
        DataSpace& space;       IN: Dataspace describing memory buffer &
                                    containing selection to use.
        const void *fill;       IN: Pointer to fill value to use - default NULL
        DataType& fill_type;    IN: Datatype of the fill value
 DESCRIPTION
    Use the selection in the dataspace to fill elements in a memory buffer.
 COMMENTS, BUGS, ASSUMPTIONS
    Second usage uses all zeros as fill value
--------------------------------------------------------------------------*/
void DataSet::fillMemBuf(const void *fill, DataType& fill_type, void *buf, DataType& buf_type, DataSpace& space)
{
    hid_t fill_type_id = fill_type.getId();
    hid_t buf_type_id = buf_type.getId();
    hid_t space_id = space.getId();
    herr_t ret_value = H5Dfill(fill, fill_type_id, buf, buf_type_id, space_id);
    if( ret_value < 0 )
    {
	throw DataSetIException("DataSet::fillMemBuf", "H5Dfill failed");
    }
}
void DataSet::fillMemBuf(void *buf, DataType& buf_type, DataSpace& space)
{
    hid_t buf_type_id = buf_type.getId();
    hid_t space_id = space.getId();
    herr_t ret_value = H5Dfill(NULL, buf_type_id, buf, buf_type_id, space_id);
    if( ret_value < 0 )
    {
	throw DataSetIException("DataSet::fillMemBuf", "H5Dfill failed");
    }
}

// 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(0, "H5Dclose failed");
   }
}

// 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 
    try {
	resetIdComponent( this ); }
    catch (Exception close_error) { // thrown by p_close
        cerr << "DataSet::~DataSet - " << close_error.getDetailMsg() << endl;
    }
}

#ifndef H5_NO_NAMESPACE
} // end namespace
#endif