~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to pypy/rpython/rctypes/rstringbuf.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
9
 
 
10
class StringBufRepr(CTypesRefRepr):
 
11
 
 
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)
 
17
 
 
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)
 
28
        else:
 
29
            raise TyperError("StringBufRepr has no attribute %r" % (
 
30
                s_attr.const,))
 
31
 
 
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)
 
38
 
 
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
 
45
        else:
 
46
            v_char_p = llops.genop('direct_ptradd', [v_char_p, v_index],
 
47
                                   resulttype = ONE_CHAR_PTR)
 
48
        return v_char_p
 
49
 
 
50
 
 
51
ONE_CHAR_PTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))
 
52
 
 
53
 
 
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)
 
61
 
 
62
    def rtype_setitem((r_stringbuf, r_int), hop):
 
63
        v_stringbuf, v_index, v_item = hop.inputargs(r_stringbuf,
 
64
                                                     lltype.Signed,
 
65
                                                     lltype.Char)
 
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])
 
69
 
 
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,))
 
82
 
 
83
def ll_slice_startonly(sbuf, start):
 
84
    return ll_slice_start_stop(sbuf, start, len(sbuf))
 
85
    
 
86
def ll_slice(sbuf, slice):
 
87
    return ll_slice_start_stop(sbuf, slice.start, slice.stop)
 
88
 
 
89
def ll_slice_start_stop(sbuf, start, stop):
 
90
    length = len(sbuf)
 
91
    if start < 0:
 
92
        start = length + start
 
93
    if start < 0:
 
94
        start = 0
 
95
    if stop < 0:
 
96
        stop = length + stop
 
97
    if stop < 0:
 
98
        stop = 0
 
99
    if stop > length:
 
100
        stop = length
 
101
    if start > stop:
 
102
        start = stop
 
103
    newlength = stop - start
 
104
    newstr = lltype.malloc(string_repr.lowleveltype.TO, newlength)
 
105
    newstr.hash = 0
 
106
    for i in range(newlength):
 
107
        newstr.chars[i] = sbuf[start + i]
 
108
    return newstr
 
109
 
 
110
 
 
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.
 
117
    p = box.c_data
 
118
    n = min(len(s.chars) + 1, len(p))
 
119
    for i in range(n):
 
120
        p[i] = s.chars[i]
 
121
 
 
122
def ll_stringbufraw(box):
 
123
    p = box.c_data
 
124
    length = len(p)
 
125
    newstr = lltype.malloc(string_repr.lowleveltype.TO, length)
 
126
    newstr.hash = 0
 
127
    for i in range(length):
 
128
        newstr.chars[i] = p[i]
 
129
    return newstr
 
130
 
 
131
STRBUFTYPE = lltype.Array(lltype.Char)