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

Side by Side Diff: services/flog/flog_reader_impl.cc

Issue 2046703002: Add 'flog' service implementation. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Fixes per feedback. Created 4 years, 6 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 | « services/flog/flog_reader_impl.h ('k') | services/flog/flog_service_impl.h » ('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 2016 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 #include <iostream>
6
7 #include "base/logging.h"
8 #include "mojo/public/cpp/bindings/lib/array_serialization.h"
9 #include "mojo/public/cpp/bindings/lib/string_serialization.h"
10 #include "services/flog/flog_reader_impl.h"
11
12 namespace mojo {
13 namespace flog {
14
15 // static
16 std::shared_ptr<FlogReaderImpl> FlogReaderImpl::Create(
17 InterfaceRequest<FlogReader> request,
18 uint32_t log_id,
19 const std::string& label,
20 std::shared_ptr<FlogDirectory> directory,
21 FlogServiceImpl* owner) {
22 return std::shared_ptr<FlogReaderImpl>(
23 new FlogReaderImpl(request.Pass(), log_id, label, directory, owner));
24 }
25
26 FlogReaderImpl::FlogReaderImpl(InterfaceRequest<FlogReader> request,
27 uint32_t log_id,
28 const std::string& label,
29 std::shared_ptr<FlogDirectory> directory,
30 FlogServiceImpl* owner)
31 : FlogServiceImpl::Product<FlogReader>(this, request.Pass(), owner),
32 log_id_(log_id),
33 file_(directory->GetFile(log_id, label, false)) {
34 FillReadBuffer(true);
35 stub_.set_sink(this);
36 }
37
38 FlogReaderImpl::~FlogReaderImpl() {}
39
40 void FlogReaderImpl::GetEntries(uint32_t start_index,
41 uint32_t max_count,
42 const GetEntriesCallback& callback) {
43 if (fault_) {
44 std::cerr << "FlogReaderImpl::GetEntries: fault_" << std::endl;
45 callback.Run(Array<FlogEntryPtr>::New(0));
46 return;
47 }
48
49 if (current_entry_index_ > start_index) {
50 std::cerr << "FlogReaderImpl::GetEntries: resetting" << std::endl;
51 current_entry_index_ = 0;
52 FillReadBuffer(true);
53 }
54
55 while (current_entry_index_ < start_index) {
56 std::cerr << "FlogReaderImpl::GetEntries: discard" << std::endl;
57 if (!DiscardEntry()) {
58 callback.Run(Array<FlogEntryPtr>::New(0));
59 return;
60 }
61 }
62
63 DCHECK(current_entry_index_ == start_index);
64
65 Array<FlogEntryPtr> entries = Array<FlogEntryPtr>::New(max_count);
66
67 for (uint32_t i = 0; i < max_count; i++) {
68 FlogEntryPtr entry = GetEntry();
69 if (!entry) {
70 if (fault_) {
71 callback.Run(Array<FlogEntryPtr>::New(0));
72 return;
73 }
74
75 // Reached end-of-file.
76 entries.resize(i);
77 callback.Run(entries.Pass());
78 return;
79 }
80
81 entries[i] = entry.Pass();
82 }
83
84 callback.Run(entries.Pass());
85 }
86
87 bool FlogReaderImpl::DiscardEntry() {
88 uint32_t message_size;
89 size_t bytes_read = ReadData(sizeof(message_size), &message_size);
90 if (bytes_read < sizeof(message_size)) {
91 if (bytes_read != 0) {
92 std::cerr << "FlogReaderImpl::DiscardEntry: FAULT: bytes_read < "
93 "sizeof(message_size)"
94 << std::endl;
95 }
96 fault_ = bytes_read != 0;
97 return false;
98 }
99
100 if (message_size == 0) {
101 std::cerr << "FlogReaderImpl::DiscardEntry: FAULT: message_size == 0"
102 << std::endl;
103 fault_ = true;
104 return false;
105 }
106
107 bytes_read = ReadData(message_size, nullptr);
108 if (bytes_read < message_size) {
109 std::cerr
110 << "FlogReaderImpl::DiscardEntry: FAULT: bytes_read < message_size"
111 << std::endl;
112 fault_ = true;
113 return false;
114 }
115
116 ++current_entry_index_;
117
118 return true;
119 }
120
121 FlogEntryPtr FlogReaderImpl::GetEntry() {
122 uint32_t message_size;
123 size_t bytes_read = ReadData(sizeof(message_size), &message_size);
124 if (bytes_read < sizeof(message_size)) {
125 if (bytes_read != 0) {
126 std::cerr << "FlogReaderImpl::GetEntry: FAULT: bytes_read < "
127 "sizeof(message_size)"
128 << std::endl;
129 }
130 fault_ = bytes_read != 0;
131 return nullptr;
132 }
133
134 if (message_size == 0) {
135 std::cerr << "FlogReaderImpl::GetEntry: FAULT: message_size == 0"
136 << std::endl;
137 fault_ = true;
138 return nullptr;
139 }
140
141 std::unique_ptr<Message> message = std::unique_ptr<Message>(new Message());
142 message->AllocUninitializedData(message_size);
143
144 bytes_read = ReadData(message_size, message->mutable_data());
145 if (bytes_read < message_size) {
146 std::cerr << "FlogReaderImpl::GetEntry: FAULT: bytes_read < message_size"
147 << std::endl;
148 fault_ = true;
149 return nullptr;
150 }
151
152 ++current_entry_index_;
153
154 // Use the stub to deserialize into entry_.
155 stub_.Accept(message.get());
156 DCHECK(entry_);
157 return entry_.Pass();
158 }
159
160 size_t FlogReaderImpl::ReadData(size_t data_size, void* data) {
161 DCHECK(data_size != 0);
162
163 while (read_buffer_bytes_remaining() == 0) {
164 if (read_buffer_.size() < kReadBufferSize) {
165 // read_buffer_ is exhausted and short (because we reached end of file).
166 return 0;
167 }
168
169 FillReadBuffer(false);
170 }
171
172 // Copy up to data_size bytes from the buffer.
173 uint32_t initial_data_size = read_buffer_bytes_remaining();
174 if (initial_data_size > data_size) {
175 initial_data_size = data_size;
176 }
177
178 if (data != nullptr) {
179 memcpy(data, read_buffer_.data() + read_buffer_bytes_used_,
180 initial_data_size);
181 }
182
183 read_buffer_bytes_used_ += initial_data_size;
184
185 if (initial_data_size == data_size || read_buffer_.size() < kReadBufferSize) {
186 // Either read_buffer_ contained all the required data, or read_buffer_ is
187 // short, indicating we've hit end-of-file.
188 return initial_data_size;
189 }
190
191 DCHECK(read_buffer_bytes_remaining() == 0);
192
193 // Read the remainder.
194 return ReadData(data_size - initial_data_size,
195 reinterpret_cast<uint8_t*>(data) + initial_data_size) +
196 initial_data_size;
197 }
198
199 void FlogReaderImpl::FillReadBuffer(bool restart) {
200 file_->Read(kReadBufferSize, 0,
201 restart ? files::Whence::FROM_START : files::Whence::FROM_CURRENT,
202 [this](files::Error error, Array<uint8_t> bytes_read) {
203 if (error != files::Error::OK) {
204 std::cerr << "FlogReaderImpl::FillReadBuffer: FAULT: error "
205 << error << std::endl;
206 fault_ = true;
207 read_buffer_.clear();
208 return;
209 }
210
211 bytes_read.Swap(&read_buffer_);
212 });
213 file_.WaitForIncomingResponse();
214 read_buffer_bytes_used_ = 0;
215 }
216
217 FlogEntryPtr FlogReaderImpl::CreateEntry(int64_t time_us, uint32_t channel_id) {
218 FlogEntryPtr entry = FlogEntry::New();
219 entry->time_us = time_us;
220 entry->log_id = log_id_;
221 entry->channel_id = channel_id;
222 entry->details = FlogEntryDetails::New();
223 return entry;
224 }
225
226 void FlogReaderImpl::LogChannelCreation(int64_t time_us,
227 uint32_t channel_id,
228 const mojo::String& type_name) {
229 entry_ = CreateEntry(time_us, channel_id);
230 FlogChannelCreationEntryDetailsPtr details =
231 FlogChannelCreationEntryDetails::New();
232 details->type_name = type_name;
233 entry_->details->set_channel_creation(details.Pass());
234 }
235
236 void FlogReaderImpl::LogChannelMessage(int64_t time_us,
237 uint32_t channel_id,
238 mojo::Array<uint8_t> data) {
239 entry_ = CreateEntry(time_us, channel_id);
240 FlogChannelMessageEntryDetailsPtr details =
241 FlogChannelMessageEntryDetails::New();
242 details->data = data.Pass();
243 entry_->details->set_channel_message(details.Pass());
244 }
245
246 void FlogReaderImpl::LogChannelDeletion(int64_t time_us, uint32_t channel_id) {
247 entry_ = CreateEntry(time_us, channel_id);
248 FlogChannelDeletionEntryDetailsPtr details =
249 FlogChannelDeletionEntryDetails::New();
250 entry_->details->set_channel_deletion(details.Pass());
251 }
252
253 } // namespace flog
254 } // namespace mojo
OLDNEW
« no previous file with comments | « services/flog/flog_reader_impl.h ('k') | services/flog/flog_service_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698