Ejemplo n.º 1
0
 def _accept_integral(self, meth):
     space = self.space
     w_obj = self.accept_obj_arg()
     if (space.isinstance_w(w_obj, space.w_int)
             or space.isinstance_w(w_obj, space.w_long)):
         w_index = w_obj
     else:
         w_index = None
         if space.lookup(w_obj, '__index__'):
             try:
                 w_index = space.index(w_obj)
             except OperationError as e:
                 if not e.match(space, space.w_TypeError):
                     raise
                 pass
         if w_index is None and space.lookup(w_obj, '__int__'):
             if space.isinstance_w(w_obj, space.w_float):
                 msg = "integer argument expected, got float"
             else:
                 msg = "integer argument expected, got non-integer" \
                       " (implicit conversion using __int__ is deprecated)"
             space.warn(space.newtext(msg), space.w_DeprecationWarning)
             w_index = space.int(
                 w_obj)  # wrapped float -> wrapped int or long
         if w_index is None:
             raise StructError("cannot convert argument to integer")
     method = getattr(space, meth)
     try:
         return method(w_index)
     except OperationError as e:
         if e.match(self.space, self.space.w_OverflowError):
             raise StructError("argument out of range")
         raise
Ejemplo n.º 2
0
 def accept_obj_arg(self):
     try:
         w_obj = self.args_w[self.args_index]
     except IndexError:
         raise StructError("struct format requires more arguments")
     self.args_index += 1
     return w_obj
Ejemplo n.º 3
0
 def read(self, count):
     end = self.inputpos + count
     if end > len(self.input):
         raise StructError("unpack str size too short for format")
     s = self.input[self.inputpos : end]
     self.inputpos = end
     return s
Ejemplo n.º 4
0
 def read(self, count):
     end = self.pos + count
     if end > self.length:
         raise StructError("unpack str size too short for format")
     s = self.buf.getslice(self.pos, end, 1, count)
     self.pos = end
     return s
Ejemplo n.º 5
0
def pack_unichar(fmtiter):
    unistr = fmtiter.accept_unicode_arg()
    if len(unistr) != 1:
        raise StructError("expected a unicode string of length 1")
    c = unistr[0]  # string->char conversion for the annotator
    unichar.pack_unichar(c, fmtiter.wbuf, fmtiter.pos)
    fmtiter.advance(unichar.UNICODE_SIZE)
Ejemplo n.º 6
0
def pack_unichar(fmtiter):
    utf8, lgt = fmtiter.accept_unicode_arg()
    if lgt != 1:
        raise StructError("expected a unicode string of length 1")
    uchr = rutf8.codepoint_at_pos(utf8, 0)
    unichar.pack_codepoint(uchr, fmtiter.wbuf, fmtiter.pos)
    fmtiter.advance(unichar.UNICODE_SIZE)
Ejemplo n.º 7
0
def pack_char(fmtiter):
    string = fmtiter.accept_str_arg()
    if len(string) != 1:
        raise StructError("expected a string of length 1")
    c = string[0]  # string->char conversion for the annotator
    fmtiter.wbuf.setitem(fmtiter.pos, c)
    fmtiter.advance(1)
Ejemplo n.º 8
0
def unpack_pascal(fmtiter, count):
    if count == 0:
        raise StructError("bad '0p' in struct format")
    data = fmtiter.read(count)
    end = 1 + ord(data[0])
    if end > count:
        end = count
    fmtiter.appendobj(data[1:end])
Ejemplo n.º 9
0
 def accept_float_arg(self):
     w_obj = self.accept_obj_arg()
     try:
         return self.space.float_w(w_obj)
     except OperationError as e:
         if e.match(self.space, self.space.w_TypeError):
             raise StructError("required argument is not a float")
         raise
Ejemplo n.º 10
0
 def skip(self, count):
     # assumption: UnpackFormatIterator only iterates over
     # flat structures (continous memory) either: forward (index
     # grows) or reverse
     if self.strides:
         assert len(self.strides) == 1
         count = self.strides[0]
     end = self.pos + count
     if end > self.length:
         raise StructError("unpack str size too short for format")
     self.pos = end
Ejemplo n.º 11
0
def pack_pascal(fmtiter, count):
    string = fmtiter.accept_str_arg()
    prefix = len(string)
    if prefix >= count:
        prefix = count - 1
        if prefix < 0:
            raise StructError("bad '0p' in struct format")
    if prefix > 255:
        prefix = 255
    fmtiter.wbuf.setitem(fmtiter.pos, chr(prefix))
    fmtiter.advance(1)
    _pack_string(fmtiter, string, count - 1)
