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

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: Move to AsyncWait, add tests 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
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 == 0 or
38 self.original_deadline == mojo_system.DEADLINE_INDEFINITE):
39 return self.original_deadline
40 elapsed_time = mojo_system.GetTimeTicksNow() - self.start_time
41 return self.original_deadline - elapsed_time
qsr 2015/03/03 17:10:36 You probably want a max(0, self.original_deadline
blundell 2015/03/04 10:28:52 Done.
42
43 def CopyFromDataPipeAsync(self, result):
44 while result == mojo_system.RESULT_OK:
45 assert self.index <= len(self.data)
46 if self.index == len(self.data):
47 self.buffer_size *= 2
48 self.data.extend(itertools.repeat(0, self.buffer_size))
49
50 # Careful! Have to construct a memoryview object here as otherwise the
51 # slice operation will create a copy of |data| and hence not write into
52 # |data| as desired.
53 result, read_bytes = self.data_pipe.ReadData(
54 memoryview(self.data)[self.index:])
55 if read_bytes:
56 self.index += len(read_bytes)
57 del read_bytes
58
59 if result == mojo_system.RESULT_SHOULD_WAIT:
60 data_pipe.AsyncWait(mojo_system.HANDLE_SIGNAL_READABLE,
61 self._ComputeCurrentDeadline(),
62 self.CopyFromDataPipeAsync)
63 return
64
65 # Treat a failed precondition as EOF.
66 if result == mojo_system.RESULT_FAILED_PRECONDITION:
67 self.resolve(self.data[:self.index])
68 return
69
70 self.reject(DataPipeCopyException("Result: %d" % result))
71
72
73 def GenerationMethod(resolve, reject):
74 helper = DataPipeCopyHelper(data_pipe, deadline, resolve, reject)
75 helper.CopyFromDataPipeAsync(mojo_system.RESULT_OK)
76
77 return promise.Promise(GenerationMethod)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698