我试图了解如何使用缓冲协议,这里有一些代码可以将一大块Base64编码文本写入缓冲区:
cpdef object encode_base64(object fin, object fout):
if not PyObject_CheckBuffer(fin):
raise TypeError("fin must follow the buffer protocol")
if not PyObject_CheckBuffer(fout):
raise TypeError("fout must follow the buffer protocol")
cdef Py_buffer in_view
cdef int ret_code = PyObject_GetBuffer(fin, &in_view, PyBUF_SIMPLE)
if ret_code < 0:
return
cdef Py_buffer out_view
out_view.len = in_view.len;
ret_code = PyObject_GetBuffer(fout, &out_view, PyBUF_SIMPLE)
if ret_code < 0:
return
cdef size_t written;
cdef bytes py_bytes = "1. out.buf: %s, out.len: %d\n".encode()
cdef char* c_string = py_bytes
printf(c_string, out_view.buf, out_view.len)
cdef size_t used = encode_buffer(
<unsigned char *>in_view.buf,
in_view.len,
<unsigned char *>out_view.buf,
out_view.len,
80,
80,
&written,
)
out_view.len = written;
printf(c_string, out_view.buf, out_view.len)
print "used: {}, written: {}, out: {}".format(used, written, printbuf(fout))
encode_buffer()
在C代码中的其他地方定义如下:
size_t encode_buffer(
const unsigned char* buf_in, const size_t buf_in_size,
const unsigned char* buf_out, const size_t buf_out_size,
const size_t pre_pad, const size_t padding, size_t* written);
它运作正常(至少在我的理解中)。
问题在于,如果我以这种方式在Python中使用此代码:
def test_printbuf():
buf_in = BytesIO(b'1234567890')
buf_in.seek(0)
buf_out = BytesIO()
buf_out.seek(0)
encode_base64(buf_in.getbuffer(), buf_out.getbuffer())
buf_out.seek(0)
print('Encoded: {} -> {}'.format(buf_out.getbuffer(), buf_out.getvalue()))
buf_out
似乎是空的。 (我可能会将编码后的文本写入一些我不应该触摸的记忆中,但这不是现在的主要问题。)
我的问题是:如何从BytesIO
获取我想要的大小的缓冲区?由于它是使用空字符串初始化的,因此它具有零长度缓冲区,并且它忽略len
结构的Py_buffer
字段。
我查看了BytesIO
的实现,它具有调整缓冲区大小的特殊功能,但它们特定于此对象,我希望我的代码是通用的。