Commits

Ronny Pfannschmidt committed 731a913

flip around allocation/reallocation

Comments (0)

Files changed (1)

 """) #XXX better
 
 typecodes = {
-    'c': 'char[]',
-    'b': 'signed char[]',
-    'B': 'unsigned char[]',
-    'u': 'wchar[]',
-    'h': 'signed short[]',
-    'H': 'unsigned short[]',
-    'i': 'signed int[]',
-    'I': 'unsigned int[]',
-    'l': 'signed long[]',
-    'L': 'unsigned long[]',
-    'f': 'float[]',
-    'd': 'double[]',
+    'c': 'char',
+    'b': 'signed char',
+    'B': 'unsigned char',
+    'u': 'wchar',
+    'h': 'signed short',
+    'H': 'unsigned short',
+    'i': 'signed int',
+    'I': 'unsigned int',
+    'l': 'signed long',
+    'L': 'unsigned long',
+    'f': 'float',
+    'd': 'double',
 }
 
 
-def alloc(typecode, size):
+def typecode2ctype(typecode):
     try:
-        ctype = typecodes[typecode]
+        return typecodes[typecode]
     except KeyError:
         if not isinstance(typecode, str):
             raise TypeError('must be char, not %s' %(type(typecode).__name__,))
         if len(typecode) > 1:
             raise TypeError('must be char, not str')
         raise ValueError("bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d")
-    return ffi.new(ctype, size)
+
 
 missing = object()
 
 
 class array(object):
-    __slots__ = '_len', '_capacity', '_data', 'typecode', '__weakref__'
+    __slots__ = [
+        '_len', '_capacity', '_data',
+        'typecode', '_ctype', '_arraytype',
+        '__weakref__',
+    ]
+
     def __new__(cls, typecode, initializer=missing, **kw):
         self = object.__new__(cls)
         self.typecode = typecode
+        self._ctype = typecode2ctype(typecode)
+        self._arraytype = ffi.getctype(self._ctype, '[]')
         self._len = 0
-        self._capacity = 1
-        self._data = alloc(typecode, 1)
+        self._capacity = 0
+        self._data = ffi.NULL
         if initializer is not missing:
             if isinstance(initializer, str):
                 self.fromstring(initializer)
 
     def _realloc(self, new_size):
         assert new_size > self._len
-        new = alloc(self.typecode, new_size)
+        new = ffi.new(self._arraytype, new_size)
         #XXX: memcopy
         #XXX: downsizing?
 
-        ffi.buffer(new, ffi.sizeof(self._data))[:] = ffi.buffer(self._data)
+        if self._data is not ffi.NULL:
+            ffi.buffer(new, ffi.sizeof(self._data))[:] = ffi.buffer(self._data)
 
         self._data = new
         self._capacity = new_size
     
     @property
     def itemsize(self):
-        return ffi.sizeof(self._data)/len(self._data)
+        return ffi.sizeof(self._ctype)
 
     def __len__(self):
         return self._len
     def append(self, item):
         #XXX: checksize
         if self._len == self._capacity:
-            self._realloc(self._capacity*2)
+            self._realloc(self._capacity*2 or 4)
         self._data[self._len] = item
         self._len += 1
 
             end = start + self.itemsize
             buffer = ffi.buffer(self._data)
             buffer[start:-self.itemsize] = buffer[end:]
+        elif isinstance(item, slice):
+            assert not slice.step
+
 
     def __imul__(self, number):
         evil = array.array(self.typecode, self) *number