Ejemplo n.º 12
0
 def pack_int(fmtiter):
     method = getattr(fmtiter, accept_method)
     value = method()
     if not min <= value <= max:
         raise StructError(errormsg)
     if fmtiter.bigendian:
         for i in unroll_revrange_size:
             x = (value >> (8*i)) & 0xff
             fmtiter.result.append(chr(x))
     else:
         for i in unroll_revrange_size:
             fmtiter.result.append(chr(value & 0xff))
             value >>= 8
Ejemplo n.º 13
0
def pack_pascal(fmtiter, count):
    string = fmtiter.accept_str_arg()
    prefix = len(string)
    if prefix >= count:
        prefix = count - 1
        if prefix < 0:
            raise StructError("bad '0p' in struct format")
    if prefix > 255:
        prefixchar = '\xff'
    else:
        prefixchar = chr(prefix)
    fmtiter.result.append(prefixchar)
    fmtiter.result.append_slice(string, 0, prefix)
    fmtiter.result.append_multiple_char('\x00', count - (1 + prefix))
Ejemplo n.º 14
0
 def _accept_integral(self, meth):
     space = self.space
     w_obj = self.accept_obj_arg()
     if space.isinstance_w(w_obj, space.w_int):
         w_index = w_obj
     else:
         w_index = None
         if space.lookup(w_obj, '__index__'):
             try:
                 w_index = space.index(w_obj)
             except OperationError as e:
                 if not e.match(space, space.w_TypeError):
                     raise
                 pass
         if w_index is None:
             raise StructError("required argument is not an integer")
     method = getattr(space, meth)
     try:
         return method(w_index)
     except OperationError as e:
         if e.match(self.space, self.space.w_OverflowError):
             raise StructError("argument out of range")
         raise
Ejemplo n.º 15
0
 def _accept_integral(self, meth):
     space = self.space
     w_obj = self.accept_obj_arg()
     if space.isinstance_w(w_obj, space.w_int):
         w_index = w_obj
     else:
         w_index = None
         if space.lookup(w_obj, '__index__'):
             try:
                 w_index = space.index(w_obj)
             except OperationError, e:
                 if not e.match(space, space.w_TypeError):
                     raise
                 pass
         if w_index is None:
             raise StructError("required argument is not an integer")
Ejemplo n.º 16
0
    def pack_int(fmtiter):
        method = getattr(fmtiter, accept_method)
        value = method()
        if not min <= value <= max:
            raise StructError(errormsg)
        #
        if pack_fastpath(TYPE)(fmtiter, value):
            return
        #
        pos = fmtiter.pos + size - 1
        if fmtiter.bigendian:
            for i in unroll_revrange_size:
                x = (value >> (8 * i)) & 0xff
                fmtiter.wbuf.setitem(pos - i, chr(x))
        else:

            for i in unroll_revrange_size:
                fmtiter.wbuf.setitem(pos - i, chr(value & 0xff))
                value >>= 8
        fmtiter.advance(size)
Ejemplo n.º 17
0
 def align(self, mask):
     pad = (-self.totalsize) & mask
     try:
         self.totalsize = ovfcheck(self.totalsize + pad)
     except OverflowError:
         raise StructError("total struct size too long")
Ejemplo n.º 18
0
 def operate(self, fmtdesc, repetitions):
     try:
         size = ovfcheck(fmtdesc.size * repetitions)
         self.totalsize = ovfcheck(self.totalsize + size)
     except OverflowError:
         raise StructError("total struct size too long")
Ejemplo n.º 19
0
    def interpret(self, fmt):
        # decode the byte order, size and alignment based on the 1st char
        table = unroll_native_fmtdescs
        self.bigendian = native_is_bigendian
        index = 0
        if len(fmt) > 0:
            c = fmt[0]
            index = 1
            if c == '@':
                pass
            elif c == '=':
                table = unroll_standard_fmtdescs
            elif c == '<':
                table = unroll_standard_fmtdescs
                self.bigendian = False
            elif c == '>' or c == '!':
                table = unroll_standard_fmtdescs
                self.bigendian = True
            else:
                index = 0

        # interpret the format string,
        # calling self.operate() for each format unit
        while index < len(fmt):
            c = fmt[index]
            index += 1
            if c.isspace():
                continue
            if c.isdigit():
                repetitions = ord(c) - ord('0')
                while True:
                    if index == len(fmt):
                        raise StructError("incomplete struct format")
                    c = fmt[index]
                    index += 1
                    if not c.isdigit():
                        break
                    try:
                        repetitions = ovfcheck(repetitions * 10)
                        repetitions = ovfcheck(repetitions + (ord(c) -
                                                              ord('0')))
                    except OverflowError:
                        raise StructError("overflow in item count")
                assert repetitions >= 0
            else:
                repetitions = 1

            for fmtdesc in table:
                if c == fmtdesc.fmtchar:
                    if self._operate_is_specialized_:
                        if fmtdesc.alignment > 1:
                            self.align(fmtdesc.mask)
                        self.operate(fmtdesc, repetitions)
                    break
            else:
                if c == '\0':
                    raise StructError("embedded null character")
                raise StructError("bad char in struct format")
            if not self._operate_is_specialized_:
                if fmtdesc.alignment > 1:
                    self.align(fmtdesc.mask)
                self.operate(fmtdesc, repetitions)
        self.finished()
