1
from pypy.rpython.lltypesystem import lltype
2
from pypy.annotation.pairtype import pairtype
3
from pypy.rpython.rmodel import IntegerRepr, inputconst
4
from pypy.rpython.rctypes.rmodel import CTypesRefRepr
5
from pypy.objspace.flow.model import Constant
6
from pypy.rpython.rslice import AbstractSliceRepr
7
from pypy.rpython.lltypesystem.rstr import string_repr
8
from pypy.rpython.error import TyperError
10
class StringBufRepr(CTypesRefRepr):
12
def rtype_len(self, hop):
13
[v_stringbuf] = hop.inputargs(self)
14
v_array = self.get_c_data(hop.llops, v_stringbuf)
15
return hop.genop('getarraysize', [v_array],
16
resulttype = lltype.Signed)
18
def rtype_getattr(self, hop):
19
s_attr = hop.args_s[1]
20
assert s_attr.is_constant()
21
v_box = hop.inputarg(self, 0)
22
hop.exception_cannot_occur()
23
if s_attr.const == 'value':
24
from pypy.rpython.rctypes.rarray import ll_chararrayvalue
25
return hop.gendirectcall(ll_chararrayvalue, v_box)
26
elif s_attr.const == 'raw':
27
return hop.gendirectcall(ll_stringbufraw, v_box)
29
raise TyperError("StringBufRepr has no attribute %r" % (
32
def rtype_setattr(self, hop):
33
s_attr = hop.args_s[1]
34
assert s_attr.is_constant()
35
assert s_attr.const in ('value', 'raw')
36
v_box, v_attr, v_value = hop.inputargs(self, lltype.Void, string_repr)
37
hop.gendirectcall(ll_stringbuf_setvalue_from_string, v_box, v_value)
39
def get_c_data_of_item(self, llops, v_stringbuf, v_index):
40
v_array = self.get_c_data(llops, v_stringbuf)
41
v_char_p = llops.genop('direct_arrayitems', [v_array],
42
resulttype = ONE_CHAR_PTR)
43
if isinstance(v_index, Constant) and v_index.value == 0:
44
pass # skip direct_ptradd
46
v_char_p = llops.genop('direct_ptradd', [v_char_p, v_index],
47
resulttype = ONE_CHAR_PTR)
51
ONE_CHAR_PTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))
54
class __extend__(pairtype(StringBufRepr, IntegerRepr)):
55
def rtype_getitem((r_stringbuf, r_int), hop):
56
v_stringbuf, v_index = hop.inputargs(r_stringbuf, lltype.Signed)
57
v_array = r_stringbuf.get_c_data(hop.llops, v_stringbuf)
58
hop.exception_cannot_occur()
59
return hop.genop('getarrayitem', [v_array, v_index],
60
resulttype = lltype.Char)
62
def rtype_setitem((r_stringbuf, r_int), hop):
63
v_stringbuf, v_index, v_item = hop.inputargs(r_stringbuf,
66
v_array = r_stringbuf.get_c_data(hop.llops, v_stringbuf)
67
hop.exception_cannot_occur()
68
hop.genop('setarrayitem', [v_array, v_index, v_item])
70
class __extend__(pairtype(StringBufRepr, AbstractSliceRepr)):
71
def rtype_getitem((r_stringbuf, r_slice), hop):
72
rs = r_stringbuf.rtyper.type_system.rslice
73
if r_slice == rs.startonly_slice_repr:
74
v_stringbuf, v_start = hop.inputargs(r_stringbuf, rs.startonly_slice_repr)
75
v_array = r_stringbuf.get_c_data(hop.llops, v_stringbuf)
76
return hop.gendirectcall(ll_slice_startonly, v_array, v_start)
77
if r_slice == rs.startstop_slice_repr:
78
v_stringbuf, v_slice = hop.inputargs(r_stringbuf, rs.startstop_slice_repr)
79
v_array = r_stringbuf.get_c_data(hop.llops, v_stringbuf)
80
return hop.gendirectcall(ll_slice, v_array, v_slice)
81
raise TyperError('getitem does not support slices with %r' % (r_slice,))
83
def ll_slice_startonly(sbuf, start):
84
return ll_slice_start_stop(sbuf, start, len(sbuf))
86
def ll_slice(sbuf, slice):
87
return ll_slice_start_stop(sbuf, slice.start, slice.stop)
89
def ll_slice_start_stop(sbuf, start, stop):
92
start = length + start
103
newlength = stop - start
104
newstr = lltype.malloc(string_repr.lowleveltype.TO, newlength)
106
for i in range(newlength):
107
newstr.chars[i] = sbuf[start + i]
111
def ll_stringbuf_setvalue_from_string(box, s):
112
# Copy the string into the stringbuf. In ctypes the final \x00 is
113
# copied unless the string has exactly the same size as the stringbuf.
114
# We do the same, but unlike ctypes don't raise ValueError if the
115
# string is longer than the stringbuf; we just truncate instead.
116
# There is no support for setattr raising exceptions in RPython so far.
118
n = min(len(s.chars) + 1, len(p))
122
def ll_stringbufraw(box):
125
newstr = lltype.malloc(string_repr.lowleveltype.TO, length)
127
for i in range(length):
128
newstr.chars[i] = p[i]
131
STRBUFTYPE = lltype.Array(lltype.Char)