def frombuffer(space, w_buffer, w_dtype=None, count=-1, offset=0): dtype = space.interp_w( descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.elsize == 0: raise oefmt(space.w_ValueError, "itemsize cannot be zero in type") try: buf = _getbuffer(space, w_buffer) except OperationError as e: if not e.match(space, space.w_TypeError): raise w_buffer = space.call_method(w_buffer, '__buffer__', space.newint(space.BUF_FULL_RO)) buf = _getbuffer(space, w_buffer) ts = buf.getlength() if offset < 0 or offset > ts: raise oefmt( space.w_ValueError, "offset must be non-negative and no greater than " "buffer length (%d)", ts) s = ts - offset if offset: buf = SubBuffer(buf, offset, s) n = count itemsize = dtype.elsize assert itemsize > 0 if n < 0: if s % itemsize != 0: raise oefmt(space.w_ValueError, "buffer size must be a multiple of element size") n = s / itemsize else: if s < n * itemsize: raise oefmt(space.w_ValueError, "buffer is smaller than requested size") try: storage = buf.get_raw_address() except ValueError: a = W_NDimArray.from_shape(space, [n], dtype=dtype) loop.fromstring_loop(space, a, dtype, itemsize, buf.as_str()) return a else: writable = not buf.readonly return W_NDimArray.from_shape_and_storage(space, [n], storage, storage_bytes=s, dtype=dtype, w_base=w_buffer, writable=writable)
def frombuffer(space, w_buffer, w_dtype=None, count=-1, offset=0): dtype = space.interp_w(descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.elsize == 0: raise oefmt(space.w_ValueError, "itemsize cannot be zero in type") try: buf = _getbuffer(space, w_buffer) except OperationError as e: if not e.match(space, space.w_TypeError): raise w_buffer = space.call_method(w_buffer, '__buffer__', space.newint(space.BUF_FULL_RO)) buf = _getbuffer(space, w_buffer) ts = buf.getlength() if offset < 0 or offset > ts: raise oefmt(space.w_ValueError, "offset must be non-negative and no greater than " "buffer length (%d)", ts) s = ts - offset if offset: buf = SubBuffer(buf, offset, s) n = count itemsize = dtype.elsize assert itemsize > 0 if n < 0: if s % itemsize != 0: raise oefmt(space.w_ValueError, "buffer size must be a multiple of element size") n = s / itemsize else: if s < n * itemsize: raise oefmt(space.w_ValueError, "buffer is smaller than requested size") try: storage = buf.get_raw_address() except ValueError: a = W_NDimArray.from_shape(space, [n], dtype=dtype) loop.fromstring_loop(space, a, dtype, itemsize, buf.as_str()) return a else: writable = not buf.readonly return W_NDimArray.from_shape_and_storage(space, [n], storage, storage_bytes=s, dtype=dtype, w_base=w_buffer, writable=writable)
def new_slice(self, start, step, slicelength): if step == 1: n = self.itemsize newbuf = SubBuffer(self.data, start * n, slicelength * n) return ArrayView(newbuf, self.fmt, self.itemsize, self.readonly) else: return BufferView.new_slice(self, start, step, slicelength)
def _raw_read(self, space, buffer, start, length): assert buffer is not None length = intmask(length) start = intmask(start) w_view = SimpleView(SubBuffer(buffer, start, length)).wrap(space) while True: try: w_size = space.call_method(self.w_raw, "readinto", w_view) except OperationError as e: if trap_eintr(space, e): continue # try again raise else: break if space.is_w(w_size, space.w_None): raise BlockingIOError() size = space.int_w(w_size) if size < 0 or size > length: raise oefmt( space.w_IOError, "raw readinto() returned invalid length %d (should " "have been between 0 and %d)", size, length) if self.abs_pos != -1: self.abs_pos += size return size
def do_pack_into(space, format, w_buffer, offset, args_w): """ Pack the values v1, v2, ... according to fmt. Write the packed bytes into the writable buffer buf starting at offset """ size = _calcsize(space, format) buf = space.writebuf_w(w_buffer) buflen = buf.getlength() if offset < 0: # Check that negative offset is low enough to fit data if offset + size > 0: raise oefmt(get_error(space), "no space to pack %d bytes at offset %d", size, offset) # Check that negative offset is not crossing buffer boundary if offset + buflen < 0: raise oefmt(get_error(space), "offset %d out of range for %d-byte buffer", offset, buflen) offset += buflen if (buflen - offset) < size: raise oefmt( get_error(space), "pack_into requires a buffer of at least %d bytes for " "packing %d bytes at offset %d " "(actual buffer size is %d)", size + offset, size, offset, buflen) # wbuf = SubBuffer(buf, offset, size) fmtiter = PackFormatIterator(space, wbuf, args_w) try: fmtiter.interpret(format) except StructOverflowError as e: raise OperationError(space.w_OverflowError, space.newtext(e.msg)) except StructError as e: raise OperationError(get_error(space), space.newtext(e.msg))
def descr_getitem(self, space, w_index): start, stop, step, size = space.decode_index4(w_index, self.getlength()) if step not in (0, 1): raise oefmt(space.w_NotImplementedError, "") if step == 0: # index only return space.wrap(self.buf.getitem(start)) else: buf = SubBuffer(self.buf, start, size) return W_MemoryView(buf)
def descr_next(self, space): if self.w_struct is None: raise OperationError(space.w_StopIteration, space.w_None) if self.index >= self.buf.getlength(): raise OperationError(space.w_StopIteration, space.w_None) size = self.w_struct.size buf = SubBuffer(self.buf, self.index, size) w_res = _unpack(space, self.w_struct.format, buf) self.index += size return w_res
def unpack_from(space, format, w_buffer, offset=0): size = _calcsize(space, format) buf = space.buffer_w(w_buffer, space.BUF_SIMPLE) if offset < 0: offset += buf.getlength() if offset < 0 or (buf.getlength() - offset) < size: raise oefmt(get_error(space), "unpack_from requires a buffer of at least %d bytes", size) buf = SubBuffer(buf, offset, size) return _unpack(space, format, buf)
def descr_new_buffer(space, w_subtype, w_object, offset=0, size=-1): buf = space.readbuf_w(w_object) if offset == 0 and size == -1: return W_Buffer(buf) # handle buffer slices if offset < 0: raise oefmt(space.w_ValueError, "offset must be zero or positive") if size < -1: raise oefmt(space.w_ValueError, "size must be zero or positive") buf = SubBuffer(buf, offset, size) return W_Buffer(buf)
def do_unpack_from(space, format, w_buffer, offset=0): """Unpack the buffer, containing packed C structure data, according to fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).""" size = _calcsize(space, format) buf = space.readbuf_w(w_buffer) if offset < 0: offset += buf.getlength() if offset < 0 or (buf.getlength() - offset) < size: raise oefmt(get_error(space), "unpack_from requires a buffer of at least %d bytes", size) buf = SubBuffer(buf, offset, size) return _unpack(space, format, buf)
def unpack_from(space, format, w_buffer, offset=0): size = _calcsize(space, format) buf = space.getarg_w('z*', w_buffer) if buf is None: raise oefmt(get_error(space), "unpack_from requires a buffer argument") if offset < 0: offset += buf.getlength() if offset < 0 or (buf.getlength() - offset) < size: raise oefmt(get_error(space), "unpack_from requires a buffer of at least %d bytes", size) buf = SubBuffer(buf, offset, size) return _unpack(space, format, buf)
def test_subbuffer(self): # to force a non-aligned 'i' expected = struct.pack('=BBi', 0xAB, 0xCD, 0x1234) size = len(expected) # wbuf = MutableStringBuffer(size) wsubbuf = SubBuffer(wbuf, 2, size - 4) wbuf.setitem(0, chr(0xAB)) wbuf.setitem(1, chr(0xCD)) fake_fmtiter = self.mypack_into('i', wsubbuf, 0x1234) assert fake_fmtiter.pos == wbuf.getlength( ) - 2 # -2 since it's a SubBuffer got = wbuf.finish() assert got == expected
def descr_new_buffer(space, w_subtype, w_object, offset=0, size=-1): try: buf = w_object.readbuf_w(space) except BufferInterfaceNotFound: raise oefmt(space.w_TypeError, "expected a readable buffer object") if offset == 0 and size == -1: return W_Buffer(buf) # handle buffer slices if offset < 0: raise oefmt(space.w_ValueError, "offset must be zero or positive") if size < -1: raise oefmt(space.w_ValueError, "size must be zero or positive") buf = SubBuffer(buf, offset, size) return W_Buffer(buf)
def descr_getitem(self, space, w_index): self._check_released(space) start, stop, step, size = space.decode_index4(w_index, self.getlength()) if step not in (0, 1): raise oefmt(space.w_NotImplementedError, "") if step == 0: # index only a = start * self.itemsize b = a + self.itemsize return space.wrapbytes( ''.join([self.buf.getitem(i) for i in range(a, b)])) else: buf = SubBuffer(self.buf, start * self.itemsize, size * self.itemsize) return W_MemoryView(buf, self.format, self.itemsize)
def descr_new_buffer(space, w_subtype, w_object, offset=0, size=-1): try: buf = w_object.readbuf_w(space) except BufferInterfaceNotFound: raise oefmt(space.w_TypeError, "anticipó un objecto búfer leíble") if offset == 0 and size == -1: return W_Buffer(buf) # handle buffer slices if offset < 0: raise oefmt(space.w_ValueError, "offset tiene que ser cero o positivo") if size < -1: raise oefmt(space.w_ValueError, "tamaño tiene que ser cero o positivo") buf = SubBuffer(buf, offset, size) return W_Buffer(buf)
def descr_getitem(self, space, w_index): start, stop, step, size = space.decode_index4(w_index, self.getlength()) itemsize = self.buf.getitemsize() if itemsize > 1: start *= itemsize size *= itemsize stop = start + size if step == 0: step = 1 if stop > self.getlength(): raise oefmt(space.w_IndexError, 'index out of range') if step not in (0, 1): raise oefmt(space.w_NotImplementedError, "") if step == 0: # index only return space.newbytes(self.buf.getitem(start)) else: buf = SubBuffer(self.buf, start, size) return W_MemoryView(buf)
def pack_into(space, format, w_buffer, offset, args_w): """ Pack the values v1, v2, ... according to fmt. Write the packed bytes into the writable buffer buf starting at offset """ size = _calcsize(space, format) buf = space.getarg_w('w*', w_buffer) if offset < 0: offset += buf.getlength() if offset < 0 or (buf.getlength() - offset) < size: raise oefmt(get_error(space), "pack_into requires a buffer of at least %d bytes", size) # wbuf = SubBuffer(buf, offset, size) fmtiter = PackFormatIterator(space, wbuf, args_w) try: fmtiter.interpret(format) except StructOverflowError as e: raise OperationError(space.w_OverflowError, space.newtext(e.msg)) except StructError as e: raise OperationError(get_error(space), space.newtext(e.msg))
def test_as_str_and_offset_maybe(): buf = StringBuffer('hello world') assert buf.as_str_and_offset_maybe() == ('hello world', 0) # sbuf = SubBuffer(buf, 6, 5) assert sbuf.getslice(0, 5, 1, 5) == 'world' assert sbuf.as_str_and_offset_maybe() == ('hello world', 6) # ssbuf = SubBuffer(sbuf, 3, 2) assert ssbuf.getslice(0, 2, 1, 2) == 'ld' assert ssbuf.as_str_and_offset_maybe() == ('hello world', 9) # ss2buf = SubBuffer(sbuf, 1, -1) assert ss2buf.as_str() == 'orld' assert ss2buf.getlength() == 4 ss3buf = SubBuffer(ss2buf, 1, -1) assert ss3buf.as_str() == 'rld' assert ss3buf.getlength() == 3 # ss4buf = SubBuffer(buf, 3, 4) assert ss4buf.as_str() == 'lo w' ss5buf = SubBuffer(ss4buf, 1, -1) assert ss5buf.as_str() == 'o w' assert ss5buf.getlength() == 3
def new_slice(self, start, step, slicelength): if step == 1: return SimpleView(SubBuffer(self.data, start, slicelength)) else: return BufferSlice(self, start, step, slicelength)
def test_repeated_subbuffer(): buf = StringBuffer('x' * 10000) for i in range(9999, 9, -1): buf = SubBuffer(buf, 1, i) assert buf.getlength() == 10
def read(self, TYPE, data, offset): buf = StringBuffer('x' * 16 + data) subbuf = SubBuffer(buf, 16, len(data)) return subbuf.typed_read(TYPE, offset)