~ubuntu-branches/ubuntu/natty/pytables/natty-updates

« back to all changes in this revision

Viewing changes to src/utils.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2006-06-28 10:45:03 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20060628104503-cc251q5o5j3e2k10
  * Fixed call to pyversions in debian/rules which failed on recent versions 
    of pyversions
  * Fixed clean rule in debian/rules which left the stamp files behind
  * Acknowledge NMU
  * Added Alexandre Fayolle to uploaders

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
#include "version.h"
5
5
#include "H5Zlzo.h"                    /* Import FILTER_LZO */
6
6
#include "H5Zucl.h"                    /* Import FILTER_UCL */
7
 
 
8
 
 
9
 
/*-------------------------------------------------------------------------
10
 
 * 
11
 
 * Private functions
12
 
 * These are a replica of those in H5LT.c, but get_attribute_string_sys
13
 
 * needs them, so it is better to copy them here.
14
 
 * F. Alted 2004-04-20
15
 
 *
16
 
 *-------------------------------------------------------------------------
17
 
 */
18
 
 
19
 
herr_t _open_id( hid_t loc_id, 
20
 
                 const char *obj_name, 
21
 
                 int obj_type );
22
 
 
23
 
herr_t _close_id( hid_t obj_id,
24
 
                  int obj_type );
 
7
#include "H5Zbzip2.h"                  /* Import FILTER_BZIP2 */
 
8
 
 
9
 
 
10
/* ---------------------------------------------------------------- */
 
11
 
 
12
#ifdef WIN32
 
13
#include <windows.h>
 
14
 
 
15
/* This routine is meant to detect whether a dynamic library can be
 
16
   loaded on Windows. This is only way to detect its presence without
 
17
   harming the user.
 
18
*/
 
19
int getLibrary(char *libname) {
 
20
    HINSTANCE hinstLib;
 
21
 
 
22
    /* Load the dynamic library */
 
23
    hinstLib = LoadLibrary(TEXT(libname));
 
24
 
 
25
    if (hinstLib != NULL) {
 
26
      /* Free the dynamic library */
 
27
      FreeLibrary(hinstLib);
 
28
      return 0;
 
29
    }
 
30
    else {
 
31
      return -1;
 
32
    }
 
33
}
 
34
 
 
35
#else  /* Unix platforms */
 
36
#include <dlfcn.h>
 
37
 
 
38
/* Routine to detect the existance of shared libraries in UNIX. This
 
39
   has to be checked in MacOSX. However, this is not used right now in
 
40
   utilsExtension.pyx because UNIX does not complain when trying to
 
41
   load an extension library that depends on a shared library that it
 
42
   is not in the system (python raises just the ImportError). */
 
43
int getLibrary(char *libname) {
 
44
    void *hinstLib;
 
45
 
 
46
    /* Load the dynamic library */
 
47
    hinstLib = dlopen(libname, RTLD_LAZY);
 
48
 
 
49
    if (hinstLib != NULL) {
 
50
      /* Free the dynamic library */
 
51
      dlclose(hinstLib);
 
52
      return 0;
 
53
    }
 
54
    else {
 
55
      return -1;
 
56
    }
 
57
}
 
58
 
 
59
 
 
60
#endif  /* Win32 */
 
61
 
 
62
herr_t set_cache_size(hid_t file_id, size_t cache_size) {
 
63
  herr_t code;
 
64
 
 
65
  code = 0;
 
66
 
 
67
#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR >= 7
 
68
  H5AC_cache_config_t config;
 
69
 
 
70
  config.version = H5AC__CURR_CACHE_CONFIG_VERSION;
 
71
  code = H5Fget_mdc_config(file_id, &config);
 
72
  config.set_initial_size = TRUE;
 
73
  config.initial_size = cache_size;
 
74
/*   config.incr_mode = H5C_incr__off; */
 
75
/*   config.decr_mode = H5C_decr__off; */
 
76
/*   printf("Setting cache size to: %d\n", cache_size); */
 
77
  code = H5Fset_mdc_config(file_id, &config);
 
78
/*   printf("Return code for H5Fset_mdc_config: %d\n", code); */
 
79
 
 
80
#endif /* if H5_VERSION < "1.7" */
 
81
 
 
82
  return code;
 
83
 
 
84
}
25
85
 
26
86
PyObject *_getTablesVersion() {
27
87
  return PyString_FromString(PYTABLES_VERSION);
28
88
}
29
89
 
30
 
/* PyObject *getZLIBVersionInfo(void) { */
31
 
/*   long binver; */
32
 
/*   PyObject *t; */
33
 
 
34
 
/* #ifdef ZLIB_VERNUM           /\* Only available for zlib >= 1.2 *\/ */
35
 
/*   binver = ZLIB_VERNUM;      /\* This is not exactly the user's lib */
36
 
