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

Unified Diff: content/browser/devtools/devtools_io_context.cc

Issue 1307073002: DevTools: provide an option to return traces as streams (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: work around MSVC compiler error due to missing Client definition Created 5 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/devtools/devtools_io_context.h ('k') | content/browser/devtools/protocol/io_handler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/devtools/devtools_io_context.cc
diff --git a/content/browser/devtools/devtools_io_context.cc b/content/browser/devtools/devtools_io_context.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e3082ddb3cd7d5e2a95f6b2527e36bfa10a31ae7
--- /dev/null
+++ b/content/browser/devtools/devtools_io_context.cc
@@ -0,0 +1,145 @@
+// 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.
+
+#include "content/browser/devtools/devtools_io_context.h"
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/third_party/icu/icu_utf.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+namespace devtools {
+
+namespace {
+unsigned s_last_stream_handle = 0;
+}
+
+using Stream = DevToolsIOContext::Stream;
+
+Stream::Stream()
+ : base::RefCountedDeleteOnMessageLoop<Stream>(
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)),
+ handle_(base::IntToString(++s_last_stream_handle)),
+ had_errors_(false),
+ last_read_pos_(0) {}
+
+Stream::~Stream() {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+}
+
+bool Stream::InitOnFileThreadIfNeeded() {
+ if (had_errors_)
+ return false;
+ if (file_.IsValid())
+ return true;
+ base::FilePath temp_path;
+ if (!base::CreateTemporaryFile(&temp_path)) {
+ LOG(ERROR) << "Failed to create temporary file";
+ had_errors_ = true;
+ return false;
+ }
+ const unsigned flags = base::File::FLAG_OPEN_TRUNCATED |
+ base::File::FLAG_WRITE | base::File::FLAG_READ |
+ base::File::FLAG_DELETE_ON_CLOSE;
+ file_.Initialize(temp_path, flags);
+ if (!file_.IsValid()) {
+ LOG(ERROR) << "Failed to open temporary file: " << temp_path.value()
+ << ", " << base::File::ErrorToString(file_.error_details());
+ had_errors_ = true;
+ DeleteFile(temp_path, false);
+ return false;
+ }
+ return true;
+}
+
+void Stream::Read(off_t position, size_t max_size, ReadCallback callback) {
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&Stream::ReadOnFileThread, this, position, max_size,
+ callback));
+}
+
+void Stream::Append(const scoped_refptr<base::RefCountedString>& data) {
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&Stream::AppendOnFileThread, this, data));
+}
+
+void Stream::ReadOnFileThread(off_t position, size_t max_size,
+ ReadCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+ Status status = StatusFailure;
+ scoped_refptr<base::RefCountedString> data;
+
+ if (file_.IsValid()) {
+ std::string buffer;
+ buffer.resize(max_size);
+ if (position < 0)
+ position = last_read_pos_;
+ int size_got = file_.ReadNoBestEffort(position, &*buffer.begin(), max_size);
+ if (size_got < 0) {
+ LOG(ERROR) << "Failed to read temporary file";
+ had_errors_ = true;
+ file_.Close();
+ } else {
+ // Provided client has requested sufficient large block, make their
+ // life easier by not truncating in the middle of a UTF-8 character.
+ if (size_got > 6 && !CBU8_IS_SINGLE(buffer[size_got - 1])) {
+ base::TruncateUTF8ToByteSize(buffer, size_got, &buffer);
+ size_got = buffer.size();
+ } else {
+ buffer.resize(size_got);
+ }
+ data = base::RefCountedString::TakeString(&buffer);
+ status = size_got ? StatusSuccess : StatusEOF;
+ last_read_pos_ = position + size_got;
+ }
+ }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(callback, data, status));
+}
+
+void Stream::AppendOnFileThread(
+ const scoped_refptr<base::RefCountedString>& data) {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+ if (!InitOnFileThreadIfNeeded())
+ return;
+ const std::string& buffer = data->data();
+ int size_written = file_.WriteAtCurrentPos(&*buffer.begin(), buffer.size());
+ if (size_written != static_cast<int>(buffer.size())) {
+ LOG(ERROR) << "Failed to write temporary file";
+ had_errors_ = true;
+ file_.Close();
+ }
+}
+
+DevToolsIOContext::DevToolsIOContext() {}
+
+DevToolsIOContext::~DevToolsIOContext() {}
+
+scoped_refptr<Stream> DevToolsIOContext::CreateTempFileBackedStream() {
+ scoped_refptr<Stream> result = new Stream();
+ bool inserted =
+ streams_.insert(std::make_pair(result->handle(), result)).second;
+ DCHECK(inserted);
+ return result;
+}
+
+scoped_refptr<Stream>
+ DevToolsIOContext::GetByHandle(const std::string& handle) {
+ StreamsMap::const_iterator it = streams_.find(handle);
+ return it == streams_.end() ? scoped_refptr<Stream>() : it->second;
+}
+
+bool DevToolsIOContext::Close(const std::string& handle) {
+ return streams_.erase(handle) == 1;
+}
+
+void DevToolsIOContext::DiscardAllStreams() {
+ return streams_.clear();
+}
+
+} // namespace devtools
+} // namespace content
« no previous file with comments | « content/browser/devtools/devtools_io_context.h ('k') | content/browser/devtools/protocol/io_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698