Exemplo n.º 1
0
    def _decode_header(self):
        magic = self.reader.read_uint32()

        if (hex(magic) != const.SRL_MAGIC_STRING_HIGHBIT_UINT_LE):
            raise exception.SrlError('bad header: invalid magic string')

        doc_version_type = self.reader.read_uint8()
        doc_version = (doc_version_type & 15)
        doc_type = (doc_version_type >> 4) & 15

        if (doc_version not in [3, 4]):
            raise exception.SrlError(
                'bad header: unsupported protocol version {}'.format(
                    doc_version))

        if (doc_type < 0 or doc_type > 3):
            raise exception.SrlError(
                'bad header: unsupported document type {}'.format(doc_type))

        header_suffix_size = self.reader.read_varint()
        if header_suffix_size:
            # Skipping the suffix.
            self.reader._read_unpack('{0}s'.format(header_suffix_size))

        self.header['version'] = doc_version
        self.header['type'] = doc_type
Exemplo n.º 2
0
    def _decode_bytes(self):
        tag = self.reader.read_uint8()

        track_pos = None

        if (tag & const.SRL_TRACK_BIT) != 0:
            tag = tag & ~const.SRL_TRACK_BIT
            track_pos = self.reader.tell() - self.body_offset

        if (tag >= const.SRL_TYPE_POS_0 and tag < const.SRL_TYPE_POS_0 + 16):
            return int(tag)

        elif tag >= const.SRL_NEG_16 and tag < const.SRL_NEG_16 + 16:
            return int(tag) - 32

        elif tag == const.SRL_TYPE_FLOAT:
            return self.reader.read_float()

        elif tag == const.SRL_TYPE_VARINT:
            return self.reader.read_varint()

        elif tag == const.SRL_TYPE_UNDEF:
            return None

        elif (tag == const.SRL_TYPE_BINARY):
            return self._decode_binary(tag)

        elif (tag == const.SRL_TYPE_REFN):
            return self._decode_refn(tag)

        elif tag == const.SRL_TYPE_REFP:
            return self._decode_refp()

        elif (tag == const.SRL_TYPE_HASH):
            ln = self.reader.read_varint()
            return self._decode_hash(ln, track_pos)

        elif (tag == const.SRL_TYPE_ARRAY):
            ln = self.reader.read_varint()
            return self._decode_array(ln, track_pos)

        elif tag == const.SRL_TYPE_COPY:
            return self._get_copy()

        elif (tag >= const.SRL_TYPE_ARRAYREF_0
              and tag < const.SRL_TYPE_ARRAYREF_0 + 16):
            ln = tag & 15
            return self._decode_array(ln, track_pos)

        elif (tag >= const.SRL_TYPE_HASHREF_0
              and tag < const.SRL_TYPE_HASHREF_0 + 16):
            ln = tag & 15
            return self._decode_hash(ln, track_pos)

        elif (tag >= const.SRL_TYPE_SHORT_BINARY_0
              and tag < const.SRL_TYPE_SHORT_BINARY_0 + 32):
            return self._decode_short_binary(tag)

        else:
            raise exception.SrlError('bad tag: unsupported tag {}'.format(tag))
Exemplo n.º 3
0
    def _get_copy(self):
        if self.copy_depth > 0:
            raise exception.SrlError('bad nested copy tag: recursive copy tag found')

        copy_pos = self.reader.read_varint()
        copy_pos += self.body_offset-1

        curr_pos = self.reader.tell()

        self.reader.seek(copy_pos, os.SEEK_SET)
        self.copy_depth += 1
        copy = self._decode_bytes()
        self.copy_depth -= 1
        self.reader.seek(curr_pos, os.SEEK_SET)

        return copy
Exemplo n.º 4
0
    def _decode_tag(self, tag):
        if tag >= const.SRL_TYPE_POS_0 and tag < const.SRL_TYPE_POS_0 + 16:
            return int(tag)

        elif tag >= const.SRL_NEG_16 and tag < const.SRL_NEG_16 + 16:
            return int(tag) - 32

        elif tag == const.SRL_TYPE_FLOAT:
            return self.reader.read_float()

        elif tag == const.SRL_TYPE_DOUBLE:
            return self.reader.read_double()

        elif tag == const.SRL_TYPE_VARINT:
            return self.reader.read_varint()

        elif tag == const.SRL_TYPE_ZIGZAG:
            return self._decode_zigzag()

        elif tag == const.SRL_TYPE_UNDEF:
            return None

        elif tag == const.SRL_TYPE_BINARY:
            return self._decode_binary(tag)

        elif tag == const.SRL_TYPE_STR_UTF8:
            return self._decode_str_utf8(tag)

        elif tag == const.SRL_TYPE_REFN:
            return self._decode_refn(tag)

        elif tag == const.SRL_TYPE_REFP:
            return self._decode_refp()

        elif tag == const.SRL_TYPE_HASH:
            ln = self.reader.read_varint()
            return self._decode_hash(ln)

        elif tag == const.SRL_TYPE_ARRAY:
            ln = self.reader.read_varint()
            return self._decode_array(ln)

        elif tag == const.SRL_TYPE_OBJECT:
            return self._decode_object()

        elif tag == const.SRL_TYPE_OBJECTV:
            return self._decode_objectv()

        elif tag == const.SRL_TYPE_REGEXP:
            pattern = self._decode_bytes()
            flags = self._decode_bytes()
            python_flags = reduce(
                lambda x, y: x | re.RegexFlag[str(y).upper()], flags, 0)
            return re.compile(pattern, python_flags)

        elif tag == const.SRL_TYPE_CANONICAL_UNDEF:
            return None

        elif tag == const.SRL_TYPE_FALSE:
            return False

        elif tag == const.SRL_TYPE_TRUE:
            return True

        elif tag == const.SRL_TYPE_COPY:
            return self._get_copy()

        elif tag >= const.SRL_TYPE_ARRAYREF_0 and tag < const.SRL_TYPE_ARRAYREF_0 + 16:
            ln = tag & 15
            return self._decode_array(ln)

        elif tag >= const.SRL_TYPE_HASHREF_0 and tag < const.SRL_TYPE_HASHREF_0 + 16:
            ln = tag & 15
            return self._decode_hash(ln)

        elif tag >= const.SRL_TYPE_SHORT_BINARY_0 and tag < const.SRL_TYPE_SHORT_BINARY_0 + 32:
            # Note: self.reader.read_str() automatically decodes as utf-8.
            # Thus, this returns a string, instead of returning bytes.
            return self._decode_short_binary(tag)

        else:
            raise exception.SrlError('bad tag: unsupported tag {}'.format(tag))