Пример #1
0
    def write_xpak(cls, target_source, data):
        """
        write an xpak dict to disk; overwriting an xpak if it exists

        :param target_source: string path, or \
          :obj:`snakeoil.data_source.base` derivative
        :param data: mapping instance to write into the xpak.
        :return: xpak instance
        """
        try:
            old_xpak = cls(target_source)
            # force access
            list(old_xpak.keys())
            start = old_xpak.xpak_start
            source_is_path = old_xpak._source_is_path
        except (MalformedXpak, IOError):
            source_is_path = isinstance(target_source, str)
            if source_is_path:
                try:
                    start = os.lstat(target_source).st_size
                except FileNotFoundError:
                    start = 0
            else:
                f = target_source.bytes_fileobj(writable=True)
                f.seek(0, 2)
                start = f.tell()
        new_index = []
        new_data = []
        cur_pos = 0
        for key, val in data.items():
            if isinstance(val, str):
                val = val.encode('utf8')
            if isinstance(key, str):
                key = key.encode()
            new_index.append(struct.pack(
                ">L%isLL" % len(key),
                len(key), key, cur_pos, len(val)))
            new_data.append(val)
            cur_pos += len(val)

        if source_is_path:
            # rb+ required since A) binary, B) w truncates from the getgo
            handle = open(target_source, "r+b")
        else:
            handle = target_source.bytes_fileobj(writable=True)

        joiner = b''
        new_index = joiner.join(new_index)
        new_data = joiner.join(new_data)

        handle.seek(start, 0)
        cls.header.write(
            handle, cls.header_pre_magic, len(new_index), len(new_data))

        handle.write(struct.pack(
            ">%is%is" % (len(new_index), len(new_data)), new_index, new_data))

        # the +8 is for the longs for new_index/new_data
        cls.trailer.write(
            handle, cls.trailer_pre_magic,
            len(new_index) + len(new_data) + cls.trailer.size + 8,
            cls.trailer_post_magic)
        handle.truncate()
        handle.close()
        return Xpak(target_source)
Пример #2
0
    def write_xpak(cls, target_source, data):
        """
        write an xpak dict to disk; overwriting an xpak if it exists

        :param target_source: string path, or \
          :obj:`snakeoil.data_source.base` derivative
        :param data: mapping instance to write into the xpak.
        :return: xpak instance
        """
        try:
            old_xpak = cls(target_source)
            # force access
            list(old_xpak.keys())
            start = old_xpak.xpak_start
            source_is_path = old_xpak._source_is_path
        except (MalformedXpak, IOError):
            source_is_path = isinstance(target_source, str)
            if source_is_path:
                try:
                    start = os.lstat(target_source).st_size
                except FileNotFoundError:
                    start = 0
            else:
                f = target_source.bytes_fileobj(writable=True)
                f.seek(0, 2)
                start = f.tell()
        new_index = []
        new_data = []
        cur_pos = 0
        for key, val in data.items():
            if isinstance(val, str):
                val = val.encode('utf8')
            if isinstance(key, str):
                key = key.encode()
            new_index.append(struct.pack(
                ">L%isLL" % len(key),
                len(key), key, cur_pos, len(val)))
            new_data.append(val)
            cur_pos += len(val)

        if source_is_path:
            # rb+ required since A) binary, B) w truncates from the getgo
            handle = open(target_source, "r+b")
        else:
            handle = target_source.bytes_fileobj(writable=True)

        joiner = b''
        new_index = joiner.join(new_index)
        new_data = joiner.join(new_data)

        handle.seek(start, 0)
        cls.header.write(
            handle, cls.header_pre_magic, len(new_index), len(new_data))

        handle.write(struct.pack(
            ">%is%is" % (len(new_index), len(new_data)), new_index, new_data))

        # the +8 is for the longs for new_index/new_data
        cls.trailer.write(
            handle, cls.trailer_pre_magic,
            len(new_index) + len(new_data) + cls.trailer.size + 8,
            cls.trailer_post_magic)
        handle.truncate()
        handle.close()
        return Xpak(target_source)
