mirror of
https://github.com/msgpack/msgpack-python.git
synced 2025-10-23 22:03:18 +00:00
Unpacker: add tell() (#227)
This commit is contained in:
parent
3388e4a6ee
commit
a8d9162ca6
3 changed files with 32 additions and 0 deletions
|
|
@ -29,6 +29,7 @@ cdef extern from "Python.h":
|
||||||
from libc.stdlib cimport *
|
from libc.stdlib cimport *
|
||||||
from libc.string cimport *
|
from libc.string cimport *
|
||||||
from libc.limits cimport *
|
from libc.limits cimport *
|
||||||
|
ctypedef unsigned long long uint64_t
|
||||||
|
|
||||||
from msgpack.exceptions import (
|
from msgpack.exceptions import (
|
||||||
BufferFull,
|
BufferFull,
|
||||||
|
|
@ -314,6 +315,7 @@ cdef class Unpacker(object):
|
||||||
cdef object object_hook, object_pairs_hook, list_hook, ext_hook
|
cdef object object_hook, object_pairs_hook, list_hook, ext_hook
|
||||||
cdef object encoding, unicode_errors
|
cdef object encoding, unicode_errors
|
||||||
cdef Py_ssize_t max_buffer_size
|
cdef Py_ssize_t max_buffer_size
|
||||||
|
cdef uint64_t stream_offset
|
||||||
|
|
||||||
def __cinit__(self):
|
def __cinit__(self):
|
||||||
self.buf = NULL
|
self.buf = NULL
|
||||||
|
|
@ -358,6 +360,7 @@ cdef class Unpacker(object):
|
||||||
self.buf_size = read_size
|
self.buf_size = read_size
|
||||||
self.buf_head = 0
|
self.buf_head = 0
|
||||||
self.buf_tail = 0
|
self.buf_tail = 0
|
||||||
|
self.stream_offset = 0
|
||||||
|
|
||||||
if encoding is not None:
|
if encoding is not None:
|
||||||
if isinstance(encoding, unicode):
|
if isinstance(encoding, unicode):
|
||||||
|
|
@ -468,6 +471,7 @@ cdef class Unpacker(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ret = execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head)
|
ret = execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head)
|
||||||
|
self.stream_offset += self.buf_head - prev_head
|
||||||
if write_bytes is not None:
|
if write_bytes is not None:
|
||||||
write_bytes(PyBytes_FromStringAndSize(self.buf + prev_head, self.buf_head - prev_head))
|
write_bytes(PyBytes_FromStringAndSize(self.buf + prev_head, self.buf_head - prev_head))
|
||||||
|
|
||||||
|
|
@ -534,6 +538,9 @@ cdef class Unpacker(object):
|
||||||
"""
|
"""
|
||||||
return self._unpack(read_map_header, write_bytes)
|
return self._unpack(read_map_header, write_bytes)
|
||||||
|
|
||||||
|
def tell(self):
|
||||||
|
return self.stream_offset
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ class Unpacker(object):
|
||||||
self._max_array_len = max_array_len
|
self._max_array_len = max_array_len
|
||||||
self._max_map_len = max_map_len
|
self._max_map_len = max_map_len
|
||||||
self._max_ext_len = max_ext_len
|
self._max_ext_len = max_ext_len
|
||||||
|
self._stream_offset = 0
|
||||||
|
|
||||||
if list_hook is not None and not callable(list_hook):
|
if list_hook is not None and not callable(list_hook):
|
||||||
raise TypeError('`list_hook` is not callable')
|
raise TypeError('`list_hook` is not callable')
|
||||||
|
|
@ -266,6 +267,7 @@ class Unpacker(object):
|
||||||
|
|
||||||
def _consume(self):
|
def _consume(self):
|
||||||
""" Gets rid of the used parts of the buffer. """
|
""" Gets rid of the used parts of the buffer. """
|
||||||
|
self._stream_offset += self._buff_i - self._buf_checkpoint
|
||||||
self._buf_checkpoint = self._buff_i
|
self._buf_checkpoint = self._buff_i
|
||||||
|
|
||||||
def _got_extradata(self):
|
def _got_extradata(self):
|
||||||
|
|
@ -629,6 +631,9 @@ class Unpacker(object):
|
||||||
self._consume()
|
self._consume()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def tell(self):
|
||||||
|
return self._stream_offset
|
||||||
|
|
||||||
|
|
||||||
class Packer(object):
|
class Packer(object):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import io
|
import io
|
||||||
from msgpack import Unpacker, BufferFull
|
from msgpack import Unpacker, BufferFull
|
||||||
|
from msgpack import pack
|
||||||
from msgpack.exceptions import OutOfData
|
from msgpack.exceptions import OutOfData
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
|
|
@ -96,3 +97,22 @@ def test_issue124():
|
||||||
unpacker.feed(b"!")
|
unpacker.feed(b"!")
|
||||||
assert tuple(unpacker) == (b'!',)
|
assert tuple(unpacker) == (b'!',)
|
||||||
assert tuple(unpacker) == ()
|
assert tuple(unpacker) == ()
|
||||||
|
|
||||||
|
|
||||||
|
def test_unpack_tell():
|
||||||
|
stream = io.BytesIO()
|
||||||
|
messages = [2**i-1 for i in range(65)]
|
||||||
|
messages += [-(2**i) for i in range(1, 64)]
|
||||||
|
messages += [b'hello', b'hello'*1000, list(range(20)),
|
||||||
|
{i: bytes(i)*i for i in range(10)},
|
||||||
|
{i: bytes(i)*i for i in range(32)}]
|
||||||
|
offsets = []
|
||||||
|
for m in messages:
|
||||||
|
pack(m, stream)
|
||||||
|
offsets.append(stream.tell())
|
||||||
|
stream.seek(0)
|
||||||
|
unpacker = Unpacker(stream)
|
||||||
|
for m, o in zip(messages, offsets):
|
||||||
|
m2 = next(unpacker)
|
||||||
|
assert m == m2
|
||||||
|
assert o == unpacker.tell()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue