1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Copyright by the Board of Trustees of the University of Illinois. *
3
* All rights reserved. *
5
* This file is part of HDF5. The full HDF5 copyright notice, including *
6
* terms governing use, modification, and redistribution, is contained in *
7
* the files COPYING and Copyright.html. COPYING can be found at the root *
8
* of the source code distribution tree; Copyright.html can be found at the *
9
* root level of an installed copy of the electronic HDF5 document set and *
10
* is linked from the top-level documents page. It can also be found at *
11
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
12
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
13
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16
* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
17
* Thursday, September 30, 2004
20
#define H5D_PACKAGE /*suppress error about including H5Dpkg */
22
#include "H5private.h" /* Generic Functions */
23
#include "H5Dpkg.h" /* Datasets */
24
#include "H5Eprivate.h" /* Error handling */
25
#include "H5Fprivate.h" /* Files */
27
/* PRIVATE PROTOTYPES */
28
static herr_t H5D_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size,
30
static herr_t H5D_efl_write(const H5O_efl_t *efl, haddr_t addr, size_t size,
34
/*-------------------------------------------------------------------------
35
* Function: H5D_efl_read
37
* Purpose: Reads data from an external file list. It is an error to
38
* read past the logical end of file, but reading past the end
39
* of any particular member of the external file list results in
42
* Return: Non-negative on success/Negative on failure
44
* Programmer: Robb Matzke
45
* Wednesday, March 4, 1998
48
* Robb Matzke, 1999-07-28
49
* The ADDR argument is passed by value.
50
*-------------------------------------------------------------------------
53
H5D_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size, uint8_t *buf)
63
size_t u; /* Local index variable */
64
herr_t ret_value=SUCCEED; /* Return value */
66
FUNC_ENTER_NOAPI_NOINIT(H5D_efl_read)
69
assert (efl && efl->nused>0);
70
assert (H5F_addr_defined (addr));
71
assert (size < SIZET_MAX);
72
assert (buf || 0==size);
74
/* Find the first efl member from which to read */
75
for (u=0, cur=0; u<efl->nused; u++) {
76
if (H5O_EFL_UNLIMITED==efl->slot[u].size || addr < cur+efl->slot[u].size) {
80
cur += efl->slot[u].size;
87
HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "read past logical end of file")
88
if (H5F_OVERFLOW_HSIZET2OFFT (efl->slot[u].offset+skip))
89
HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "external file address overflowed")
90
if ((fd=HDopen (efl->slot[u].name, O_RDONLY, 0))<0)
91
HGOTO_ERROR (H5E_EFL, H5E_CANTOPENFILE, FAIL, "unable to open external raw data file")
92
if (HDlseek (fd, (off_t)(efl->slot[u].offset+skip), SEEK_SET)<0)
93
HGOTO_ERROR (H5E_EFL, H5E_SEEKERROR, FAIL, "unable to seek in external raw data file")
95
tempto_read = MIN(efl->slot[u].size-skip,(hsize_t)size);
96
H5_CHECK_OVERFLOW(tempto_read,hsize_t,size_t);
97
to_read = (size_t)tempto_read;
99
to_read = MIN((size_t)(efl->slot[u].size-skip), size);
101
if ((n=HDread (fd, buf, to_read))<0) {
102
HGOTO_ERROR (H5E_EFL, H5E_READERROR, FAIL, "read error in external raw data file")
103
} else if ((size_t)n<to_read) {
104
HDmemset (buf+n, 0, to_read-n);
118
FUNC_LEAVE_NOAPI(ret_value)
122
/*-------------------------------------------------------------------------
123
* Function: H5D_efl_write
125
* Purpose: Writes data to an external file list. It is an error to
126
* write past the logical end of file, but writing past the end
127
* of any particular member of the external file list just
130
* Return: Non-negative on success/Negative on failure
132
* Programmer: Robb Matzke
133
* Wednesday, March 4, 1998
136
* Robb Matzke, 1999-07-28
137
* The ADDR argument is passed by value.
138
*-------------------------------------------------------------------------
141
H5D_efl_write (const H5O_efl_t *efl, haddr_t addr, size_t size, const uint8_t *buf)
146
hsize_t tempto_write;
150
size_t u; /* Local index variable */
151
herr_t ret_value=SUCCEED; /* Return value */
153
FUNC_ENTER_NOAPI_NOINIT(H5D_efl_write)
156
assert (efl && efl->nused>0);
157
assert (H5F_addr_defined (addr));
158
assert (size < SIZET_MAX);
159
assert (buf || 0==size);
161
/* Find the first efl member in which to write */
162
for (u=0, cur=0; u<efl->nused; u++) {
163
if (H5O_EFL_UNLIMITED==efl->slot[u].size || addr < cur+efl->slot[u].size) {
167
cur += efl->slot[u].size;
174
HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "write past logical end of file")
175
if (H5F_OVERFLOW_HSIZET2OFFT (efl->slot[u].offset+skip))
176
HGOTO_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, "external file address overflowed")
177
if ((fd=HDopen (efl->slot[u].name, O_CREAT|O_RDWR, 0666))<0) {
178
if (HDaccess (efl->slot[u].name, F_OK)<0) {
179
HGOTO_ERROR (H5E_EFL, H5E_CANTOPENFILE, FAIL, "external raw data file does not exist")
181
HGOTO_ERROR (H5E_EFL, H5E_CANTOPENFILE, FAIL, "unable to open external raw data file")
184
if (HDlseek (fd, (off_t)(efl->slot[u].offset+skip), SEEK_SET)<0)
185
HGOTO_ERROR (H5E_EFL, H5E_SEEKERROR, FAIL, "unable to seek in external raw data file")
187
tempto_write = MIN(efl->slot[u].size-skip,(hsize_t)size);
188
H5_CHECK_OVERFLOW(tempto_write,hsize_t,size_t);
189
to_write = (size_t)tempto_write;
191
to_write = MIN((size_t)(efl->slot[u].size-skip), size);
193
if ((size_t)HDwrite (fd, buf, to_write)!=to_write)
194
HGOTO_ERROR (H5E_EFL, H5E_READERROR, FAIL, "write error in external raw data file")
207
FUNC_LEAVE_NOAPI(ret_value)
211
/*-------------------------------------------------------------------------
212
* Function: H5D_efl_readvv
214
* Purpose: Reads data from an external file list. It is an error to
215
* read past the logical end of file, but reading past the end
216
* of any particular member of the external file list results in
219
* Return: Non-negative on success/Negative on failure
221
* Programmer: Quincey Koziol
222
* Wednesday, May 7, 2003
226
*-------------------------------------------------------------------------
229
H5D_efl_readvv(const H5D_io_info_t *io_info,
230
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
231
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
234
const H5O_efl_t *efl=&(io_info->store->efl); /* Pointer to efl info */
235
unsigned char *buf; /* Pointer to buffer to write */
236
haddr_t addr; /* Actual address to read */
237
size_t total_size=0; /* Total size of sequence in bytes */
238
size_t size; /* Size of sequence in bytes */
239
size_t u; /* Counting variable */
240
size_t v; /* Counting variable */
241
ssize_t ret_value; /* Return value */
243
FUNC_ENTER_NOAPI(H5D_efl_readvv, FAIL)
246
assert (efl && efl->nused>0);
249
/* Work through all the sequences */
250
for(u=*dset_curr_seq, v=*mem_curr_seq; u<dset_max_nseq && v<mem_max_nseq; ) {
251
/* Choose smallest buffer to write */
252
if(mem_len_arr[v]<dset_len_arr[u])
255
size=dset_len_arr[u];
257
/* Compute offset on disk */
258
addr=dset_offset_arr[u];
260
/* Compute offset in memory */
261
buf = (unsigned char *)_buf + mem_offset_arr[v];
264
if (H5D_efl_read(efl, addr, size, buf)<0)
265
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
267
/* Update memory information */
268
mem_len_arr[v]-=size;
269
mem_offset_arr[v]+=size;
270
if(mem_len_arr[v]==0)
273
/* Update file information */
274
dset_len_arr[u]-=size;
275
dset_offset_arr[u]+=size;
276
if(dset_len_arr[u]==0)
279
/* Increment number of bytes copied */
283
/* Update current sequence vectors */
287
/* Set return value */
288
H5_ASSIGN_OVERFLOW(ret_value,total_size,size_t,ssize_t);
291
FUNC_LEAVE_NOAPI(ret_value)
292
} /* end H5D_efl_readvv() */
295
/*-------------------------------------------------------------------------
296
* Function: H5D_efl_writevv
298
* Purpose: Writes data to an external file list. It is an error to
299
* write past the logical end of file, but writing past the end
300
* of any particular member of the external file list just
303
* Return: Non-negative on success/Negative on failure
305
* Programmer: Quincey Koziol
306
* Friday, May 2, 2003
310
*-------------------------------------------------------------------------
313
H5D_efl_writevv(const H5D_io_info_t *io_info,
314
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
315
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
318
const H5O_efl_t *efl=&(io_info->store->efl); /* Pointer to efl info */
319
const unsigned char *buf; /* Pointer to buffer to write */
320
haddr_t addr; /* Actual address to read */
321
size_t total_size=0; /* Total size of sequence in bytes */
322
size_t size; /* Size of sequence in bytes */
323
size_t u; /* Counting variable */
324
size_t v; /* Counting variable */
325
ssize_t ret_value; /* Return value */
327
FUNC_ENTER_NOAPI(H5D_efl_writevv, FAIL)
330
assert (efl && efl->nused>0);
333
/* Work through all the sequences */
334
for(u=*dset_curr_seq, v=*mem_curr_seq; u<dset_max_nseq && v<mem_max_nseq; ) {
335
/* Choose smallest buffer to write */
336
if(mem_len_arr[v]<dset_len_arr[u])
339
size=dset_len_arr[u];
341
/* Compute offset on disk */
342
addr=dset_offset_arr[u];
344
/* Compute offset in memory */
345
buf = (const unsigned char *)_buf + mem_offset_arr[v];
348
if (H5D_efl_write(efl, addr, size, buf)<0)
349
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
351
/* Update memory information */
352
mem_len_arr[v]-=size;
353
mem_offset_arr[v]+=size;
354
if(mem_len_arr[v]==0)
357
/* Update file information */
358
dset_len_arr[u]-=size;
359
dset_offset_arr[u]+=size;
360
if(dset_len_arr[u]==0)
363
/* Increment number of bytes copied */
367
/* Update current sequence vectors */
371
/* Set return value */
372
H5_ASSIGN_OVERFLOW(ret_value,total_size,size_t,ssize_t);
375
FUNC_LEAVE_NOAPI(ret_value)
376
} /* end H5D_efl_writevv() */