Пример #3
0
    def write_xpak(cls, target_source, data):
        """
        write an xpak dict to disk; overwriting an xpak if it exists

        :param target_source: string path, or \
          :obj:`snakeoil.data_source.base` derivative
        :param data: mapping instance to write into the xpak.
        :return: xpak instance
        """
        try:
            old_xpak = cls(target_source)
            # force access
            old_xpak.keys()
            start = old_xpak.xpak_start
            source_is_path = old_xpak._source_is_path
        except (MalformedXpak, IOError):
            source_is_path = isinstance(target_source, basestring)
            if source_is_path:
                try:
                    start = os.lstat(target_source).st_size
                except OSError as e:
                    if e.errno != errno.ENOENT:
                        raise
                    start = 0
            else:
                f = target_source.bytes_fileobj(writable=True)
                f.seek(0, 2)
                start = f.tell()
        new_index = []
        new_data = []
        cur_pos = 0
        for key, val in data.iteritems():
            if isinstance(val, unicode):
                val = val.encode('utf8')
            if isinstance(key, unicode):
                key = key.encode()
            new_index.append(struct.pack(
                ">L%isLL" % len(key),
                len(key), key, cur_pos, len(val)))
            new_data.append(val)
            cur_pos += len(val)

        if source_is_path:
            # rb+ required since A) binary, B) w truncates from the getgo
            handle = open(target_source, "r+b")
        else:
            handle = target_source.bytes_fileobj(writable=True)

        joiner = ''
        if compatibility.is_py3k:
            # can't do str.join(bytes), thus this.
            # written this way since the py3k translator doesn't allow us to
            # just do b''
            joiner = joiner.encode()
        new_index = joiner.join(new_index)
        new_data = joiner.join(new_data)

        handle.seek(start, 0)
        cls.header.write(
            handle, cls.header_pre_magic, len(new_index), len(new_data))

        handle.write(struct.pack(
            ">%is%is" % (len(new_index), len(new_data)), new_index, new_data))

        # the +8 is for the longs for new_index/new_data
        cls.trailer.write(
            handle, cls.trailer_pre_magic,
            len(new_index) + len(new_data) + cls.trailer.size + 8,
            cls.trailer_post_magic)
        handle.truncate()
        handle.close()
        return Xpak(target_source)
Пример #4
0
    def write_xpak(cls, target_source, data):
        """
        write an xpak dict to disk; overwriting an xpak if it exists

        :param target_source: string path, or \
          :obj:`snakeoil.data_source.base` derivative
        :param data: mapping instance to write into the xpak.
        :return: xpak instance
        """
        try:
            old_xpak = cls(target_source)
            # force access
            old_xpak.keys()
            start = old_xpak.xpak_start
            source_is_path = old_xpak._source_is_path
        except (MalformedXpak, IOError):
            source_is_path = isinstance(target_source, basestring)
            if source_is_path:
                try:
                    start = os.lstat(target_source).st_size
                except OSError as e:
                    if e.errno != errno.ENOENT:
                        raise
                    start = 0
            else:
                f = target_source.bytes_fileobj(writable=True)
                f.seek(0, 2)
                start = f.tell()
        new_index = []
        new_data = []
        cur_pos = 0
        for key, val in data.iteritems():
            if isinstance(val, unicode):
                val = val.encode('utf8')
            if isinstance(key, unicode):
                key = key.encode()
            new_index.append(
                struct.pack(">L%isLL" % len(key), len(key), key, cur_pos,
                            len(val)))
            new_data.append(val)
            cur_pos += len(val)

        if source_is_path:
            # rb+ required since A) binary, B) w truncates from the getgo
            handle = open(target_source, "r+b")
        else:
            handle = target_source.bytes_fileobj(writable=True)

        joiner = ''
        if compatibility.is_py3k:
            # can't do str.join(bytes), thus this.
            # written this way since the py3k translator doesn't allow us to
            # just do b''
            joiner = joiner.encode()
        new_index = joiner.join(new_index)
        new_data = joiner.join(new_data)

        handle.seek(start, 0)
        cls.header.write(handle, cls.header_pre_magic, len(new_index),
                         len(new_data))

        handle.write(
            struct.pack(">%is%is" % (len(new_index), len(new_data)), new_index,
                        new_data))

        # the +8 is for the longs for new_index/new_data
        cls.trailer.write(
            handle, cls.trailer_pre_magic,
            len(new_index) + len(new_data) + cls.trailer.size + 8,
            cls.trailer_post_magic)
        handle.truncate()
        handle.close()
        return Xpak(target_source)