~ubuntu-branches/ubuntu/quantal/xdmf/quantal

« back to all changes in this revision

Viewing changes to Utilities/hdf5/H5Defl.c

  • Committer: Bazaar Package Importer
  • Author(s): Alastair McKinstry
  • Date: 2011-07-09 10:33:32 UTC
  • Revision ID: james.westby@ubuntu.com-20110709103332-2w36cerw7215fzoe
Tags: upstream-2.1.dfsg.1
ImportĀ upstreamĀ versionĀ 2.1.dfsg.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
2
 * Copyright by the Board of Trustees of the University of Illinois.         *
 
3
 * All rights reserved.                                                      *
 
4
 *                                                                           *
 
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
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
14
 
 
15
/*
 
16
 * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
 
17
 *         Thursday, September 30, 2004
 
18
 */
 
19
 
 
20
#define H5D_PACKAGE    /*suppress error about including H5Dpkg    */
 
21
 
 
22
#include "H5private.h"    /* Generic Functions      */
 
23
#include "H5Dpkg.h"    /* Datasets        */
 
24
#include "H5Eprivate.h"    /* Error handling        */
 
25
#include "H5Fprivate.h"    /* Files        */
 
26
 
 
27
/* PRIVATE PROTOTYPES */
 
28
static herr_t H5D_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size,
 
29
    uint8_t *buf);
 
30
static herr_t H5D_efl_write(const H5O_efl_t *efl, haddr_t addr, size_t size,
 
31
    const uint8_t *buf);
 
32
 
 
33
 
 
34
/*-------------------------------------------------------------------------
 
35
 * Function:  H5D_efl_read
 
36
 *
 
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
 
40
 *    zeros.
 
41
 *
 
42
 * Return:  Non-negative on success/Negative on failure
 
43
 *
 
44
 * Programmer:  Robb Matzke
 
45
 *              Wednesday, March  4, 1998
 
46
 *
 
47
 * Modifications:
 
48
 *    Robb Matzke, 1999-07-28
 
49
 *    The ADDR argument is passed by value.
 
50
 *-------------------------------------------------------------------------
 
51
 */
 
52
static herr_t
 
53
H5D_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size, uint8_t *buf)
 
54
{
 
55
    int    fd=-1;
 
56
    size_t  to_read;
 
57
#ifndef NDEBUG
 
58
    hsize_t     tempto_read;
 
59
#endif /* NDEBUG */
 
60
    hsize_t     skip=0;
 
61
    haddr_t     cur;
 
62
    ssize_t  n;
 
63
    size_t      u;                      /* Local index variable */
 
64
    herr_t      ret_value=SUCCEED;       /* Return value */
 
65
 
 
66
    FUNC_ENTER_NOAPI_NOINIT(H5D_efl_read)
 
67
 
 
68
    /* Check args */
 
69
    assert (efl && efl->nused>0);
 
70
    assert (H5F_addr_defined (addr));
 
71
    assert (size < SIZET_MAX);
 
72
    assert (buf || 0==size);
 
73
 
 
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) {
 
77
      skip = addr - cur;
 
78
      break;
 
79
  }
 
80
    cur += efl->slot[u].size;
 
81
    }
 
82
 
 
83
    /* Read the data */
 
84
    while (size) {
 
85
        assert(buf);
 
86
  if (u>=efl->nused)
 
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")
 
94
#ifndef NDEBUG
 
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;
 
98
#else /* NDEBUG */
 
99
  to_read = MIN((size_t)(efl->slot[u].size-skip), size);
 
100
#endif /* NDEBUG */
 
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);
 
105
  }
 
106
  HDclose (fd);
 
107
  fd = -1;
 
108
  size -= to_read;
 
109
  buf += to_read;
 
110
  skip = 0;
 
111
  u++;
 
112
    }
 
113
 
 
114
done:
 
115
    if (fd>=0)
 
