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

Side by Side Diff: mojo/common/data_pipe_utils.cc

Issue 696543003: Mojo content handler shebang support (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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
« mojo/common/data_pipe_utils.h ('K') | « mojo/common/data_pipe_utils.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/common/data_pipe_utils.h" 5 #include "mojo/common/data_pipe_utils.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/files/scoped_file.h" 11 #include "base/files/scoped_file.h"
12 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
13 #include "base/task_runner_util.h" 13 #include "base/task_runner_util.h"
14 #include "base/threading/platform_thread.h"
14 15
15 namespace mojo { 16 namespace mojo {
16 namespace common { 17 namespace common {
17 namespace { 18 namespace {
18 19
19 bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source, 20 bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source,
20 const base::Callback<size_t(const void*, uint32_t)>& write_bytes) { 21 const base::Callback<size_t(const void*, uint32_t)>& write_bytes) {
21 for (;;) { 22 for (;;) {
22 const void* buffer; 23 const void* buffer;
23 uint32_t num_bytes; 24 uint32_t num_bytes;
(...skipping 27 matching lines...) Expand all
51 size_t CopyToStringHelper( 52 size_t CopyToStringHelper(
52 std::string* result, const void* buffer, uint32_t num_bytes) { 53 std::string* result, const void* buffer, uint32_t num_bytes) {
53 result->append(static_cast<const char*>(buffer), num_bytes); 54 result->append(static_cast<const char*>(buffer), num_bytes);
54 return num_bytes; 55 return num_bytes;
55 } 56 }
56 57
57 size_t CopyToFileHelper(FILE* fp, const void* buffer, uint32_t num_bytes) { 58 size_t CopyToFileHelper(FILE* fp, const void* buffer, uint32_t num_bytes) {
58 return fwrite(buffer, 1, num_bytes, fp); 59 return fwrite(buffer, 1, num_bytes, fp);
59 } 60 }
60 61
62 // Sleep for as long as max_sleep_micros if the deadline hasn't been reached
63 // and the number of bytes read is still increasing. Returns true if sleep
64 // was actually called.
65 //
66 // This class is a substitute for being able to wait until N bytes are available
67 // from a data pipe. The MaybeSleep method is called when num_bytes_read are
68 // available but more are needed by the Peek operation. If a second
69 // Peek operation finds the same number of bytes after sleeping we assume
70 // that there's no point in trying again.
viettrungluu 2014/10/31 23:30:23 Please add a TODO for yourself, since this is pret
hansmuller 2014/11/01 00:06:04 Done.
71
viettrungluu 2014/10/31 23:30:22 nit: no blank line here
hansmuller 2014/11/01 00:06:05 Done.
72 class PeekSleeper {
viettrungluu 2014/10/31 23:30:22 For some reason, having this helper class seems li
hansmuller 2014/11/01 00:06:05 I initially wrote the code without it. Moving the
73 public:
viettrungluu 2014/10/31 23:30:23 indent one space (consider running clang-format)
hansmuller 2014/11/01 00:06:05 Done.
74 PeekSleeper(MojoTimeTicks deadline)
viettrungluu 2014/10/31 23:30:23 explicit
hansmuller 2014/11/01 00:06:05 Done.
75 : deadline_(deadline),
76 last_number_bytes_read_(0),
77 max_sleep_micros_(1000 * 10) {
viettrungluu 2014/10/31 23:30:22 This is a constant, so it should be declared as su
hansmuller 2014/11/01 00:06:05 Done.
78 }
79
80 bool MaybeSleep(uint32 num_bytes_read) {
81 if (num_bytes_read > 0 && last_number_bytes_read_ >= num_bytes_read)
82 return false;
83 last_number_bytes_read_ = num_bytes_read;
84
85 MojoTimeTicks now(GetTimeTicksNow());
86 if (now > deadline_)
87 return false;
88
89 MojoTimeTicks sleep_time = (deadline_ == 0)
90 ? max_sleep_micros_
91 : std::min<int64>(deadline_ - now, max_sleep_micros_);
92 base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(sleep_time));
93 return true;
94 }
95
96 private:
viettrungluu 2014/10/31 23:30:23 indent one space
hansmuller 2014/11/01 00:06:05 Done.
97 MojoTimeTicks deadline_; // 0 => MOJO_DEADLINE_INDEFINITE
98 uint32 last_number_bytes_read_;
99 MojoTimeTicks max_sleep_micros_; // microseconds
100 };
101
102 enum PeekStatus {kSuccess, kFail, kKeepReading};
viettrungluu 2014/10/31 23:30:23 space after {, before }
hansmuller 2014/11/01 00:06:05 Done.
103 typedef PeekStatus (*PeekFunc)(const void*, uint32_t, size_t, std::string*);
viettrungluu 2014/10/31 23:30:23 I find the fact that the size_t argument has varyi
hansmuller 2014/11/03 23:24:24 Done.
104
105 // When data is available on source, call peek_func and then either return true
106 // and value, continue waiting for enough data to satisfy peek_func, or fail
107 // and return false. Fail if the timeout is exceeded.
108
viettrungluu 2014/10/31 23:30:23 no blank line
hansmuller 2014/11/01 00:06:05 Done.
109 bool BlockingPeekHelper(DataPipeConsumerHandle source,
110 std::string* value,
111 size_t value_length,
112 MojoDeadline timeout,
113 PeekFunc peek_func) {
114 CHECK(value);
viettrungluu 2014/10/31 23:30:23 Probably a DCHECK is sufficient.
hansmuller 2014/11/01 00:06:04 Done.
115 value->clear();
116
117 MojoTimeTicks deadline = (timeout == MOJO_DEADLINE_INDEFINITE) ? 0
118 : 1 + GetTimeTicksNow() + static_cast<MojoTimeTicks>(timeout);
119 PeekSleeper sleeper(deadline);
120 MojoResult result = MOJO_RESULT_OK;
121
122 while(result == MOJO_RESULT_OK) {
viettrungluu 2014/10/31 23:30:23 Maybe write this as a do-while instead?
viettrungluu 2014/11/03 18:36:56 You missed this.
hansmuller 2014/11/03 23:24:24 Done.
123 const void* buffer;
124 uint32_t num_bytes;
125 result =
126 BeginReadDataRaw(source, &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
viettrungluu 2014/10/31 23:30:23 So if this is called not at the beginning of the b
viettrungluu 2014/11/03 18:36:56 And this....
127
128 if (result == MOJO_RESULT_OK) {
129 PeekStatus status = peek_func(buffer, num_bytes, value_length, value);
130 if (EndReadDataRaw(source, 0) != MOJO_RESULT_OK)
viettrungluu 2014/10/31 23:30:23 Probably just do a CHECK_NE.
viettrungluu 2014/11/03 18:36:56 ...
hansmuller 2014/11/03 23:24:24 Done.
131 return false;
132 switch (status) {
133 case PeekStatus::kSuccess: return true;
134 case PeekStatus::kFail: return false;
135 case PeekStatus::kKeepReading: break;
136 }
137 if (!sleeper.MaybeSleep(num_bytes))
138 return false;
139
viettrungluu 2014/10/31 23:30:23 no blank line
hansmuller 2014/11/01 00:06:05 Done.
140 } else if (result == MOJO_RESULT_SHOULD_WAIT) {
141 MojoTimeTicks now(GetTimeTicksNow());
142 if (timeout == MOJO_DEADLINE_INDEFINITE || now < deadline)
143 result = Wait(source, MOJO_HANDLE_SIGNAL_READABLE, deadline - now);
144 }
145 }
146
147 return false;
148 }
149
150 PeekStatus PeekLine(const void* buffer,
151 uint32 buffer_num_bytes,
152 size_t max_line_length,
153 std::string* line) {
154 const char* p = static_cast<const char*>(buffer);
155 std::string s(p, buffer_num_bytes);
viettrungluu 2014/10/31 23:30:23 It seems quite painful to build an entire string j
hansmuller 2014/11/01 00:06:04 Since you went to the trouble of writing a loop, I
156 size_t n = s.find("\n");
157 if (n != std::string::npos && n <= max_line_length) {
158 *line = s.substr(0, n);
viettrungluu 2014/10/31 23:30:23 This won't include the '\n', will it? I find that
hansmuller 2014/11/01 00:06:05 Yes he line return value doesn't include the termi
viettrungluu 2014/11/03 18:36:56 I guess for "peek", it's less odd, but you should
159 return PeekStatus::kSuccess;
160 }
161 if (s.size() > max_line_length)
162 return PeekStatus::kFail;
163 return PeekStatus::kKeepReading;
164 }
165
166 PeekStatus PeekNBytes(const void* buffer,
167 uint32 buffer_num_bytes,
viettrungluu 2014/10/31 23:30:23 fix indentation
hansmuller 2014/11/01 00:06:05 Done.
168 size_t bytes_length,
169 std::string* bytes) {
170 if (buffer_num_bytes >= bytes_length) {
171 const char* p = static_cast<const char*>(buffer);
172 *bytes = std::string(p, bytes_length);
173 return PeekStatus::kSuccess;
174 }
175 return PeekStatus::kKeepReading;
176 }
177
61 } // namespace 178 } // namespace
62 179
63 180
viettrungluu 2014/10/31 23:30:23 nit: one fewer blank line
hansmuller 2014/11/01 00:06:04 Done.
181 bool BlockingPeekNBytes(DataPipeConsumerHandle source,
182 std::string* bytes,
183 size_t bytes_length,
184 MojoDeadline timeout) {
185 return BlockingPeekHelper(source, bytes, bytes_length, timeout, &PeekNBytes);
186 }
187
188 bool BlockingPeekLine(DataPipeConsumerHandle source,
189 std::string* line,
190 size_t max_line_length,
191 MojoDeadline timeout) {
192 return BlockingPeekHelper(source, line, max_line_length, timeout, &PeekLine);
193 }
194
64 // TODO(hansmuller): Add a max_size parameter. 195 // TODO(hansmuller): Add a max_size parameter.
65 bool BlockingCopyToString(ScopedDataPipeConsumerHandle source, 196 bool BlockingCopyToString(ScopedDataPipeConsumerHandle source,
66 std::string* result) { 197 std::string* result) {
67 CHECK(result); 198 CHECK(result);
68 result->clear(); 199 result->clear();
69 return BlockingCopyHelper( 200 return BlockingCopyHelper(
70 source.Pass(), base::Bind(&CopyToStringHelper, result)); 201 source.Pass(), base::Bind(&CopyToStringHelper, result));
71 } 202 }
72 203
73 bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source, 204 bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source,
(...skipping 11 matching lines...) Expand all
85 const base::Callback<void(bool)>& callback) { 216 const base::Callback<void(bool)>& callback) {
86 base::PostTaskAndReplyWithResult( 217 base::PostTaskAndReplyWithResult(
87 task_runner, 218 task_runner,
88 FROM_HERE, 219 FROM_HERE,
89 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), 220 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination),
90 callback); 221 callback);
91 } 222 }
92 223
93 } // namespace common 224 } // namespace common
94 } // namespace mojo 225 } // namespace mojo
OLDNEW
« mojo/common/data_pipe_utils.h ('K') | « mojo/common/data_pipe_utils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698