Ejemplo n.º 20
0
def pack_unichar(fmtiter):
    unistr = fmtiter.accept_unicode_arg()
    if len(unistr) != 1:
        raise StructError("expected a unicode string of length 1")
    c = unistr[0]  # string->char conversion for the annotator
    unichar.pack_unichar(c, fmtiter.result)
Ejemplo n.º 21
0
 def finished(self):
     value = self.pos
     if self.strides and self.strides[0] < 0:
         value = -self.pos
     if value != self.length:
         raise StructError("unpack str size too long for format")
Ejemplo n.º 22
0
 def finished(self):
     if self.pos != self.length:
         raise StructError("unpack str size too long for format")
Ejemplo n.º 23
0
 def advance(self, count):
     if not self.can_advance(count):
         raise StructError("unpack str size too short for format")
     self.pos += count
Ejemplo n.º 24
0
 def finished(self):
     if self.args_index != len(self.args_w):
         raise StructError("too many arguments for struct format")
Ejemplo n.º 25
0
class PackFormatIterator(FormatIterator):
    def __init__(self, space, args_w, size):
        self.space = space
        self.args_w = args_w
        self.args_index = 0
        self.result = StringBuilder(size)

    # This *should* be always unroll safe, the only way to get here is by
    # unroll the interpret function, which means the fmt is const, and thus
    # this should be const (in theory ;)
    @jit.unroll_safe
    @specialize.arg(1)
    def operate(self, fmtdesc, repetitions):
        if fmtdesc.needcount:
            fmtdesc.pack(self, repetitions)
        else:
            for i in range(repetitions):
                fmtdesc.pack(self)

    _operate_is_specialized_ = True

    @jit.unroll_safe
    def align(self, mask):
        pad = (-self.result.getlength()) & mask
        self.result.append_multiple_char('\x00', pad)

    def finished(self):
        if self.args_index != len(self.args_w):
            raise StructError("too many arguments for struct format")

    def accept_obj_arg(self):
        try:
            w_obj = self.args_w[self.args_index]
        except IndexError:
            raise StructError("struct format requires more arguments")
        self.args_index += 1
        return w_obj

    def accept_int_arg(self):
        return self._accept_integral("int_w")

    def accept_uint_arg(self):
        return self._accept_integral("uint_w")

    def accept_longlong_arg(self):
        return self._accept_integral("r_longlong_w")

    def accept_ulonglong_arg(self):
        return self._accept_integral("r_ulonglong_w")

    @specialize.arg(1)
    def _accept_integral(self, meth):
        space = self.space
        w_obj = self.accept_obj_arg()
        if (space.isinstance_w(w_obj, space.w_int)
                or space.isinstance_w(w_obj, space.w_long)):
            w_index = w_obj
        else:
            w_index = None
            if space.lookup(w_obj, '__index__'):
                try:
                    w_index = space.index(w_obj)
                except OperationError, e:
                    if not e.match(space, space.w_TypeError):
                        raise
                    pass
            if w_index is None and space.lookup(w_obj, '__int__'):
                if space.isinstance_w(w_obj, space.w_float):
                    msg = "integer argument expected, got float"
                else:
                    msg = "integer argument expected, got non-integer" \
                          " (implicit conversion using __int__ is deprecated)"
                space.warn(space.wrap(msg), space.w_DeprecationWarning)
                w_index = space.int(
                    w_obj)  # wrapped float -> wrapped int or long
            if w_index is None:
                raise StructError("cannot convert argument to integer")
        method = getattr(space, meth)
        try:
            return method(w_index)
        except OperationError as e:
            if e.match(self.space, self.space.w_OverflowError):
                raise StructError("argument out of range")
            raise
Ejemplo n.º 26
0
def pack_char(fmtiter):
    string = fmtiter.accept_str_arg()
    if len(string) != 1:
        raise StructError("expected a string of length 1")
    c = string[0]   # string->char conversion for the annotator
    fmtiter.result.append(c)