Rev 4411: We don't need a base Coder class, because Decoder._update_tail is different than Encoder._update_tail. in lp:///~jameinel/bzr/bencode_serializer

John Arbash Meinel john at arbash-meinel.com
Thu Jun 4 17:50:51 BST 2009


At lp:///~jameinel/bzr/bencode_serializer

------------------------------------------------------------
revno: 4411
revision-id: john at arbash-meinel.com-20090604165033-bfdo0lyf4yt4vjcz
parent: john at arbash-meinel.com-20090604160644-gtr5g8vsr9ufvvb3
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bencode_serializer
timestamp: Thu 2009-06-04 11:50:33 -0500
message:
  We don't need a base Coder class, because Decoder._update_tail is different than Encoder._update_tail.
  (one adds, one subtracts from self.size).
  So we now have 2 versions of the macro, and the test suite stops crashing... :)
-------------- next part --------------
=== modified file 'bzrlib/_bencode_pyx.h'
--- a/bzrlib/_bencode_pyx.h	2009-06-04 15:54:21 +0000
+++ b/bzrlib/_bencode_pyx.h	2009-06-04 16:50:33 +0000
@@ -1,15 +1,15 @@
 /* Copyright (C) 2009 Canonical Ltd
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
@@ -18,6 +18,5 @@
 /* Simple header providing some macro definitions for _bencode_pyx.pyx
  */
 
-#define UPDATE_TAIL(coder, n) (((coder)->size -= (n), (coder)->tail += (n)))
-
-
+#define D_UPDATE_TAIL(self, n) (((self)->size -= (n), (self)->tail += (n)))
+#define E_UPDATE_TAIL(self, n) (((self)->size += (n), (self)->tail += (n)))

=== modified file 'bzrlib/_bencode_pyx.pyx'
--- a/bzrlib/_bencode_pyx.pyx	2009-06-04 16:06:44 +0000
+++ b/bzrlib/_bencode_pyx.pyx	2009-06-04 16:50:33 +0000
@@ -51,21 +51,19 @@
 cdef extern from "python-compat.h":
     int snprintf(char* buffer, size_t nsize, char* fmt, ...)
 
-cdef class Coder:
-    """Base class for both Decoder and Encoder"""
-
-    cdef readonly char *tail
-    cdef readonly int size
+cdef class Decoder
+cdef class Encoder
 
 cdef extern from "_bencode_pyx.h":
-    void UPDATE_TAIL(Coder, int n)
-    int MAX_INT_AS_STR
-
-
-
-cdef class Decoder(Coder):
+    void D_UPDATE_TAIL(Decoder, int n)
+    void E_UPDATE_TAIL(Encoder, int n)
+
+
+cdef class Decoder:
     """Bencode decoder"""
 
+    cdef readonly char *tail
+    cdef readonly int size
     cdef readonly int _yield_tuples
     cdef object text
 
@@ -101,30 +99,25 @@
         try:
             ch = self.tail[0]
             if ch == c'i':
-                UPDATE_TAIL(self, 1)
+                D_UPDATE_TAIL(self, 1)
                 return self._decode_int()
             elif c'0' <= ch <= c'9':
                 return self._decode_string()
             elif ch == c'l':
-                UPDATE_TAIL(self, 1)
+                D_UPDATE_TAIL(self, 1)
                 return self._decode_list()
             elif ch == c'd':
-                UPDATE_TAIL(self, 1)
+                D_UPDATE_TAIL(self, 1)
                 return self._decode_dict()
             else:
                 raise ValueError('unknown object type identifier %r' % ch)
         finally:
             Py_LeaveRecursiveCall()
 
-    cdef void _update_tail(self, int n):
-        """Update tail pointer and resulting size by n characters"""
-        self.size = self.size - n
-        self.tail = self.tail + n
-
     cdef int _read_digits(self, char stop_char) except -1:
         cdef int i
         i = 0
