def _read_generic(self, space, n): """Generic read function: read from the stream until enough bytes are read, or until an EOF occurs or until read() would block.""" # Must run with the lock held! current_size = self._readahead() if n <= current_size: return self._read_fast(n) result_buffer = ByteBuffer(n) remaining = n written = 0 if current_size: self.output_slice(space, result_buffer, written, self.buffer[self.pos:self.pos + current_size]) remaining -= current_size written += current_size self.pos += current_size # Flush the write buffer if necessary if self.writable: self._flush_and_rewind_unlocked(space) self._reader_reset_buf() # Read whole blocks, and don't buffer them while remaining > 0: r = self.buffer_size * (remaining // self.buffer_size) if r == 0: break try: size = self._raw_read(space, result_buffer, written, r) except BlockingIOError: if written == 0: return None size = 0 if size == 0: return result_buffer[0:written] remaining -= size written += size self.pos = 0 self.raw_pos = 0 self.read_end = 0 while remaining > 0 and self.read_end < self.buffer_size: try: size = self._fill_buffer(space) except BlockingIOError: # EOF or read() would block if written == 0: return None size = 0 if size == 0: break if remaining > 0: if size > remaining: size = remaining self.output_slice(space, result_buffer, written, self.buffer[self.pos:self.pos + size]) self.pos += size written += size remaining -= size return result_buffer[0:written]
def f(x): buf = ByteBuffer(8) return direct_read(buf), typed_read(buf)
def EnumValue(space, w_hkey, index): """tuple = EnumValue(key, index) - Enumerates values of an open registry key. key is an already open key, or any one of the predefined HKEY_* constants. index is an integer that identifies the index of the value to retrieve. The function retrieves the name of one subkey each time it is called. It is typically called repeatedly, until an EnvironmentError exception is raised, indicating no more values. The result is a tuple of 3 items: value_name is a string that identifies the value. value_data is an object that holds the value data, and whose type depends on the underlying registry type. data_type is an integer that identifies the type of the value data.""" hkey = hkey_w(w_hkey, space) null_dword = lltype.nullptr(rwin32.LPDWORD.TO) with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as valueSize: with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as dataSize: ret = rwinreg.RegQueryInfoKeyW(hkey, None, null_dword, null_dword, null_dword, null_dword, null_dword, null_dword, valueSize, dataSize, null_dword, lltype.nullptr(rwin32.PFILETIME.TO)) if ret != 0: raiseWindowsError(space, ret, 'RegQueryInfoKey') # include null terminators valueSize[0] += 1 dataSize[0] += 1 bufDataSize = intmask(dataSize[0]) bufValueSize = intmask(valueSize[0] * 2) valueBuf = ByteBuffer(bufValueSize) valueBufP = rffi.cast(rffi.CWCHARP, valueBuf.get_raw_address()) while True: dataBuf = ByteBuffer(bufDataSize) dataBufP = rffi.cast(rffi.CCHARP, dataBuf.get_raw_address()) with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retType: ret = rwinreg.RegEnumValueW(hkey, index, valueBufP, valueSize, null_dword, retType, dataBufP, dataSize) if ret == rwinreg.ERROR_MORE_DATA: # Resize and retry. For dynamic keys, the value of # dataSize[0] is useless (always 1) so do what CPython # does, except they use 2 instead of 4 bufDataSize *= 4 dataSize[0] = rffi.cast(rwin32.DWORD, bufDataSize) valueSize[0] = rffi.cast(rwin32.DWORD, bufValueSize) continue if ret != 0: raiseWindowsError(space, ret, 'RegEnumValue') length = intmask(dataSize[0]) vlen = (intmask(valueSize[0]) + 1) * 2 utf8v, lenv = wbuf_to_utf8(space, valueBuf[0:vlen]) return space.newtuple([ space.newtext(utf8v, lenv), convert_from_regdata(space, dataBuf, length, retType[0]), space.newint(intmask(retType[0])), ])