Skip to content

Commit

Permalink
Improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
comex committed Feb 27, 2009
1 parent 9e290e2 commit 10516d4
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
25 changes: 23 additions & 2 deletions r2/muting/muting.pyx
@@ -1,16 +1,21 @@
# A LOT faster than the python version, which has to allocate new strings for setslice
cdef extern from "Python.h":
object PyString_FromStringAndSize(char *s, Py_ssize_t len)
char* PyString_AsString(object string)
int PyString_Check(object o)

cdef extern from "stdlib.h":
void *memcpy(void *dest, void *src, int size)
void *malloc(int size)
int memcmp(void *s1, void *s2, int n)
void free(void *ptr)

cdef inline char* mycopy(char* dest, int plus, char* frum, int size):
memcpy(dest + plus, frum, size)
cdef object my_sas(char *st, int offs, int len):
cdef inline object my_sas(char *st, int offs, int len):
return PyString_FromStringAndSize(st + offs, len)
cdef inline void my_setitem(char *dest, int offs, char val):
dest[offs] = val
cdef class MutableString:
cdef char* mystring
cdef int size
Expand All @@ -24,6 +29,18 @@ cdef class MutableString:
def __dealloc__(self):
if <int>(self.mystring) != 0:
free(<void *> self.mystring)
def __getitem__(self, i):
if i >= self.size or i < -self.size:
raise IndexError('string index out of range')
return my_sas(self.mystring, i % self.size, 1)

def __setitem__(self, i, val):
if i >= self.size or i < -self.size:
raise IndexError('string index out of range')
if len(val) != 1:
raise ValueError('can\'t set to this')
my_setitem(self.mystring, i, (PyString_AsString(val))[0])

def __getslice__(self, i, j):
# From stringobject.c
if i < 0: i = 0
Expand All @@ -40,9 +57,13 @@ cdef class MutableString:
if sz != len(st):
raise Exception('Wrong size.')
mycopy(self.mystring, i, st, j-i)
def __hash__(self):
return hash(str(self)) # TODO: This sucks
def __cmp__(self, other):
return memcmp(self.mystring, (<MutableString>other).mystring, self.size)
def __len__(self):
return self.size
def __str__(self):
return PyString_FromStringAndSize(self.mystring, self.size)
def __repr__(self):
return 'm' + repr(str(self))
return 'm' + repr(str(self))
14 changes: 13 additions & 1 deletion r2/muting/testmuting.py
@@ -1,9 +1,21 @@
from muting import MutableString
st = 'test test'
a = MutableString(st)
def maybe(x):
try:
return x()
except Exception, e:
return str(e)
for i in xrange(-30, 30):
for j in xrange(-30, 30):
if a[i:j] != st[i:j]:
print i, j, repr(a[i:j]), repr(st[i:j])
for i in xrange(-30, 30):
if maybe(lambda: a[i]) != maybe(lambda: st[i]):
print i, maybe(lambda: a[i]), maybe(lambda: st[i])
a[2:5] = 'foo'
print str(a)
a[1] = 'q'
print a
q = {a: 1, 'tqfootest': 2}
print q
print a.__cmp__(MutableString('tqfootest')) # Python limitations say I can't have it == 'tqfootest'

0 comments on commit 10516d4

Please sign in to comment.