mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
77 lines
2.7 KiB
Python
77 lines
2.7 KiB
Python
# Copyright 2015 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import itertools
|
|
import sys
|
|
|
|
import mojo_system
|
|
from mojo_bindings import promise
|
|
|
|
class DataPipeCopyException(Exception):
|
|
def __init__(self, *args, **kwargs):
|
|
Exception.__init__(self, *args, **kwargs)
|
|
self.__traceback__ = sys.exc_info()[2]
|
|
|
|
|
|
def CopyFromDataPipe(data_pipe, deadline):
|
|
"""
|
|
Returns a Promise that operates as follows:
|
|
- If |data_pipe| is successfully read from, the promise resolves with the
|
|
bytes that were read.
|
|
- Otherwise, the promise rejects with an exception whose message contains the
|
|
status from the attempted read.
|
|
"""
|
|
class DataPipeCopyHelper():
|
|
def __init__(self, data_pipe, deadline, resolve, reject):
|
|
self.data_pipe = data_pipe
|
|
self.original_deadline = deadline
|
|
self.start_time = mojo_system.GetTimeTicksNow()
|
|
self.resolve = resolve
|
|
self.reject = reject
|
|
self.buffer_size = 1024
|
|
self.data = bytearray(self.buffer_size)
|
|
self.index = 0
|
|
|
|
def _ComputeCurrentDeadline(self):
|
|
if self.original_deadline == mojo_system.DEADLINE_INDEFINITE:
|
|
return self.original_deadline
|
|
elapsed_time = mojo_system.GetTimeTicksNow() - self.start_time
|
|
return max(0, self.original_deadline - elapsed_time)
|
|
|
|
def CopyFromDataPipeAsync(self, result):
|
|
while result == mojo_system.RESULT_OK:
|
|
assert self.index <= len(self.data)
|
|
if self.index == len(self.data):
|
|
self.buffer_size *= 2
|
|
self.data.extend(itertools.repeat(0, self.buffer_size))
|
|
|
|
# Careful! Have to construct a memoryview object here as otherwise the
|
|
# slice operation will create a copy of |data| and hence not write into
|
|
# |data| as desired.
|
|
result, read_bytes = self.data_pipe.ReadData(
|
|
memoryview(self.data)[self.index:])
|
|
if read_bytes:
|
|
self.index += len(read_bytes)
|
|
del read_bytes
|
|
|
|
if result == mojo_system.RESULT_SHOULD_WAIT:
|
|
data_pipe.AsyncWait(mojo_system.HANDLE_SIGNAL_READABLE,
|
|
self._ComputeCurrentDeadline(),
|
|
self.CopyFromDataPipeAsync)
|
|
return
|
|
|
|
# Treat a failed precondition as EOF.
|
|
if result == mojo_system.RESULT_FAILED_PRECONDITION:
|
|
self.resolve(self.data[:self.index])
|
|
return
|
|
|
|
self.reject(DataPipeCopyException("Result: %d" % result))
|
|
|
|
|
|
def GenerationMethod(resolve, reject):
|
|
helper = DataPipeCopyHelper(data_pipe, deadline, resolve, reject)
|
|
helper.CopyFromDataPipeAsync(mojo_system.RESULT_OK)
|
|
|
|
return promise.Promise(GenerationMethod)
|