Ejemplo n.º 1
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.º 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 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.º 4
0
 def pack_int(fmtiter):
     method = getattr(fmtiter, accept_method)
     value = method()
     if check_range:
         if value < min or 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.º 5
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.º 6
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 += string[:prefix]
    for i in range(1 + prefix, count):
        fmtiter.result.append('\x00')
Ejemplo n.º 7
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.º 8
0
 def finished(self):
     if self.inputpos != len(self.input):
         raise StructError('unpack str size too long for format')
Ejemplo n.º 9
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.º 10
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.º 11
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:
                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.º 12
0
 def finished(self):
     if self.args_index != len(self.args_w):
         raise StructError("too many arguments for struct format")
Ejemplo n.º 13
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)