File: cinterface.diff

package info (click to toggle)
cf-python 1.3.2%2Bdfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 7,996 kB
  • sloc: python: 51,733; ansic: 2,736; makefile: 78; sh: 2
file content (146 lines) | stat: -rw-r--r-- 5,575 bytes parent folder | download
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
diff --git a/umread/cInterface.py b/umread/cInterface.py
index ce70b52..d64e783 100644
--- a/umread/cInterface.py
+++ b/umread/cInterface.py
@@ -13,34 +13,65 @@ class File_type(CT.Structure):
                 ("byte_ordering", CT.c_int),
                 ("word_size", CT.c_int)]
 
-class Rec(CT.Structure):
-    """
-    ctypes object corresponding to the Rec object in the C code
-    """
-    # defer setting _fields_ as this depends on 
-    # file data type for correct interpretation of the 
-    # void* used for each of int and real PP header data
-    pass
 
-class Var(CT.Structure):
+def _get_ctypes_array(dtype, size=None):
     """
-    ctypes object corresponding to the Var object in the C code
+    get ctypes corresponding to a numpy array of a given type;
+    the size should not be necessary unless the storage for the array 
+    is allocated in the C code
     """
-    _fields_ = [("recs", CT.POINTER(CT.POINTER(Rec))),
-                ("nz", CT.c_int),
-                ("nt", CT.c_int),
-                ("supervar_index", CT.c_int),
-                ("_internp", CT.c_void_p)]
-
-class File(CT.Structure):
+    kwargs = {'dtype': dtype,
+              'ndim': 1,
+              'flags': ('C_CONTIGUOUS', 'WRITEABLE')}
+    if size:
+        kwargs['shape'] = (size,)
+    return numpy.ctypeslib.ndpointer(**kwargs)
+
+def _gen_rec_class(int_type, float_type):
+    class Rec(CT.Structure):
+        _fields_ = [("int_hdr", _get_ctypes_array(int_type, _len_int_hdr)),
+                    ("real_hdr", _get_ctypes_array(float_type, _len_real_hdr)),
+                    ("header_offset", CT.c_size_t),
+                    ("data_offset", CT.c_size_t),
+                    ("disk_length", CT.c_size_t),
+                    ("_internp", CT.c_void_p)]
     """
-    ctypes object corresponding to the File object in the C code
+    ctypes object corresponding to the Rec object in the C code, 
     """
-    _fields_ = [("fd", CT.c_int),
-                ("file_type", File_type),
-                ("nvars", CT.c_int),
-                ("vars", CT.POINTER(CT.POINTER(Var))),
-                ("_internp", CT.c_void_p)]
+    return Rec
+
+Rec32 = _gen_rec_class(numpy.int32, numpy.float32)
+Rec64 = _gen_rec_class(numpy.int64, numpy.float64)
+
+def _gen_var_class(rec_class):
+    class Var(CT.Structure):
+        """
+        ctypes object corresponding to the Var object in the C code
+        """
+        _fields_ = [("recs", CT.POINTER(CT.POINTER(rec_class))),
+                    ("nz", CT.c_int),
+                    ("nt", CT.c_int),
+                    ("supervar_index", CT.c_int),
+                    ("_internp", CT.c_void_p)]
+    return Var
+
+Var32 = _gen_var_class(Rec32)
+Var64 = _gen_var_class(Rec64)
+
+def _gen_file_class(var_class):
+    class File(CT.Structure):
+        """
+        ctypes object corresponding to the File object in the C code
+        """
+        _fields_ = [("fd", CT.c_int),
+                    ("file_type", File_type),
+                    ("nvars", CT.c_int),
+                    ("vars", CT.POINTER(CT.POINTER(var_class))),
+                    ("_internp", CT.c_void_p)]
+    return File
+
+File32 = _gen_file_class(Var32)
+File64 = _gen_file_class(Var64)
 
 class Enum(object):
     def __init__(self, *names):
@@ -138,32 +169,21 @@ class CInterface(object):
             word_size = val
 
         if word_size == 4:
+            self.file_class = File32
             self.file_data_int_type = numpy.int32
             self.file_data_real_type = numpy.float32
         elif word_size == 8:
+            self.file_class = File64
             self.file_data_int_type = numpy.int64
             self.file_data_real_type = numpy.float64
         else:
             raise ValueError("word size must be 4 or 8 (not %s)" % word_size)
 
-    def _get_ctypes_array(self, dtype, size=None):
-        """
-        get ctypes corresponding to a numpy array of a given type;
-        the size should not be necessary unless the storage for the array 
-        is allocated in the C code
-        """
-        kwargs = {'dtype': dtype,
-                  'ndim': 1,
-                  'flags': ('C_CONTIGUOUS', 'WRITEABLE')}
-        if size:
-            kwargs['shape'] = (size,)
-        return numpy.ctypeslib.ndpointer(**kwargs)
-
     def _get_ctypes_int_array(self, size=None):
-        return self._get_ctypes_array(self.file_data_int_type, size)
+        return _get_ctypes_array(self.file_data_int_type, size)
 
     def _get_ctypes_real_array(self, size=None):
-        return self._get_ctypes_array(self.file_data_real_type, size)
+        return _get_ctypes_array(self.file_data_real_type, size)
     
     def _get_empty_real_array(self, size):
         """
@@ -190,14 +210,8 @@ class CInterface(object):
                                create_file_type()                               
         """
         func = self.lib.file_parse
-        file_p_type = CT.POINTER(File)
+        file_p_type = CT.POINTER(self.file_class)
         func.restype = file_p_type
-        Rec._fields_ = [("int_hdr", self._get_ctypes_int_array(_len_int_hdr)),
-                        ("real_hdr", self._get_ctypes_real_array(_len_real_hdr)),
-                        ("header_offset", CT.c_size_t),
-                        ("data_offset", CT.c_size_t),
-                        ("disk_length", CT.c_size_t),
-                        ("_internp", CT.c_void_p)]
         file_p = func(fh, file_type)
         if self._is_null_pointer(file_p):
             raise umfile.UMFileException("file parsing failed")