Пример #1
0
    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]
Пример #2
0
 def f(x):
     buf = ByteBuffer(8)
     return direct_read(buf), typed_read(buf)
Пример #3
0
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])),
                    ])