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