116
        HDclose (fd);
 
117
 
 
118
    FUNC_LEAVE_NOAPI(ret_value)
 
119
}
 
120
 
 
121
 
 
122
/*-------------------------------------------------------------------------
 
123
 * Function:  H5D_efl_write
 
124
 *
 
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
 
128
 *    extends that file.
 
129
 *
 
130
 * Return:  Non-negative on success/Negative on failure
 
131
 *
 
132
 * Programmer:  Robb Matzke
 
133
 *              Wednesday, March  4, 1998
 
134
 *
 
135
 * Modifications:
 
136
 *    Robb Matzke, 1999-07-28
 
137
 *    The ADDR argument is passed by value.
 
138
 *-------------------------------------------------------------------------
 
139
 */
 
140
static herr_t
 
141
H5D_efl_write (const H5O_efl_t *efl, haddr_t addr, size_t size, const uint8_t *buf)
 
142
{
 
143
    int    fd=-1;
 
144
    size_t  to_write;
 
145
#ifndef NDEBUG
 
146
    hsize_t  tempto_write;
 
147
#endif /* NDEBUG */
 
148
    haddr_t     cur;
 
149
    hsize_t     skip=0;
 
150
    size_t  u;                      /* Local index variable */
 
151
    herr_t      ret_value=SUCCEED;       /* Return value */
 
152
 
 
153
    FUNC_ENTER_NOAPI_NOINIT(H5D_efl_write)
 
154
 
 
155
    /* Check args */
 
156
    assert (efl && efl->nused>0);
 
157
    assert (H5F_addr_defined (addr));
 
158
    assert (size < SIZET_MAX);
 
159
    assert (buf || 0==size);
 
160
 
 
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) {
 
164
      skip = addr - cur;
 
165
      break;
 
166
  }
 
167
  cur += efl->slot[u].size;
 
168
    }
 
169
 
 
170
    /* Write the data */
 
171
    while (size) {
 
172
        assert(buf);
 
173
  if (u>=efl->nused)
 
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")
 
180
      } else {
 
181
    HGOTO_ERROR (H5E_EFL, H5E_CANTOPENFILE, FAIL, "unable to open external raw data file")
 
182
      }
 
183
  }
 
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")
 
186
#ifndef NDEBUG
 
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;
 
190
#else /* NDEBUG */
 
191
  to_write = MIN((size_t)(efl->slot[u].size-skip), size);
 
192
#endif /* NDEBUG */
 
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")
 
195
  HDclose (fd);
 
196
  fd = -1;
 
197
  size -= to_write;
 
198
  buf += to_write;
 
199
  skip = 0;
 
200
  u++;
 
201
    }
 
202
 
 
203
done:
 
204
    if (fd>=0)
 
205
        HDclose (fd);
 
206
 
 
207
    FUNC_LEAVE_NOAPI(ret_value)
 
208
}
 
209
 
 
210
 
 
211
/*-------------------------------------------------------------------------
 
212
 * Function:  H5D_efl_readvv
 
213
 *
 
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
 
217
 *    zeros.
 
218
 *
 
219
 * Return:  Non-negative on success/Negative on failure
 
220
 *
 
221
 * Programmer:  Quincey Koziol
 
222
 *              Wednesday, May  7, 2003
 
223
 *
 
224
 * Modifications:
 
225
 *
 
226
 *-------------------------------------------------------------------------
 
227
 */
 
228
ssize_t
 
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[],
 
232
    void *_buf)
 
233
{
 
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 */
 
242
 
 
243
    FUNC_ENTER_NOAPI(H5D_efl_readvv, FAIL)
 
244
 
 
245
    /* Check args */
 
246
    assert (efl && efl->nused>0);
 
247
    assert (_buf);
 
248
 
 
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])
 
253
            size=mem_len_arr[v];
 
254
        else
 
255
            size=dset_len_arr[u];
 
