]> git.sesse.net Git - casparcg/blobdiff - dependencies64/cef/windows/libcef_dll/wrapper/cef_stream_resource_handler.cc
Upgrade CEF to 3.3029.1611.g44e39a8 / Chromium 58.0.3029.81.
[casparcg] / dependencies64 / cef / windows / libcef_dll / wrapper / cef_stream_resource_handler.cc
diff --git a/dependencies64/cef/windows/libcef_dll/wrapper/cef_stream_resource_handler.cc b/dependencies64/cef/windows/libcef_dll/wrapper/cef_stream_resource_handler.cc
new file mode 100644 (file)
index 0000000..ed6a2c4
--- /dev/null
@@ -0,0 +1,207 @@
+// Copyright (c) 2012 The Chromium Embedded Framework 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 "include/wrapper/cef_stream_resource_handler.h"
+
+#include <algorithm>
+
+#include "include/base/cef_bind.h"
+#include "include/base/cef_logging.h"
+#include "include/base/cef_macros.h"
+#include "include/cef_callback.h"
+#include "include/cef_request.h"
+#include "include/cef_stream.h"
+#include "include/wrapper/cef_closure_task.h"
+#include "include/wrapper/cef_helpers.h"
+
+// Class that represents a readable/writable character buffer.
+class CefStreamResourceHandler::Buffer {
+ public:
+  Buffer()
+      : size_(0),
+        bytes_requested_(0),
+        bytes_written_(0),
+        bytes_read_(0) {
+  }
+
+  void Reset(int new_size) {
+    if (size_ < new_size) {
+      size_ = new_size;
+      buffer_.reset(new char[size_]);
+      DCHECK(buffer_);
+    }
+    bytes_requested_ = new_size;
+    bytes_written_ = 0;
+    bytes_read_ = 0;
+  }
+
+  bool IsEmpty() const {
+    return (bytes_written_ == 0);
+  }
+
+  bool CanRead() const {
+    return (bytes_read_ < bytes_written_);
+  }
+
+  int WriteTo(void* data_out, int bytes_to_read) {
+    const int write_size =
+        std::min(bytes_to_read, bytes_written_ - bytes_read_);
+    if (write_size > 0) {
+      memcpy(data_out, buffer_ .get() + bytes_read_, write_size);
+      bytes_read_ += write_size;
+    }
+    return write_size;
+  }
+
+  int ReadFrom(CefRefPtr<CefStreamReader> reader) {
+    // Read until the buffer is full or until Read() returns 0 to indicate no
+    // more data.
+    int bytes_read;
+    do {
+      bytes_read = static_cast<int>(
+          reader->Read(buffer_.get() + bytes_written_, 1,
+                       bytes_requested_ - bytes_written_));
+      bytes_written_ += bytes_read;
+    } while (bytes_read != 0 && bytes_written_ < bytes_requested_);
+
+    return bytes_written_;
+  }
+
+ private:
+  scoped_ptr<char[]> buffer_;
+  int size_;
+  int bytes_requested_;
+  int bytes_written_;
+  int bytes_read_;
+
+  DISALLOW_COPY_AND_ASSIGN(Buffer);
+};
+
+CefStreamResourceHandler::CefStreamResourceHandler(
+    const CefString& mime_type,
+    CefRefPtr<CefStreamReader> stream)
+    : status_code_(200),
+      status_text_("OK"),
+      mime_type_(mime_type),
+      stream_(stream)
+#if DCHECK_IS_ON()
+      , buffer_owned_by_file_thread_(false)
+#endif
+{
+  DCHECK(!mime_type_.empty());
+  DCHECK(stream_.get());
+  read_on_file_thread_ = stream_->MayBlock();
+}
+
+CefStreamResourceHandler::CefStreamResourceHandler(
+    int status_code,
+    const CefString& status_text,
+    const CefString& mime_type,
+    CefResponse::HeaderMap header_map,
+    CefRefPtr<CefStreamReader> stream)
+    : status_code_(status_code),
+      status_text_(status_text),
+      mime_type_(mime_type),
+      header_map_(header_map),
+      stream_(stream)
+#if DCHECK_IS_ON()
+      , buffer_owned_by_file_thread_(false)
+#endif
+{
+  DCHECK(!mime_type_.empty());
+  DCHECK(stream_.get());
+  read_on_file_thread_ = stream_->MayBlock();
+}
+
+CefStreamResourceHandler::~CefStreamResourceHandler() {
+}
+
+bool CefStreamResourceHandler::ProcessRequest(CefRefPtr<CefRequest> request,
+                                              CefRefPtr<CefCallback> callback) {
+  callback->Continue();
+  return true;
+}
+
+void CefStreamResourceHandler::GetResponseHeaders(
+    CefRefPtr<CefResponse> response,
+    int64& response_length,
+    CefString& redirectUrl) {
+  response->SetStatus(status_code_);
+  response->SetStatusText(status_text_);
+  response->SetMimeType(mime_type_);
+
+  if (!header_map_.empty())
+    response->SetHeaderMap(header_map_);
+
+  response_length = -1;
+}
+
+bool CefStreamResourceHandler::ReadResponse(void* data_out,
+                                            int bytes_to_read,
+                                            int& bytes_read,
+                                            CefRefPtr<CefCallback> callback) {
+  DCHECK_GT(bytes_to_read, 0);
+
+  if (read_on_file_thread_) {
+#if DCHECK_IS_ON()
+    DCHECK(!buffer_owned_by_file_thread_);
+#endif
+    if (buffer_ && (buffer_->CanRead() || buffer_->IsEmpty())) {
+      if (buffer_->CanRead()) {
+        // Provide data from the buffer.
+        bytes_read = buffer_->WriteTo(data_out, bytes_to_read);
+        return (bytes_read > 0);
+      } else {
+        // End of the steam.
+        bytes_read = 0;
+        return false;
+      }
+    } else {
+      // Perform another read on the file thread.
+      bytes_read = 0;
+#if DCHECK_IS_ON()
+      buffer_owned_by_file_thread_ = true;
+#endif
+      CefPostTask(TID_FILE,
+          base::Bind(&CefStreamResourceHandler::ReadOnFileThread, this,
+                     bytes_to_read, callback));
+      return true;
+    }
+  } else {
+    // Read until the buffer is full or until Read() returns 0 to indicate no
+    // more data.
+    bytes_read = 0;
+    int read = 0;
+    do {
+      read = static_cast<int>(
+          stream_->Read(static_cast<char*>(data_out) + bytes_read, 1,
+                        bytes_to_read - bytes_read));
+      bytes_read += read;
+    } while (read != 0 && bytes_read < bytes_to_read);
+
+    return (bytes_read > 0);
+  }
+}
+
+void CefStreamResourceHandler::Cancel() {
+}
+
+void CefStreamResourceHandler::ReadOnFileThread(
+    int bytes_to_read,
+    CefRefPtr<CefCallback> callback) {
+  CEF_REQUIRE_FILE_THREAD();
+#if DCHECK_IS_ON()
+  DCHECK(buffer_owned_by_file_thread_);
+#endif
+
+  if (!buffer_)
+    buffer_.reset(new Buffer());
+  buffer_->Reset(bytes_to_read);
+  buffer_->ReadFrom(stream_);
+
+#if DCHECK_IS_ON()
+  buffer_owned_by_file_thread_ = false;
+#endif
+  callback->Continue();
+}