File: interp_builders.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (102 lines) | stat: -rw-r--r-- 4,104 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import oefmt
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
from rpython.rlib.rstring import StringBuilder
from rpython.rlib.rutf8 import StringBuilder, Utf8StringBuilder
from pypy.objspace.std.unicodeobject import W_UnicodeObject
from rpython.tool.sourcetools import func_with_new_name


class W_BytesBuilder(W_Root):
    def __init__(self, space, size):
        if size < 0:
            self.builder = StringBuilder()
        else:
            self.builder = StringBuilder(size)

    @unwrap_spec(size=int)
    def descr__new__(space, w_subtype, size=-1):
        return W_BytesBuilder(space, size)

    @unwrap_spec(s='bytes')
    def descr_append(self, space, s):
        self.builder.append(s)

    @unwrap_spec(s='bytes', start=int, end=int)
    def descr_append_slice(self, space, s, start, end):
        if not 0 <= start <= end <= len(s):
            raise oefmt(space.w_ValueError, "bad start/stop")
        self.builder.append_slice(s, start, end)

    def descr_build(self, space):
        w_s = space.newbytes(self.builder.build())
        # after build(), we can continue to append more strings
        # to the same builder.  This is supported since
        # 2ff5087aca28 in RPython.
        return w_s

    def descr_len(self, space):
        if self.builder is None:
            raise oefmt(space.w_ValueError, "no length of built builder")
        return space.newint(self.builder.getlength())

W_BytesBuilder.typedef = TypeDef("BytesBuilder",
    __new__ = interp2app(func_with_new_name(
                                W_BytesBuilder.descr__new__.im_func,
                                'BytesBuilder_new')),
    append = interp2app(W_BytesBuilder.descr_append),
    append_slice = interp2app(W_BytesBuilder.descr_append_slice),
    build = interp2app(W_BytesBuilder.descr_build),
    __len__ = interp2app(W_BytesBuilder.descr_len),
)
W_BytesBuilder.typedef.acceptable_as_base_class = False

class W_UnicodeBuilder(W_Root):
    def __init__(self, space, size):
        if size < 0:
            self.builder = Utf8StringBuilder()
        else:
            self.builder = Utf8StringBuilder(size)

    @unwrap_spec(size=int)
    def descr__new__(space, w_subtype, size=-1):
        return W_UnicodeBuilder(space, 3 * size)

    def descr_append(self, space, w_s):
        if not isinstance(w_s, W_UnicodeObject):
            w_s = W_UnicodeObject.convert_arg_to_w_unicode(space, w_s)
        self.builder.append_utf8(w_s._utf8, w_s._len())

    @unwrap_spec(start=int, end=int)
    def descr_append_slice(self, space, w_s, start, end):
        w_unicode = W_UnicodeObject.convert_arg_to_w_unicode(space, w_s)
        if not 0 <= start <= end <= w_unicode._len():
            raise oefmt(space.w_ValueError, "bad start/stop")
        byte_start = w_unicode._index_to_byte(start)
        byte_end = w_unicode._index_to_byte(end)
        self.builder.append_utf8_slice(w_unicode._utf8, byte_start, byte_end, end - start)

    def descr_build(self, space):
        w_s = space.newutf8(self.builder.build(), self.builder.getlength())
        # after build(), we can continue to append more strings
        # to the same builder.  This is supported since
        # 2ff5087aca28 in RPython.
        return w_s

    def descr_len(self, space):
        if self.builder is None:
            raise oefmt(space.w_ValueError, "no length of built builder")
        return space.newint(self.builder.getlength())

W_UnicodeBuilder.typedef = TypeDef("StringBuilder",
    __new__ = interp2app(func_with_new_name(
                                W_UnicodeBuilder.descr__new__.im_func,
                                'UnicodeBuilder_new')),
    append = interp2app(W_UnicodeBuilder.descr_append),
    append_slice = interp2app(W_UnicodeBuilder.descr_append_slice),
    build = interp2app(W_UnicodeBuilder.descr_build),
    __len__ = interp2app(W_UnicodeBuilder.descr_len),
)
W_UnicodeBuilder.typedef.acceptable_as_base_class = False
W_StringBuilder = W_UnicodeBuilder