Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: mojo/python/mojo_utils/data_pipe_utils.py

Issue 952223002: Add Python util to read from a data pipe into a bytearray (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Response to review Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/python/mojo_utils/__init__.py ('k') | mojo/python/tests/data_pipe_utils_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import itertools
6 import sys
7
8 import mojo_system
9 from mojo_bindings import promise
10
11 class DataPipeCopyException(Exception):
12 def __init__(self, *args, **kwargs):
13 Exception.__init__(self, *args, **kwargs)
14 self.__traceback__ = sys.exc_info()[2]
15
16
17 def CopyFromDataPipe(data_pipe, deadline):
18 """
19 Returns a Promise that operates as follows:
20 - If |data_pipe| is successfully read from, the promise resolves with the
21 bytes that were read.
22 - Otherwise, the promise rejects with an exception whose message contains the
23 status from the attempted read.
24 """
25 class DataPipeCopyHelper():
26 def __init__(self, data_pipe, deadline, resolve, reject):
27 self.data_pipe = data_pipe
28 self.original_deadline = deadline
29 self.start_time = mojo_system.GetTimeTicksNow()
30 self.resolve = resolve
31 self.reject = reject
32 self.buffer_size = 1024
33 self.data = bytearray(self.buffer_size)
34 self.index = 0
35
36 def _ComputeCurrentDeadline(self):
37 if self.original_deadline == mojo_system.DEADLINE_INDEFINITE:
38 return self.original_deadline
39 elapsed_time = mojo_system.GetTimeTicksNow() - self.start_time
40 return max(0, self.original_deadline - elapsed_time)
41
42 def CopyFromDataPipeAsync(self, result):
43 while result == mojo_system.RESULT_OK:
44 assert self.index <= len(self.data)
45 if self.index == len(self.data):
46 self.buffer_size *= 2
47 self.data.extend(itertools.repeat(0, self.buffer_size))
48
49 # Careful! Have to construct a memoryview object here as otherwise the
50 # slice operation will create a copy of |data| and hence not write into
51 # |data| as desired.
52 result, read_bytes = self.data_pipe.ReadData(
53 memoryview(self.data)[self.index:])
54 if read_bytes:
55 self.index += len(read_bytes)
56 del read_bytes
57
58 if result == mojo_system.RESULT_SHOULD_WAIT:
59 data_pipe.AsyncWait(mojo_system.HANDLE_SIGNAL_READABLE,
60 self._ComputeCurrentDeadline(),
61 self.CopyFromDataPipeAsync)
62 return
63
64 # Treat a failed precondition as EOF.
65 if result == mojo_system.RESULT_FAILED_PRECONDITION:
66 self.resolve(self.data[:self.index])
67 return
68
69 self.reject(DataPipeCopyException("Result: %d" % result))
70
71
72 def GenerationMethod(resolve, reject):
73 helper = DataPipeCopyHelper(data_pipe, deadline, resolve, reject)
74 helper.CopyFromDataPipeAsync(mojo_system.RESULT_OK)
75
76 return promise.Promise(GenerationMethod)
OLDNEW
« no previous file with comments | « mojo/python/mojo_utils/__init__.py ('k') | mojo/python/tests/data_pipe_utils_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698