256
 
 
257
        /* Compute offset on disk */
 
258
        addr=dset_offset_arr[u];
 
259
 
 
260
        /* Compute offset in memory */
 
261
        buf = (unsigned char *)_buf + mem_offset_arr[v];
 
262
 
 
263
        /* Read data */
 
264
        if (H5D_efl_read(efl, addr, size, buf)<0)
 
265
            HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
 
266
 
 
267
        /* Update memory information */
 
268
        mem_len_arr[v]-=size;
 
269
        mem_offset_arr[v]+=size;
 
270
        if(mem_len_arr[v]==0)
 
271
            v++;
 
272
 
 
273
        /* Update file information */
 
274
        dset_len_arr[u]-=size;
 
275
        dset_offset_arr[u]+=size;
 
276
        if(dset_len_arr[u]==0)
 
277
            u++;
 
278
 
 
279
        /* Increment number of bytes copied */
 
280
        total_size+=size;
 
281
    } /* end for */
 
282
 
 
283
    /* Update current sequence vectors */
 
284
    *dset_curr_seq=u;
 
285
    *mem_curr_seq=v;
 
286
 
 
287
    /* Set return value */
 
288
    H5_ASSIGN_OVERFLOW(ret_value,total_size,size_t,ssize_t);
 
289
 
 
290
done:
 
291
    FUNC_LEAVE_NOAPI(ret_value)
 
292
} /* end H5D_efl_readvv() */
 
293
 
 
294
 
 
295
/*-------------------------------------------------------------------------
 
296
 * Function:  H5D_efl_writevv
 
297
 *
 
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
 
301
 *    extends that file.
 
302
 *
 
303
 * Return:  Non-negative on success/Negative on failure
 
304
 *
 
305
 * Programmer:  Quincey Koziol
 
306
 *              Friday, May  2, 2003
 
307
 *
 
308
 * Modifications:
 
309
 *
 
310
 *-------------------------------------------------------------------------
 
311
 */
 
312
ssize_t
 
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[],
 
316
    const void *_buf)
 
317
{
 
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 */
 
326
 
 
327
    FUNC_ENTER_NOAPI(H5D_efl_writevv, FAIL)
 
328
 
 
329
    /* Check args */
 
330
    assert (efl && efl->nused>0);
 
331
    assert (_buf);
 
332
 
 
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])
 
337
            size=mem_len_arr[v];
 
338
        else
 
339
            size=dset_len_arr[u];
 
340
 
 
341
        /* Compute offset on disk */
 
342
        addr=dset_offset_arr[u];
 
343
 
 
344
        /* Compute offset in memory */
 
345
        buf = (const unsigned char *)_buf + mem_offset_arr[v];
 
346
 
 
347
        /* Write data */
 
348
        if (H5D_efl_write(efl, addr, size, buf)<0)
 
349
            HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
 
350
 
 
351
        /* Update memory information */
 
352
        mem_len_arr[v]-=size;
 
353
        mem_offset_arr[v]+=size;
 
354
        if(mem_len_arr[v]==0)
 
355
            v++;
 
356
 
 
357
        /* Update file information */
 
358
        dset_len_arr[u]-=size;
 
359
        dset_offset_arr[u]+=size;
 
360
        if(dset_len_arr[u]==0)
 
361
            u++;
 
362
 
 
363
        /* Increment number of bytes copied */
 
364
        total_size+=size;
 
365
    } /* end for */
 
366
 
 
367
    /* Update current sequence vectors */
 
368
    *dset_curr_seq=u;
 
369
    *mem_curr_seq=v;
 
370
 
 
371
    /* Set return value */
 
372
    H5_ASSIGN_OVERFLOW(ret_value,total_size,size_t,ssize_t);
 
373
 
 
374
done:
 
375
    FUNC_LEAVE_NOAPI(ret_value)
 
376
} /* end H5D_efl_writevv() */
 
377