-        while ((self.tail[i] >= c'0' and self.tail[i] <= c'9') or 
+        while ((self.tail[i] >= c'0' and self.tail[i] <= c'9') or
                self.tail[i] == c'-') and i < self.size:
             i = i + 1
 
@@ -147,14 +140,14 @@
             ret = PyInt_FromString(self.tail, NULL, 10)
         finally:
             self.tail[i] = c'e'
-        UPDATE_TAIL(self, i+1)
+        D_UPDATE_TAIL(self, i+1)
         return ret
 
     cdef object _decode_string(self):
         cdef int n, i
         i = self._read_digits(c':')
         n = strtol(self.tail, NULL, 10)
-        UPDATE_TAIL(self, i+1)
+        D_UPDATE_TAIL(self, i+1)
         if n == 0:
             return ''
         if n > self.size:
@@ -163,7 +156,7 @@
             raise ValueError('string size below zero: %d' % n)
 
         result = PyString_FromStringAndSize(self.tail, n)
-        UPDATE_TAIL(self, n)
+        D_UPDATE_TAIL(self, n)
         return result
 
     cdef object _decode_list(self):
@@ -171,7 +164,7 @@
 
         while self.size > 0:
             if self.tail[0] == c'e':
-                UPDATE_TAIL(self, 1)
+                D_UPDATE_TAIL(self, 1)
                 if self._yield_tuples:
                     return tuple(result)
                 else:
@@ -190,7 +183,7 @@
         while self.size > 0:
             ch = self.tail[0]
             if ch == c'e':
-                UPDATE_TAIL(self, 1)
+                D_UPDATE_TAIL(self, 1)
                 return result
             else:
                 # keys should be strings only
@@ -227,9 +220,11 @@
     INT_BUF_SIZE = 32
 
 
-cdef class Encoder(Coder):
+cdef class Encoder:
     """Bencode encoder"""
 
+    cdef readonly char *tail
+    cdef readonly int size
     cdef readonly char *buffer
     cdef readonly int maxsize
 
@@ -285,11 +280,6 @@
         self.tail = &new_buffer[self.size]
         return 1
 
-    cdef void _update_tail(self, int n):
-        """Update tail pointer and resulting size by n characters"""
-        self.size = self.size + n
-        self.tail = &self.tail[n]
-
     cdef int _encode_int(self, int x) except 0:
         """Encode int to bencode string iNNNe
         @param  x:  value to encode
@@ -299,45 +289,49 @@
         n = snprintf(self.tail, INT_BUF_SIZE, "i%de", x)
         if n < 0:
             raise MemoryError('int %d too big to encode' % x)
-        UPDATE_TAIL(self, n)
+        E_UPDATE_TAIL(self, n)
         return 1
 
     cdef int _encode_long(self, x) except 0:
         return self._append_string(''.join(('i', str(x), 'e')))
 
     cdef int _append_string(self, s) except 0:
-        self._ensure_buffer(PyString_GET_SIZE(s))
-        memcpy(self.tail, PyString_AS_STRING(s), PyString_GET_SIZE(s))
-        UPDATE_TAIL(self, PyString_GET_SIZE(s))
+        cdef Py_ssize_t n
+        n = PyString_GET_SIZE(s)
+        self._ensure_buffer(n)
+        memcpy(self.tail, PyString_AS_STRING(s), n)
+        E_UPDATE_TAIL(self, n)
         return 1
 
     cdef int _encode_string(self, x) except 0:
         cdef int n
-        self._ensure_buffer(PyString_GET_SIZE(x) + INT_BUF_SIZE)
-        n = snprintf(self.tail, INT_BUF_SIZE, '%d:', PyString_GET_SIZE(x))
+        cdef Py_ssize_t x_len
+        x_len = PyString_GET_SIZE(x)
+        self._ensure_buffer(x_len + INT_BUF_SIZE)
+        n = snprintf(self.tail, INT_BUF_SIZE, '%d:', x_len)
         if n < 0:
             raise MemoryError('string %s too big to encode' % x)
-        memcpy(<void *>(self.tail+n), PyString_AS_STRING(x),
-               PyString_GET_SIZE(x))
-        UPDATE_TAIL(self, n+PyString_GET_SIZE(x))
+        memcpy(<void *>(self.tail+n), PyString_AS_STRING(x), x_len)
+        E_UPDATE_TAIL(self, n + x_len)
         return 1
 
     cdef int _encode_list(self, x) except 0:
-        self._ensure_buffer(2)
+        self._ensure_buffer(1)
         self.tail[0] = c'l'
-        UPDATE_TAIL(self, 1)
+        E_UPDATE_TAIL(self, 1)
 
         for i in x:
             self.process(i)
 
+        self._ensure_buffer(1)
         self.tail[0] = c'e'
-        UPDATE_TAIL(self, 1)
+        E_UPDATE_TAIL(self, 1)
         return 1
 
     cdef int _encode_dict(self, x) except 0:
-        self._ensure_buffer(2)
+        self._ensure_buffer(1)
         self.tail[0] = c'd'
-        UPDATE_TAIL(self, 1)
+        E_UPDATE_TAIL(self, 1)
 
         keys = x.keys()
         keys.sort()
@@ -347,8 +341,9 @@
             self._encode_string(k)
             self.process(x[k])
 
+        self._ensure_buffer(1)
         self.tail[0] = c'e'
-        UPDATE_TAIL(self, 1)
+        E_UPDATE_TAIL(self, 1)
         return 1
 
     def process(self, object x):



More information about the bazaar-commits mailing list