Hello again list,

so, now the diff to current svn for the rest of the implementation:

Index: setup.py
===================================================================
--- setup.py    (revisión: 4263)
+++ setup.py    (copia de trabajo)
@@ -377,6 +377,7 @@
     'utilsExtension',
     'hdf5Extension',
     'tableExtension',
+    'reference',
     '_comp_lzo',
     '_comp_bzip2' ]
 if VERSION.endswith('pro'):
@@ -494,6 +495,7 @@
 hdf5Extension_libs = LIBS + [hdf5_package.library_name]
 tableExtension_libs = LIBS + [hdf5_package.library_name]
 indexesExtension_libs = LIBS + [hdf5_package.library_name]
+reference_libs = LIBS + [hdf5_package.library_name]
 lrucacheExtension_libs = []    # Doesn't need external libraries

 # Compressor modules only need other libraries if they are enabled.
@@ -547,6 +549,15 @@
                extra_link_args=LFLAGS,
                extra_compile_args=CFLAGS ),

+    Extension( "tables.reference",
+               include_dirs=inc_dirs,
+               define_macros=def_macros,
+               sources=[ pyrex_extfiles['reference'] ],
+               library_dirs=lib_dirs,
+               libraries=reference_libs,
+               extra_link_args=LFLAGS,
+               extra_compile_args=CFLAGS ),
+
     Extension( "tables._comp_lzo",
                include_dirs=inc_dirs,
                define_macros=def_macros,
Index: tables/__init__.py
===================================================================
--- tables/__init__.py  (revisión: 4263)
+++ tables/__init__.py  (copia de trabajo)
@@ -64,6 +64,7 @@

 from tables.utilsExtension import (
     isHDF5File, isPyTablesFile, whichLibVersion, lrange )
+from tables.reference import reference

 from tables.misc.enum import Enum
 from tables.atom import *
Index: tables/hdf5Extension.pyx
===================================================================
--- tables/hdf5Extension.pyx    (revisión: 4263)
+++ tables/hdf5Extension.pyx    (copia de trabajo)
@@ -75,11 +75,13 @@
      H5Gcreate, H5Gopen, H5Gclose, H5Glink, H5Gunlink, H5Gmove, \
      H5Gmove2, H5Gget_objinfo, \
      H5Dopen, H5Dclose, H5Dread, H5Dwrite, H5Dget_type, \
-     H5Dget_space, H5Dvlen_reclaim, \
-     H5Tget_native_type, H5Tget_super, H5Tget_class, H5Tcopy, \
-     H5Tclose, H5Tis_variable_str, H5Tget_sign, \
+     H5Dget_space, H5Dvlen_reclaim, H5Tcreate, H5Tvlen_create,\
+     H5Tget_native_type, H5Tget_super, H5Tget_class, H5Tcopy, H5Tinsert, \
+     H5Tclose, H5Tis_variable_str, H5Tget_sign, H5Tget_member_name, \
+     H5Tget_member_offset, H5Tget_member_type, H5Tget_nmembers, H5Tget_size, \
+     H5Acreate, H5Aget_space, H5Aopen_name, \
      H5Adelete, H5Aget_num_attrs, H5Aget_name, H5Aopen_idx, \
-     H5Aread, H5Aclose, H5Pcreate, H5Pclose, \
+     H5Aread, H5Awrite, H5Aclose, H5Pcreate, H5Pclose, \
      H5Pset_cache, H5Pset_sieve_buf_size, H5Pset_fapl_log, \
      H5Sselect_all, H5Sselect_elements, H5Sselect_hyperslab, \
      H5Screate_simple, H5Sget_simple_extent_ndims, \
@@ -90,9 +92,12 @@
      H5ARRAYget_ndims, H5ARRAYget_info, \
      set_cache_size, get_objinfo, Giterate, Aiterate, H5UIget_info, \
      get_len_of_range, get_order, set_order, is_complex, \
-     conv_float64_timeval32, truncate_dset
+     conv_float64_timeval32, truncate_dset, H5R_OBJECT, H5T_STD_REF_OBJ, \
+     hobj_ref_t, H5E_auto_t, H5Eget_auto, H5Eset_auto


+from reference cimport reference
+
 # Include conversion tables
 include "convtypetables.pxi"

@@ -248,17 +253,30 @@
     ntype = None
   return ntype

+def islist(l):
+  try:
+    dtype = l[0].dtype
+    for e in l:
+      if e.dtype != dtype:
+        return None
+    return dtype
+  except (TypeError, IndexError):
+    return None

+cdef void deleteIfExisting(hid_t node, char *name):
+  cdef H5E_auto_t func
+  cdef void *data
+  H5Eget_auto(&func, &data)
+  H5Eset_auto(NULL, NULL)
+  H5Adelete(node, name)
+  H5Eset_auto(func, data)

 # Type extensions declarations (these are subclassed by PyTables
 # Python classes)

 cdef class File:
-  cdef hid_t   file_id
-  cdef hid_t   access_plist
-  cdef object  name
+  # Instance variables declared in .pxd

-
   def _g_new(self, name, pymode, **params):
     # Create a new file using default properties
     self.name = name
@@ -404,11 +422,12 @@
     type.
     """

-    cdef int ret
-    cdef hid_t dset_id, type_id
+    cdef int ret, i
+    cdef hid_t dset_id, type_id, vlen_id, space_id, attr_id
     cdef hsize_t *dims
+    cdef hvl_t *vl_buf
     cdef ndarray ndv
-    cdef object byteorder, rabyteorder, baseatom
+    cdef object byteorder, rabyteorder, baseatom, basetype

     # The dataset id of the node
     dset_id = node._v_objectID
@@ -417,9 +436,11 @@
     if isinstance(value, numpy.generic):
       value = numpy.array(value)

+    basetype = islist(value)
+
     # Check if value is a NumPy ndarray and of a supported type
     if (isinstance(value, numpy.ndarray) and
-        value.dtype.kind in ('V', 'S', 'b', 'i', 'u', 'f', 'c')):
+        value.dtype.kind in 'VSbiufcr'):
       if value.dtype.kind == 'V':
         description, rabyteorder = descr_from_dtype(value.dtype)
         byteorder = byteorders[rabyteorder]
@@ -441,6 +462,37 @@
       # Release resources
       free(<void *>dims)
       H5Tclose(type_id)
+    elif basetype is not None and basetype.kind in 'VSbiufcr':
+      if basetype.kind == 'V':
+        description, rabyteorder = descr_from_dtype(basetype)
+        byteorder = byteorders[rabyteorder]
+        type_id = createNestedType(description, byteorder)
+      else:
+        # Get the associated native HDF5 type of the scalar type
+        baseatom = Atom.from_dtype(basetype.base)
+        byteorder = byteorders[basetype.byteorder]
+        type_id = AtomToHDF5Type(baseatom, byteorder)
+      dims = <hsize_t *> malloc(sizeof(hsize_t))
+      dims[0] = len(value)
+      deleteIfExisting(dset_id, name)
+      space_id = H5Screate_simple(1, dims, NULL)
+      vlen_id = H5Tvlen_create(type_id)
+      attr_id = H5Acreate(dset_id, name, vlen_id, space_id, H5P_DEFAULT)
+      vl_buf = <hvl_t *> malloc(len(value) * sizeof(hvl_t))
+      i = 0
+      for v in value:
+        ndv = v
+        vl_buf[i].len = len(v)
+        vl_buf[i].p = ndv.data
+        i = i + 1
+      H5Awrite(attr_id, vlen_id, vl_buf)
+      H5Dvlen_reclaim(type_id, space_id, H5P_DEFAULT, vl_buf)
+      free(vl_buf)
+      H5Sclose(space_id)
+      free(dims)
+      H5Tclose(vlen_id)
+      H5Tclose(type_id)
+      H5Aclose(attr_id)
     else:
       # Object cannot be natively represented in HDF5.
       # Unicode attributes has to be pickled until we can definitely switch
@@ -469,8 +521,10 @@
     cdef H5T_class_t class_id
     cdef size_t type_size
     cdef hid_t mem_type, dset_id, type_id, native_type
-    cdef int rank, ret, enumtype
+    cdef hid_t vlen_id, native_type, attr_id, space_id
+    cdef int rank, ret, enumtype, i
     cdef void *rbuf
+    cdef hvl_t *vl_buf
     cdef char *str_value
     cdef ndarray ndvalue
     cdef object shape, stype_atom, shape_atom, retvalue
@@ -502,6 +556,38 @@
         self._v_unimplemented.append(attrname)
         return None
       shape = ()
+    elif (rank == 1 and class_id == H5T_VLEN):
+      attr_id = H5Aopen_name(dset_id, attrname)
+      space_id = H5Aget_space(attr_id)
+      H5Sget_simple_extent_dims(space_id, &nelements, NULL)
+      vl_buf = <hvl_t *> malloc(nelements * sizeof(hvl_t))
+      vlen_id = H5Tget_super(type_id)
+      try:
+        stype_, shape_ = HDF5ToNPExtType(vlen_id, pure_numpy_types=True)
+        dtype = numpy.dtype(stype_, shape_)
+      except TypeError:
+        # This class is not supported. Instead of raising a TypeError, issue a
+        # warning explaining the problem. This will allow to continue browsing
+        # native HDF5 files, while informing the user about the problem.
+        warnings.warn("""\
+Unsupported type for attribute '%s' in node '%s'. Offending HDF5 class: %d"""
+                      % (attrname, self.name, class_id), DataTypeWarning)
+        self._v_unimplemented.append(attrname)
+        return None
+      H5Tclose(vlen_id)
+      H5Aread(attr_id, type_id, vl_buf)
+      H5Aclose(attr_id)
+      retvalue = [ ]
+      for 0 <= i < nelements:
+        # Get the container for data
+        ndvalue = numpy.empty(vl_buf[i].len, dtype=dtype)
+        # Get the pointer to the buffer data area
+        memcpy(ndvalue.data, vl_buf[i].p, vl_buf[i].len * dtype.itemsize)
+        retvalue.append(ndvalue)
+      H5Dvlen_reclaim(type_id, space_id, H5P_DEFAULT, vl_buf)
+      H5Tclose(type_id)
+      H5Sclose(space_id)
+      return retvalue
     else:
       # General case

Index: tables/definitions.pxd
===================================================================
--- tables/definitions.pxd      (revisión: 4263)
+++ tables/definitions.pxd      (copia de trabajo)
@@ -173,6 +173,7 @@
   # such an unsigned long long type.
   ctypedef long long hsize_t
   ctypedef signed long long hssize_t
+  ctypedef long long hobj_ref_t

   ctypedef struct hvl_t:
     size_t len                 # Length of VL data (in base type units)
@@ -203,6 +204,9 @@
     H5G_DATASET,                # Object is a dataset
     H5G_TYPE,                   # Object is a named data type

+  ctypedef enum H5R_type_t:
+    H5R_OBJECT
+
   # Values for fill value status
   cdef enum H5D_fill_value_t:
     H5D_FILL_VALUE_ERROR        = -1,
@@ -219,6 +223,11 @@
     size_t linklen
     #H5O_stat_t ohdr            # Object header information. New in HDF5 1.6

+  ctypedef struct H5E_auto_t_t:
+    pass
+
+  ctypedef H5E_auto_t_t *H5E_auto_t
+
   # HDF5 layouts
   cdef enum H5D_layout_t:
     H5D_LAYOUT_ERROR    = -1,
@@ -315,6 +324,10 @@
     H5T_UNIX_D32BE
     H5T_UNIX_D64BE

+  # reference types
+  cdef enum:
+    H5T_STD_REF_OBJ
+
   # The order to retrieve atomic native datatype
   cdef enum H5T_direction_t:
     H5T_DIR_DEFAULT     = 0,    #default direction is inscendent
@@ -404,6 +417,7 @@
   hid_t  H5Tcreate(H5T_class_t type, size_t size)
   hid_t  H5Tcopy(hid_t type_id)
   herr_t H5Tclose(hid_t type_id)
+  hid_t  H5Tvlen_create(hid_t base_type_id)

   # Operations defined on string data types
   htri_t H5Tis_variable_str(hid_t dtype_id)
@@ -412,6 +426,7 @@
   int    H5Tget_nmembers(hid_t type_id)
   char  *H5Tget_member_name(hid_t type_id, unsigned membno)
   hid_t  H5Tget_member_type(hid_t type_id, unsigned membno)
+  size_t H5Tget_member_offset(hid_t type_id, unsigned membno)
   hid_t  H5Tget_native_type(hid_t type_id, H5T_direction_t direction)
   herr_t H5Tget_member_value(hid_t type_id, int membno, void *value)
   int    H5Tget_offset(hid_t type_id)
@@ -434,7 +449,12 @@
   size_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
   hid_t  H5Aopen_idx(hid_t loc_id, unsigned int idx)
   herr_t H5Aread(hid_t attr_id, hid_t mem_type_id, void *buf)
+  herr_t H5Awrite(hid_t attr_id, hid_t mem_type_id, void *buf)
   herr_t H5Aclose(hid_t attr_id)
+  hid_t  H5Acreate(hid_t loc_id, char *attr_name, hid_t type_id,
+                   hid_t space_id, hid_t acpl_id)
+  herr_t H5Aopen_name(hid_t loc_id, char *name)
+  hid_t  H5Aget_space(hid_t attr_id)

   # Operations with properties
   hid_t  H5Pcreate(hid_t plist_id)
@@ -447,7 +467,14 @@
   H5D_layout_t H5Pget_layout(hid_t plist)
   int H5Pget_chunk(hid_t plist, int max_ndims, hsize_t *dims)

+  # error handling
+  herr_t H5Eget_auto(H5E_auto_t *func, void **client_data)
+  herr_t H5Eset_auto(H5E_auto_t func, void *client_data)

+  # Operations with references
+  herr_t H5Rcreate(void *ref, hid_t loc_id, char *name, H5R_type_t ref_type,
+        hid_t space_id)
+
 # Specific HDF5 functions for PyTables
 cdef extern from "H5ATTR.h":
   herr_t H5ATTRget_attribute(hid_t loc_id, char *attr_name,
Index: tables/utilsExtension.pyx
===================================================================
--- tables/utilsExtension.pyx   (revisión: 4263)
+++ tables/utilsExtension.pyx   (copia de trabajo)
@@ -665,6 +665,8 @@
       tid = H5Tcopy(H5T_STD_B8);
     elif atom.kind == 'enum':
       tid = enumToHDF5(atom, byteorder)
+    elif atom.kind == 'reference':
+      tid = H5Tcopy(H5T_STD_REF_OBJ)
   else:
     raise TypeError("Invalid type for atom %s" % (atom,))
   # Create an H5T_ARRAY in case of non-scalar atoms
@@ -774,6 +776,8 @@
       stype = "u%s" % (itemsize)
   elif class_id == H5T_FLOAT:
     stype = "f%s" % (itemsize)
+  elif class_id == H5T_REFERENCE:
+    stype = "r8"
   elif class_id ==  H5T_COMPOUND:
     if is_complex(type_id):
       stype = "c%s" % (itemsize)
Index: tables/hdf5Extension.pxd
===================================================================
--- tables/hdf5Extension.pxd    (revisión: 4263)
+++ tables/hdf5Extension.pxd    (copia de trabajo)
@@ -2,6 +2,11 @@


 # Declaration of instance variables for shared classes
+cdef class File:
+  cdef hid_t file_id
+  cdef hid_t access_plist
+  cdef object name
+
 cdef class Node:
   cdef char  *name
   cdef hid_t  parent_id
Index: tables/atom.py
===================================================================
--- tables/atom.py      (revisión: 4263)
+++ tables/atom.py      (copia de trabajo)
@@ -619,7 +619,16 @@
     def __init__(self, shape=(), dflt=_defvalue):
         Atom.__init__(self, self.type, shape, dflt)

+class ReferenceAtom(Atom):
+    kind = 'reference'
+    itemsize = 8
+    type = 'reference'
+    _deftype = 'reference64'
+    _defvalue = None
+    def __init__(self, shape=(), dflt=_defvalue):
+        Atom.__init__(self, self.type, shape, dflt)

+
 class IntAtom(Atom):
     """Defines an atom of a signed integral type (``int`` kind)."""
     kind = 'int'
Index: tables/convtypetables.pxi
===================================================================
--- tables/convtypetables.pxi   (revisión: 4263)
+++ tables/convtypetables.pxi   (copia de trabajo)
@@ -35,7 +35,7 @@
      H5T_STD_B8BE, H5T_UNIX_D32BE, H5T_UNIX_D64BE, \
      H5T_STD_I8BE, H5T_STD_I16BE, H5T_STD_I32BE, H5T_STD_I64BE, \
      H5T_STD_U8BE, H5T_STD_U16BE, H5T_STD_U32BE, H5T_STD_U64BE, \
-     H5T_IEEE_F32BE, H5T_IEEE_F64BE
+     H5T_IEEE_F32BE, H5T_IEEE_F64BE, H5T_STD_REF_OBJ

 # Platform-dependent types
 if sys.byteorder == "little":
@@ -87,7 +87,7 @@
   }

 # Special cases whose byteorder cannot be directly changed
-PTSpecialKinds = ['complex', 'string', 'enum', 'bool']
+PTSpecialKinds = ['complex', 'string', 'enum', 'bool', 'reference']

 # Conversion table from NumPy extended codes prefixes to PyTables kinds
 NPExtPrefixesToPTKinds = {
@@ -99,6 +99,7 @@
   "c": "complex",
   "t": "time",
   "e": "enum",
+  "r": "reference"
   }

 # Names of HDF5 classes
Index: tables/description.py
===================================================================
--- tables/description.py       (revisión: 4263)
+++ tables/description.py       (copia de trabajo)
@@ -732,7 +732,7 @@
                     "are not supported yet, sorry" )
             fbyteorder = byteorder
         # Non-nested column
-        if kind in 'biufSc':
+        if kind in 'biufScOr':
             col = Col.from_dtype(dtype, pos=pos)
         # Nested column
         elif kind == 'V' and dtype.shape in [(), (1,)]:

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Pytables-users mailing list
Pytables-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pytables-users

Reply via email to