mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Create 2272 release branch for CEF3.
git-svn-id: https://chromiumembedded.googlecode.com/svn/branches/2272@1993 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
203
libcef_dll/wrapper/cef_stream_resource_handler.cc
Normal file
203
libcef_dll/wrapper/cef_stream_resource_handler.cc
Normal file
@ -0,0 +1,203 @@
|
||||
// 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)
|
||||
#ifndef NDEBUG
|
||||
, 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) {
|
||||
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_) {
|
||||
#ifndef NDEBUG
|
||||
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;
|
||||
#ifndef NDEBUG
|
||||
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();
|
||||
#ifndef NDEBUG
|
||||
DCHECK(buffer_owned_by_file_thread_);
|
||||
#endif
|
||||
|
||||
if (!buffer_)
|
||||
buffer_.reset(new Buffer());
|
||||
buffer_->Reset(bytes_to_read);
|
||||
buffer_->ReadFrom(stream_);
|
||||
|
||||
#ifndef NDEBUG
|
||||
buffer_owned_by_file_thread_ = false;
|
||||
#endif
|
||||
callback->Continue();
|
||||
}
|
Reference in New Issue
Block a user