/*                                 version but that of the binary */
37
 
/*                                 packager version!  However, this */
38
 
/*                                 should be not too important *\/ */
39
 
/* #else */
40
 
/*   binver = 1;                        /\* For version of zlib < 1.2 *\/ */
41
 
/* #endif */
42
 
/*   t = PyTuple_New(2); */
43
 
/*   PyTuple_SetItem(t, 0, PyInt_FromLong(binver)); */
44
 
/*   PyTuple_SetItem(t, 1, PyString_FromString(zlibVersion())); */
45
 
/*   return t; */
46
 
/* } */
47
 
 
48
90
PyObject *getHDF5VersionInfo(void) {
49
91
  long binver;
50
92
  unsigned majnum, minnum, relnum;
75
117
/****************************************************************
76
118
**
77
119
**  createNamesTuple(): Create Python tuple from a string of *char.
78
 
** 
 
120
**
79
121
****************************************************************/
80
122
PyObject *createNamesTuple(char *buffer[], int nelements)
81
123
{
82
124
  int i;
83
125
  PyObject *t;
 
126
  PyObject *str;
84
127
 
85
128
  t = PyTuple_New(nelements);
86
 
  for (i = 0; i < nelements; i++) { 
87
 
    PyTuple_SetItem(t, i, PyString_FromString(buffer[i]) );
 
129
  for (i = 0; i < nelements; i++) {
 
130
    str = PyString_FromString(buffer[i]);
 
131
    PyTuple_SetItem(t, i, str);
 
132
    /* PyTuple_SetItem does not need a decref, because it already do this */
 
133
/*     Py_DECREF(str); */
88
134
  }
89
135
  return t;
90
136
}
93
139
{
94
140
  int i;
95
141
  PyObject *t;
 
142
  PyObject *str;
96
143
 
97
144
  t = PyList_New(nelements);
98
 
  for (i = 0; i < nelements; i++) { 
99
 
    PyList_SetItem(t, i, PyString_FromString(buffer[i]) );
 
145
  for (i = 0; i < nelements; i++) {
 
146
    str = PyString_FromString(buffer[i]);
 
147
    PyList_SetItem(t, i, str);
 
148
    /* PyList_SetItem does not need a decref, because it already do this */
 
149
/*     Py_DECREF(str); */
100
150
  }
101
151
  return t;
102
152
}
108
158
 *
109
159
 * Return: Success: 0, Failure: -1
110
160
 *
111
 
 * Programmer: Francesc Alted, falted@pytables.org
 
161
 * Programmer: Francesc Altet, faltet@carabos.com
112
162
 *
113
163
 * Date: December 19, 2003
114
164
 *
115
 
 * Comments: 
 
165
 * Comments:
116
166
 *
117
 
 * Modifications: 
 
167
 * Modifications:
118
168
 *
119
169
 *
120
170
 *-------------------------------------------------------------------------
121
171
 */
122
172
 
123
 
PyObject *get_filter_names( hid_t loc_id, 
 
173
PyObject *get_filter_names( hid_t loc_id,
124
174
                            const char *dset_name)
125
175
{
126
176
 hid_t    dset;
138
188
 
139
189
 /* Open the dataset. */
140
190
 if ( (dset = H5Dopen( loc_id, dset_name )) < 0 ) {
141
 
/*    Py_INCREF(Py_None);  */
142
 
/*    filters = Py_None;        /\* Not chunked, so return None *\/ */
143
191
   goto out;
144
192
 }
145
193
 
152
200
   if ((nf = H5Pget_nfilters(dcpl))>0) {
153
201
     for (i=0; i<nf; i++) {
154
202
       cd_nelmts = 20;
155
 
       /* 1.6.2 */
 
203
#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 7
 
204
       /* 1.6.x */
156
205
       filt_id = H5Pget_filter(dcpl, i, &filt_flags, &cd_nelmts,
157
206
                               cd_values, sizeof(f_name), f_name);
 
207
#else
158
208
       /* 1.7.x */
159
 
/*        filt_id = H5Pget_filter(dcpl, i, &filt_flags, &cd_nelmts, */
160
 
/*                             cd_values, sizeof(f_name), f_name, NULL); */
161
 
/*        printf("f_name--> %s\n", f_name); */
162
 
        /* This code has been added because a 
163
 
         bug in the H5Pget_filter call that
164
 
         returns a null string when DEFLATE filter is active */
165
 
       /* The problem seems to have been solved in 1.6.2 though */
166
 
        switch (filt_id) {
167
 
         case H5Z_FILTER_DEFLATE:
168
 
           strcpy(f_name, "deflate");
169
 
           break;
170
 
         case H5Z_FILTER_SHUFFLE:
171
 
           strcpy(f_name, "shuffle");
172
 
           break;
173
 
         case H5Z_FILTER_FLETCHER32:
174
 
           strcpy(f_name, "fletcher32");
175
 
           break;
176
 
         case H5Z_FILTER_SZIP:
177
 
           strcpy(f_name, "szip");
178
 
           break;
179
 
         case FILTER_LZO:
180
 
           strcpy(f_name, "lzo");
181
 
           break;
182
 
         case FILTER_UCL:
183
 
           strcpy(f_name, "ucl");
184
 
           break;
185
 
        }
186
 
        
 
209
       filt_id = H5Pget_filter(dcpl, i, &filt_flags, &cd_nelmts,
 
210
                               cd_values, sizeof(f_name), f_name, NULL);
 
211
#endif /* if H5_VERSION < "1.7" */
 
212
 
187
213
       filter_values = PyTuple_New(cd_nelmts);
188
214
       for (j=0;j<(long)cd_nelmts;j++) {
189
215
         PyTuple_SetItem(filter_values, j, PyInt_FromLong(cd_values[j]));
197
223
   Py_INCREF(Py_None);
198
224
   filters = Py_None;   /* Not chunked, so return None */
199
225
 }
200
 
 
 
226
 
201
227
 H5Pclose(dcpl);
202
228
 H5Dclose(dset);
203
229
 
213
239
/****************************************************************
214
240
**
215
241
**  gitercb(): Custom group iteration callback routine.
216
 
** 
 
242
**
217
243
****************************************************************/
218
244
herr_t gitercb(hid_t loc_id, const char *name, void *data) {
219
 
  PyObject **out_info=(PyObject **)data;
 
245
  PyObject   **out_info=(PyObject **)data;
 
246
  PyObject   *strname;
220
247
  herr_t     ret;            /* Generic return value         */
221
248
  H5G_stat_t statbuf;
222
249
 
226
253
    ret = H5Gget_objinfo(loc_id, name, FALSE, &statbuf);
227
254
/*     CHECK(ret, FAIL, "H5Gget_objinfo"); */
228
255
 
 
256
    strname = PyString_FromString(name);
229
257
    if (statbuf.type == H5G_GROUP) {
230
 
      PyList_Append(out_info[0], PyString_FromString(name));
 
258
      PyList_Append(out_info[0], strname);
231
259
    }
232
260
    else if (statbuf.type == H5G_DATASET) {
233
 
      PyList_Append(out_info[1], PyString_FromString(name));
 
261
      PyList_Append(out_info[1], strname);
234
262
    }
235
 
    
 
263
    Py_DECREF(strname);
 
264
 
236
265
    return(0);  /* Loop until no more objects remain in directory */
237
266
}
238
267
 
239
268
/****************************************************************
240
269
**
241
270
**  Giterate(): Group iteration routine.
242
 
** 
 
271
**
243
272
****************************************************************/
244
273
PyObject *Giterate(hid_t parent_id, hid_t loc_id, const char *name) {
245
274
  int i=0, ret;
263
292
/****************************************************************
264
293
**
265
294
**  aitercb(): Custom attribute iteration callback routine.
266
 
** 
 
295
**
267
296
****************************************************************/
268
297
static herr_t aitercb( hid_t loc_id, const char *name, void *op_data) {
 
298
  PyObject *strname;
269
299
 
 
300
  strname = PyString_FromString(name);
270
301
  /* Return the name of the attribute on op_data */
271
 
  PyList_Append(op_data, PyString_FromString(name));
 
302
  PyList_Append(op_data, strname);
 
303
  Py_DECREF(strname);
272
304
  return(0);    /* Loop until no more attrs remain in object */
273
 
 
305
}
274
306
 
275
307
 
276
308
/****************************************************************
277
309
**
278
310
**  Aiterate(): Attribute set iteration routine.
279
 
** 
 
311
**
280
312
****************************************************************/
281
313
PyObject *Aiterate(hid_t loc_id) {
282
314
  unsigned int i = 0;
293
325
/****************************************************************
294
326
**
295
327
**  getHDF5ClassID(): Returns class ID for loc_id.name. -1 if error.
296
 
** 
 
328
**
297
329
****************************************************************/
298
330
H5T_class_t getHDF5ClassID(hid_t loc_id,
299
331
                           const char *name,
300
 
                           H5D_layout_t *layout) {
301
 
   hid_t        dataset_id;  
302
 
   hid_t        type_id;
 
332
                           H5D_layout_t *layout,
 
333
                           hid_t *type_id,
 
334
                           hid_t *dataset_id) {
303
335
   H5T_class_t  class_id;
304
336
   hid_t        plist;
305
 
     
 
337
 
306
338
   /* Open the dataset. */
307
 
   if ( (dataset_id = H5Dopen( loc_id, name )) < 0 )
 
339
   if ( (*dataset_id = H5Dopen( loc_id, name )) < 0 )
308
340
     return -1;
309
 
   
 
341
 
310
342
   /* Get an identifier for the datatype. */
311
 
   type_id = H5Dget_type( dataset_id );
312
 
   
 
343
   *type_id = H5Dget_type( *dataset_id );
 
344
 
313
345
   /* Get the class. */
314
 
   class_id = H5Tget_class( type_id );
315
 
        
316
 
   /* Release the datatype. */
317
 
   if ( H5Tclose( type_id ) )
318
 
     return -1;
 
346
   class_id = H5Tget_class( *type_id );
319
347
 
320
348
   /* Get the layout of the datatype */
321
 
   plist = H5Dget_create_plist(dataset_id);
 
349
   plist = H5Dget_create_plist(*dataset_id);
322
350
   *layout = H5Pget_layout(plist);
323
351
   H5Pclose(plist);
324
 
   
325
 
   /* End access to the dataset */
326
 
   if ( H5Dclose( dataset_id ) )
327
 
     return -1;
328
 
   
 
352
 
329
353
   return class_id;
330
 
   
 
354
 
331
355
}
332
356
 
 
357
 
333
358
/* Helper routine that returns the rank, dims and byteorder for
334
359
   UnImplemented objects. 2004
335
360
*/
336
361
 
337
 
PyObject *H5UIget_info( hid_t loc_id, 
 
362
PyObject *H5UIget_info( hid_t loc_id,
338
363
                        const char *dset_name,
339
364
                        char *byteorder)
340
365
{
341
 
  hid_t       dataset_id;  
 
366
  hid_t       dataset_id;
342
367
  int         rank;
343
368
  hsize_t     *dims;
344
 
  hid_t       space_id; 
 
369
  hid_t       space_id;
345
370
  H5T_class_t class_id;
346
371
  H5T_order_t order;
347
 
  hid_t       type_id; 
 
372
  hid_t       type_id;
348
373
  PyObject    *t;
349
374
  int         i;
350
375
 
381
406
    /* I don't know if I should increase the reference count for dims[i]! */
382
407
    PyTuple_SetItem(t, i, PyInt_FromLong((long)dims[i]));
383
408
  }
384
 
  
 
409
 
385
410
  /* Release resources */
386
411
  free(dims);
387
412
 
388
413
  /* Terminate access to the dataspace */
389
414
  if ( H5Sclose( space_id ) < 0 )
390
415
    goto out;
391
 
 
 
416
 
392
417
  /* Get the byteorder */
393
 
  /* Only class integer and float can be byteordered */
394
 
  if ( (class_id == H5T_INTEGER) || (class_id == H5T_FLOAT)
395
 
       || (class_id == H5T_BITFIELD) ) {
 
418
  /* Only integer, float, time and enum classes can be byteordered */
 
419
  if ((class_id == H5T_INTEGER) || (class_id == H5T_FLOAT)
 
420
      || (class_id == H5T_BITFIELD) || (class_id == H5T_TIME)
 
421
      ||  (class_id == H5T_ENUM)) {
396
422
    order = H5Tget_order( type_id );
397
 
    if (order == H5T_ORDER_LE) 
 
423
    if (order == H5T_ORDER_LE)
398
424
      strcpy(byteorder, "little");
399
425
    else if (order == H5T_ORDER_BE)
400
426
      strcpy(byteorder, "big");
421
447
 
422
448
}
423
449
 
 
450
/* Extract a slice index from a PyLong, and store in *pi.  Silently
 
451
   reduce values larger than LONGLONG_MAX to LONGLONG_MAX, and
 
452
   silently boost values less than -LONGLONG_MAX to 0.  Return 0 on
 
453
   error, 1 on success.
 
454
*/
 
455
/* Note: This has been copied and modified from the original in
 
456
   Python/ceval.c so as to allow working with long long values.
 
457
   F. Altet 2005-05-08
 
458
*/
 
459
 
 
460
hsize_t _PyEval_SliceIndex_modif(PyObject *v, hsize_t *pi)
 
461
{
 
462
  PY_LONG_LONG LONGLONG_MAX;
 
463
 
 
464
  /* I think it should be a more efficient way to know LONGLONG_MAX,
 
465
   but this should work on every platform, be 32 or 64 bits.
 
466
   F. Altet 2005-05-08
 
467
  */
 
468
 
 
469
/*  LONGLONG_MAX = (PY_LONG_LONG) (pow(2, 63) - 1); */ /* Works on Unix */
 
470
  LONGLONG_MAX = (PY_LONG_LONG) (pow(2, 62) - 1); /* Safer on Windows */
 
471
 
 
472
  if (v != NULL) {
 
473
    PY_LONG_LONG x;
 
474
    if (PyInt_Check(v)) {
 
475
      x = PyLong_AsLongLong(v);
 
476
    }
 
477
    else if (PyLong_Check(v)) {
 
478
      x = PyLong_AsLongLong(v);
 
479
    } else {
 
480
      PyErr_SetString(PyExc_TypeError,
 
481
                      "PyTables slice indices must be integers");
 
482
      return 0;
 
483
    }
 
484
    /* Truncate -- very long indices are truncated anyway */
 
485
    if (x > LONGLONG_MAX)
 
486
      x = LONGLONG_MAX;
 
487
    else if (x < -LONGLONG_MAX)
 
488
      x = -LONGLONG_MAX;
 
489
    *pi = x;
 
490
  }
 
491
  return 1;
 
492
}
 
493
 
424
494
/* This has been copied from the Python 2.3 sources in order to get a
425
 
   funtion similar to the method slice.indices(length) introduced in
426
 
   python 2.3, but for 2.2 */
427
 
 
428
 
/* F. Alted 2004-01-19 */
429
 
 
430
 
int GetIndicesEx(PyObject *s, int length,
431
 
                 int *start, int *stop, int *step, int *slicelength)
432
 
{
433
 
        /* this is harder to get right than you might think */
434
 
 
435
 
        int defstart, defstop;
436
 
        PySliceObject *r = (PySliceObject *) s;
437
 
 
438
 
        if (r->step == Py_None) {
439
 
                *step = 1;
440
 
        } 
441
 
        else {
442
 
                if (!_PyEval_SliceIndex(r->step, step)) return -1;
443
 
                if (*step == 0) {
444
 
                        PyErr_SetString(PyExc_ValueError,
445
 
                                        "slice step cannot be zero");
446
 
                        return -1;
447
 
                }
448
 
        }
449
 
 
450
 
        defstart = *step < 0 ? length-1 : 0;
451
 
        defstop = *step < 0 ? -1 : length;
452
 
 
453
 
        if (r->start == Py_None) {
454
 
                *start = defstart;
455
 
        }
456
 
        else {
457
 
                if (!_PyEval_SliceIndex(r->start, start)) return -1;
458
 
                if (*start < 0) *start += length;
459
 
                if (*start < 0) *start = (*step < 0) ? -1 : 0;
460
 
                if (*start >= length) 
461
 
                        *start = (*step < 0) ? length - 1 : length;
462
 
        }
463
 
 
464
 
        if (r->stop == Py_None) {
465
 
                *stop = defstop;
466
 
        }
467
 
        else {
468
 
                if (!_PyEval_SliceIndex(r->stop, stop)) return -1;
469
 
                if (*stop < 0) *stop += length;
470
 
                if (*stop < 0) *stop = -1;
471
 
                if (*stop > length) *stop = length;
472
 
        }
473
 
 
474
 
        if ((*step < 0 && *stop >= *start) 
475
 
            || (*step > 0 && *start >= *stop)) {
476
 
                *slicelength = 0;
477
 
        }
478
 
        else if (*step < 0) {
479
 
                *slicelength = (*stop-*start+1)/(*step)+1;
480
 
        }
481
 
        else {
482
 
                *slicelength = (*stop-*start-1)/(*step)+1;
483
 
        }
484
 
 
485
 
        return 0;
486
 
}
487
 
 
488
 
/*-------------------------------------------------------------------------
489
 
 * Function: get_attribute_string_sys
490
 
 *
491
 
 * Purpose: Reads a attribute specific of PyTables in a fast way
492
 
 *
493
 
 * Return: Success: 0, Failure: -1
494
 
 *
495
 
 * Programmer: Francesc Alted, falted@pytables.org
496
 
 *
497
 
 * Date: September 19, 2003
498
 
 *
499
 
 * Comments:
500
 
 *
501
 
 * Modifications:
502
 
 *
503
 
 *-------------------------------------------------------------------------
504
 
 */
505
 
 
506
 
 
507
 
PyObject *get_attribute_string_sys( hid_t loc_id,
508
 
                                    const char *obj_name,
509
 
                                    const char *attr_name)
510
 
{
511
 
 
512
 
 /* identifiers */
513
 
 hid_t      obj_id;
514
 
 hid_t      attr_id;
515
 
 hid_t      attr_type;
516
 
 size_t     attr_size;
517
 
 PyObject   *attr_value;
518
 
 char       *data;
519
 
 H5G_stat_t statbuf;
520
 
 
521
 
 /* Get the type of object */
522
 
 if (H5Gget_objinfo(loc_id, obj_name, 1, &statbuf)<0)
523
 
  return NULL;
524
 
 
525
 
 /* Open the object */
526
 
 if ((obj_id = _open_id( loc_id, obj_name, statbuf.type )) < 0)
527
 
   return NULL;
528
 
 
529
 
/*  Check if attribute exists */
530
 
 /* This is commented out to make the attribute reading faster */
531
 
/*  if (H5LT_find_attribute(obj_id, attr_name) <= 0)  */
532
 
 if ( ( attr_id = H5Aopen_name( obj_id, attr_name ) ) < 0 )
533
 
   /* If the attribute does not exists, return None */
534
 
   /* and do not even warn the user */
535
 
   return Py_None;
536
 
 
537
 
 if ( (attr_type = H5Aget_type( attr_id )) < 0 )
538
 
  goto out;
539
 
 
540
 
 /* Get the size. */
541
 
 attr_size = H5Tget_size( attr_type );
542
 
 
543
 
/*  printf("name: %s. size: %d\n", attr_name, attr_size); */
544
 
 /* Allocate memory for the input buffer */
545
 
 data = (char *)malloc(attr_size);
546
 
 
547
 
 if ( H5Aread( attr_id, attr_type, data ) < 0 )
548
 
  goto out;
549
 
 
550
 
 attr_value = PyString_FromString(data);
551
 
 free(data);
552
 
 
553
 
 if ( H5Tclose( attr_type )  < 0 )
554
 
  goto out;
555
 
 
556
 
 if ( H5Aclose( attr_id ) < 0 )
557
 
  return Py_None;
558
 
 
559
 
 /* Close the object */
560
 
 if ( _close_id( obj_id, statbuf.type ) < 0 )
561
 
  return Py_None;
562
 
 
563
 
 return attr_value;
564
 
 
565
 
out:
566
 
 H5Aclose( attr_id );
567
 
 H5Aclose( attr_type );
568
 
 return Py_None;
569
 
 
570
 
}
571
 
 
572
 
/*-------------------------------------------------------------------------
573
 
 * Function: _open_id
574
 
 *
575
 
 * Purpose: Private function used by get_attribute_string_sys
576
 
 *
577
 
 * Return: Success: 0, Failure: -1
578
 
 *
579
 
 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
580
 
 *
581
 
 * Date: September 19, 2002
582
 
 *
583
 
 * Comments:
584
 
 *
585
 
 *-------------------------------------------------------------------------
586
 
 */
587
 
 
588
 
 
589
 
 
590
 
herr_t _open_id( hid_t loc_id, 
591
 
                 const char *obj_name, 
592
 
                 int obj_type /*basic object type*/ ) 
593
 
{
594
 
 
595
 
 hid_t   obj_id = -1;  
596
 
 
597
 
 switch ( obj_type )
598
 
 {
599
 
  case H5G_DATASET:
600
 
    
601
 
   /* Open the dataset. */
602
 
   if ( (obj_id = H5Dopen( loc_id, obj_name )) < 0 )
603
 
    return -1;
604
 
   break;
605
 
 
606
 
  case H5G_GROUP:
607
 
 
608
 
   /* Open the group. */
609
 
   if ( (obj_id = H5Gopen( loc_id, obj_name )) < 0 )
610
 
    return -1;
611
 
   break;
612
 
 
613
 
  default:
614
 
   return -1; 
615
 
 }
616
 
 
617
 
 return obj_id; 
618
 
 
619
 
}
620
 
 
621
 
 
622
 
/*-------------------------------------------------------------------------
623
 
 * Function: _close_id
624
 
 *
625
 
 * Purpose: Private function used by get_attribute_string_sys
626
 
 *
627
 
 * Return: Success: 0, Failure: -1
628
 
 *
629
 
 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
630
 
 *
631
 
 * Date: September 19, 2002
632
 
 *
633
 
 * Comments:
634
 
 *
635
 
 *-------------------------------------------------------------------------
636
 
 */
637
 
 
638
 
 
639
 
 
640
 
herr_t _close_id( hid_t obj_id,
641
 
                  int obj_type /*basic object type*/ ) 
642
 
{
643
 
 
644
 
 switch ( obj_type )
645
 
 {
646
 
  case H5G_DATASET:
647
 
   /* Close the dataset. */
648
 
   if ( H5Dclose( obj_id ) < 0 )
649
 
    return -1; 
650
 
   break;
651
 
 
652
 
  case H5G_GROUP:
653
 
  /* Close the group. */
654
 
   if ( H5Gclose( obj_id ) < 0 )
655
 
    return -1; 
656
 
   break;
657
 
 
658
 
  default:
659
 
   return -1; 
660
 
 }
661
 
 
662
 
 return 0; 
663
 
 
 
495
   function similar to the method slice.indices(length) but that works
 
496
   with 64-bit ints and not only with ints.
 
497
 */
 
498
 
 
499
/* F. Altet 2005-05-08 */
 
500
 
 
501
hsize_t getIndicesExt(PyObject *s, hsize_t length,
 
502
                      hsize_t *start, hsize_t *stop, hsize_t *step,
 
503
                      hsize_t *slicelength)
 
504
{
 
505
        /* this is harder to get right than you might think */
 
506
 
 
507
        hsize_t defstart, defstop;
 
508
        PySliceObject *r = (PySliceObject *) s;
 
509
 
 
510
        if (r->step == Py_None) {
 
511
                *step = 1;
 
512
        }
 
513
        else {
 
514
                if (!_PyEval_SliceIndex_modif(r->step, step)) return -1;
 
515
                if ((PY_LONG_LONG)*step == 0) {
 
516
                        PyErr_SetString(PyExc_ValueError,
 
517
                                        "slice step cannot be zero");
 
518
                        return -1;
 
519
                }
 
520
        }
 
521
 
 
522
        defstart = (PY_LONG_LONG)*step < 0 ? length-1 : 0;
 
523
        defstop = (PY_LONG_LONG)*step < 0 ? -1 : length;
 
524
 
 
525
        if (r->start == Py_None) {
 
526
                *start = defstart;
 
527
        }
 
528
        else {
 
529
                if (!_PyEval_SliceIndex_modif(r->start, start)) return -1;
 
530
                if ((PY_LONG_LONG)*start < 0L) *start += length;
 
531
                if ((PY_LONG_LONG)*start < 0) *start = ((PY_LONG_LONG)*step < 0) ? -1 : 0;
 
532
                if ((PY_LONG_LONG)*start >= length)
 
533
                        *start = ((PY_LONG_LONG)*step < 0) ? length - 1 : length;
 
534
        }
 
535
 
 
536
        if (r->stop == Py_None) {
 
537
                *stop = defstop;
 
538
        }
 
539
        else {
 
540
                if (!_PyEval_SliceIndex_modif(r->stop, stop)) return -1;
 
541
                if ((PY_LONG_LONG)*stop < 0) *stop += length;
 
542
                if ((PY_LONG_LONG)*stop < 0) *stop = -1;
 
543
                if ((PY_LONG_LONG)*stop > length) *stop = length;
 
544
        }
 
545
 
 
546
        if (((PY_LONG_LONG)*step < 0 && (PY_LONG_LONG)*stop >= (PY_LONG_LONG)*start)
 
547
            || ((PY_LONG_LONG)*step > 0 && (PY_LONG_LONG)*start >= (PY_LONG_LONG)*stop)) {
 
548
                *slicelength = 0;
 
549
        }
 
550
        else if ((PY_LONG_LONG)*step < 0) {
 
551
                *slicelength = (*stop-*start+1)/(*step)+1;
 
552
        }
 
553
        else {
 
554
                *slicelength = (*stop-*start-1)/(*step)+1;
 
555
        }
 
556
 
 
557
        return 0;
664
558
}
665
559
 
666
560
 
669
563
   so we make one from a HDF5 compound type class.
670
564
 
671
565
   Added by Tom Hedley <thedley@users.sourceforge.net> April 2004.
672
 
   Adapted to support Tables by F. Alted September 2004.
 
566
   Adapted to support Tables by F. Altet September 2004.
673
567
*/
674
568
 
675
569
/* Return the byteorder of a complex datatype.
676
 
   It is obtained from the real part, 
 
570
   It is obtained from the real part,
677
571
   which is the first member. */
678
572
static H5T_order_t get_complex_order(hid_t type_id) {
679
573
  hid_t class_id, base_type_id;
680
 
  hid_t real_type;
 
574
  hid_t real_type = 0;
681
575
  H5T_order_t result = 0;
682
576
 
683
577
  class_id = H5Tget_class(type_id);
684
578
  if (class_id == H5T_COMPOUND) {
685
579
    real_type = H5Tget_member_type(type_id, 0);
686
 
  } 
 
580
  }
687
581
  else if (class_id == H5T_ARRAY) {
688
582
    /* Get the array base component */
689
583
    base_type_id = H5Tget_super(type_id);
698
592
  return result;
699
593
}
700
594
 
701
 
/* Test whether the datatype is of class complex 
 
595
/* Test whether the datatype is of class complex
702
596
   return 1 if it corresponds to our complex class, otherwise 0 */
703
 
/* It simply checks if its a H5T_COMPOUND type,
704
 
   but we could be more strict by checking names and classes
705
 
   of the members*/
 
597
/* This may be ultimately confused with nested types with 2 components
 
598
   called 'r' and 'i' and being floats, but in that case, the user
 
599
   most probably wanted to keep a complex type, so getting a complex
 
600
   instead of a nested type should not be a big issue (I hope!) :-/
 
601
   F. Altet 2005-05-23 */
706
602
int is_complex(hid_t type_id) {
707
 
  hid_t class_id, base_type_id, base_class_id;
 
603
  hid_t class_id, base_type_id;
 
604
  hid_t class1, class2;
 
605
  char *colname1, *colname2;
708
606
  int result = 0;
 
607
  hsize_t nfields;
 
608
 
709
609
  class_id = H5Tget_class(type_id);
710
610
  if (class_id == H5T_COMPOUND) {
711
 
    result = 1;
 
611
    nfields = H5Tget_nmembers(type_id);
 
612
    if (nfields == 2) {
 
613
      colname1 = H5Tget_member_name(type_id, 0);
 
614
      colname2 = H5Tget_member_name(type_id, 1);
 
615
      if ((strcmp(colname1, "r") == 0) && (strcmp(colname2, "i") == 0)) {
 
616
        class1 = H5Tget_member_class(type_id, 0);
 
617
        class2 = H5Tget_member_class(type_id, 1);
 
618
        if (class1 == H5T_FLOAT && class2 == H5T_FLOAT)
 
619
          result = 1;
 
620
      }
 
621
      free(colname1);
 
622
      free(colname2);
 
623
    }
712
624
  }
713
625
  /* Is an Array of Complex? */
714
626
  else if (class_id == H5T_ARRAY) {
715
627
    /* Get the array base component */
716
628
    base_type_id = H5Tget_super(type_id);
717
 
    /* Get the class of base component. */
718
 
    base_class_id = H5Tget_class(base_type_id);
719
 
    if (base_class_id == H5T_COMPOUND)
720
 
      result = 1;
 
629
    /* Call is_complex again */
 
630
    result = is_complex(base_type_id);
 
631
    H5Tclose(base_type_id);
721
632
  }
722
633
  return result;
723
634
}
725
636
/* Return the byteorder of a HDF5 data type */
726
637
/* This is effectively an extension of H5Tget_order
727
638
   to handle complex types */
728
 
H5T_order_t get_order(hid_t type_id) {
 
639
herr_t get_order(hid_t type_id, char *byteorder) {
729
640
  hid_t class_id;
 
641
  H5T_order_t h5byteorder;
730
642
 
731
643
  class_id = H5Tget_class(type_id);
732
 
/*   printf("Class ID-->%d. Iscomplex?:%d\n", class_id, is_complex(type_id)); */
 
644
 
733
645
  if (is_complex(type_id)) {
734
 
    return get_complex_order(type_id);
735
 
  }
736
 
  else {
737
 
    return H5Tget_order(type_id);
 
646
    h5byteorder = get_complex_order(type_id);
 
647
  }
 
648
  else {
 
649
    h5byteorder = H5Tget_order(type_id);
 
650
  }
 
651
  if (h5byteorder == H5T_ORDER_LE) {
 
652
    strcpy(byteorder, "little");
 
653
    return h5byteorder;
 
654
  }
 
655
  else if (h5byteorder == H5T_ORDER_BE ) {
 
656
    strcpy(byteorder, "big");
 
657
    return h5byteorder;
 
658
  }
 
659
  else if (h5byteorder == H5T_ORDER_NONE ) {
 
660
    strcpy(byteorder, "non-relevant");
 
661
    return h5byteorder;
 
662
  }
 
663
  else {
 
664
    fprintf(stderr, "Error: unsupported byteorder <%d>\n", h5byteorder);
 
665
    strcpy(byteorder, "unsupported");
 
666
    return -1;
738
667
  }
739
668
}
740
669
 
744
673
herr_t set_order(hid_t type_id, const char *byteorder) {
745
674
  herr_t status=0;
746
675
  if (! is_complex(type_id)) {
747
 
    if (strcmp(byteorder, "little") == 0) 
 
676
    if (strcmp(byteorder, "little") == 0)
748
677
      status = H5Tset_order(type_id, H5T_ORDER_LE);
749
 
    else if (strcmp(byteorder, "big") == 0) 
 
678
    else if (strcmp(byteorder, "big") == 0)
750
679
      status = H5Tset_order(type_id, H5T_ORDER_BE );
751
680
    else {
752
681
      fprintf(stderr, "Error: unsupported byteorder <%s>\n", byteorder);
756
685
  return status;
757
686
}
758
687
 
759
 
/* Create a HDF5 compound datatype that represents complex numbers 
 
688
/* Create a HDF5 compound datatype that represents complex numbers
760
689
   defined by numarray as Complex64.
761
690
   We must set the byteorder before we create the type */
762
691
hid_t create_native_complex64(const char *byteorder) {
773
702
  return complex_id;
774
703
}
775
704
 
776
 
/* Create a HDF5 compound datatype that represents complex numbers 
 
705
/* Create a HDF5 compound datatype that represents complex numbers
777
706
   defined by numarray as Complex32.
778
707
   We must set the byteorder before we create the type */
779
708
hid_t create_native_complex32(const char *byteorder) {
789
718
  return complex_id;
790
719
}
791
720
 
792
 
/* return the number of significant bits in the 
 
721
/* return the number of significant bits in the
793
722
   real and imaginary parts */
794
723
/* This is effectively an extension of H5Tget_precision
795
724
   to handle complex types */