Branch CEF3 files from /branches/cef3 to /trunk/cef3 (issue #564).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@571 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2012-04-03 01:34:16 +00:00
parent b568f160d9
commit 34adee805c
516 changed files with 83249 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
// Copyright (c) 2012 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.
// Get basic type definitions.
#define IPC_MESSAGE_IMPL
#include "libcef/common/cef_message_generator.h"
// Generate constructors.
#include "ipc/struct_constructor_macros.h"
#include "libcef/common/cef_message_generator.h"
// Generate destructors.
#include "ipc/struct_destructor_macros.h"
#include "libcef/common/cef_message_generator.h"
// Generate param traits write methods.
#include "ipc/param_traits_write_macros.h"
namespace IPC {
#include "libcef/common/cef_message_generator.h"
} // namespace IPC
// Generate param traits read methods.
#include "ipc/param_traits_read_macros.h"
namespace IPC {
#include "libcef/common/cef_message_generator.h"
} // namespace IPC
// Generate param traits log methods.
#include "ipc/param_traits_log_macros.h"
namespace IPC {
#include "libcef/common/cef_message_generator.h"
} // namespace IPC

View File

@@ -0,0 +1,7 @@
// Copyright (c) 2011 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.
// Multiply-included file, hence no include guard.
#include "libcef/common/cef_messages.h"

View File

@@ -0,0 +1,178 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 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.
// IPC messages for CEF.
// Multiply-included message file, hence no include guard.
#include "base/shared_memory.h"
#include "base/values.h"
#include "content/public/common/common_param_traits.h"
#include "content/public/common/referrer.h"
#include "ipc/ipc_message_macros.h"
#include "net/base/upload_data.h"
// TODO(cef): Re-using the message start for extensions may be problematic in
// the future. It would be better if ipc_message_utils.h contained a value
// reserved for consumers of the content API.
// See: http://crbug.com/110911
#define IPC_MESSAGE_START ExtensionMsgStart
// Common types.
// Parameters structure for a request.
IPC_STRUCT_BEGIN(Cef_Request_Params)
// Unique request id to match requests and responses.
IPC_STRUCT_MEMBER(int, request_id)
// Unique id of the target frame. -1 if unknown / invalid.
IPC_STRUCT_MEMBER(int64, frame_id)
// True if the request is user-initiated instead of internal.
IPC_STRUCT_MEMBER(bool, user_initiated)
// True if a response is expected.
IPC_STRUCT_MEMBER(bool, expect_response)
// Message name.
IPC_STRUCT_MEMBER(std::string, name)
// List of message arguments.
IPC_STRUCT_MEMBER(ListValue, arguments)
IPC_STRUCT_END()
// Parameters structure for a response.
IPC_STRUCT_BEGIN(Cef_Response_Params)
// Unique request id to match requests and responses.
IPC_STRUCT_MEMBER(int, request_id)
// True if a response ack is expected.
IPC_STRUCT_MEMBER(bool, expect_response_ack)
// True on success.
IPC_STRUCT_MEMBER(bool, success)
// Response or error string depending on the value of |success|.
IPC_STRUCT_MEMBER(std::string, response)
IPC_STRUCT_END()
// Messages sent from the browser to the renderer.
// Tell the renderer which browser window it's being attached to.
IPC_MESSAGE_ROUTED2(CefMsg_UpdateBrowserWindowId,
int /* browser_id */,
bool /* is_popup */)
// Parameters for a resource request.
IPC_STRUCT_BEGIN(CefMsg_LoadRequest_Params)
// The request method: GET, POST, etc.
IPC_STRUCT_MEMBER(std::string, method)
// The requested URL.
IPC_STRUCT_MEMBER(GURL, url)
// The URL to send in the "Referer" header field. Can be empty if there is
// no referrer.
IPC_STRUCT_MEMBER(GURL, referrer)
// One of the WebKit::WebReferrerPolicy values.
IPC_STRUCT_MEMBER(int, referrer_policy)
// Identifies the frame within the RenderView that sent the request.
// -1 if unknown / invalid.
IPC_STRUCT_MEMBER(int64, frame_id)
// Usually the URL of the document in the top-level window, which may be
// checked by the third-party cookie blocking policy. Leaving it empty may
// lead to undesired cookie blocking. Third-party cookie blocking can be
// bypassed by setting first_party_for_cookies = url, but this should ideally
// only be done if there really is no way to determine the correct value.
IPC_STRUCT_MEMBER(GURL, first_party_for_cookies)
// Additional HTTP request headers.
IPC_STRUCT_MEMBER(std::string, headers)
// net::URLRequest load flags (0 by default).
IPC_STRUCT_MEMBER(int, load_flags)
// Optional upload data (may be null).
IPC_STRUCT_MEMBER(scoped_refptr<net::UploadData>, upload_data)
IPC_STRUCT_END()
// Tell the renderer to load a request.
IPC_MESSAGE_ROUTED1(CefMsg_LoadRequest,
CefMsg_LoadRequest_Params)
// Sent when the browser has a request for the renderer. The renderer may
// respond with a CefHostMsg_Response.
IPC_MESSAGE_ROUTED1(CefMsg_Request,
Cef_Request_Params)
// Optional message sent in response to a CefHostMsg_Request.
IPC_MESSAGE_ROUTED1(CefMsg_Response,
Cef_Response_Params)
// Optional Ack message sent to the browser to notify that a CefHostMsg_Response
// has been processed.
IPC_MESSAGE_ROUTED1(CefMsg_ResponseAck,
int /* request_id */)
// Sent to child processes to register a scheme.
IPC_MESSAGE_CONTROL4(CefProcessMsg_RegisterScheme,
std::string /* sheme_name */,
bool /* is_standard */,
bool /* is_local */,
bool /* is_display_isolated */)
// Sent to child processes to add or remove a cross-origin whitelist entry.
IPC_MESSAGE_CONTROL5(CefProcessMsg_ModifyCrossOriginWhitelistEntry,
bool /* add */,
std::string /* source_origin */,
std::string /* target_protocol */,
std::string /* target_domain */,
bool /* allow_target_subdomains */)
// Sent to child processes to clear the cross-origin whitelist.
IPC_MESSAGE_CONTROL0(CefProcessMsg_ClearCrossOriginWhitelist)
// Messages sent from the renderer to the browser.
// Sent when the render thread has started and all filters are attached.
IPC_MESSAGE_CONTROL0(CefProcessHostMsg_RenderThreadStarted)
// Sent when a frame is identified for the first time.
IPC_MESSAGE_ROUTED3(CefHostMsg_FrameIdentified,
int64 /* frame_id */,
int64 /* parent_frame_id */,
string16 /* frame_name */)
// Sent when a frame has been detached.
IPC_MESSAGE_ROUTED1(CefHostMsg_FrameDetached,
int64 /* frame_id */)
// Sent when a new frame has been given focus.
IPC_MESSAGE_ROUTED1(CefHostMsg_FrameFocusChange,
int64 /* frame_id */)
// Sent when a new URL is about to be loaded in the main frame. Used for the
// cookie manager.
IPC_MESSAGE_ROUTED1(CefHostMsg_LoadingURLChange,
GURL /* loading_url */)
// Sent when the renderer has a request for the browser. The browser may respond
// with a CefMsg_Response.
IPC_MESSAGE_ROUTED1(CefHostMsg_Request,
Cef_Request_Params)
// Optional message sent in response to a CefMsg_Request.
IPC_MESSAGE_ROUTED1(CefHostMsg_Response,
Cef_Response_Params)
// Optional Ack message sent to the browser to notify that a CefMsg_Response
// has been processed.
IPC_MESSAGE_ROUTED1(CefHostMsg_ResponseAck,
int /* request_id */)

View File

@@ -0,0 +1,24 @@
// 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 "libcef/common/cef_switches.h"
namespace switches {
// Product version string.
const char kProductVersion[] = "product-version";
// Locale string.
const char kLocale[] = "locale";
// Path to cef.pak file.
const char kPackFilePath[] = "pack-file-path";
// Path to locales directory.
const char kLocalesDirPath[] = "locales-dir-path";
// Path to locales directory.
const char kPackLoadingDisabled[] = "pack-loading-disabled";
} // namespace switches

View File

@@ -0,0 +1,21 @@
// 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.
// Defines all the "cef" command-line switches.
#ifndef CEF_LIBCEF_COMMON_CEF_SWITCHES_H_
#define CEF_LIBCEF_COMMON_CEF_SWITCHES_H_
#pragma once
namespace switches {
extern const char kProductVersion[];
extern const char kLocale[];
extern const char kPackFilePath[];
extern const char kLocalesDirPath[];
extern const char kPackLoadingDisabled[];
} // namespace switches
#endif // CEF_LIBCEF_COMMON_CEF_SWITCHES_H_

View File

@@ -0,0 +1,146 @@
// 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 "libcef/common/command_line_impl.h"
#include "base/file_path.h"
#include "base/logging.h"
CefCommandLineImpl::CefCommandLineImpl(CommandLine* value,
bool will_delete,
bool read_only)
: CefValueBase<CefCommandLine, CommandLine>(
value, NULL, will_delete ? kOwnerWillDelete : kOwnerNoDelete,
read_only, NULL) {
}
bool CefCommandLineImpl::IsValid() {
return !detached();
}
bool CefCommandLineImpl::IsReadOnly() {
return read_only();
}
CefRefPtr<CefCommandLine> CefCommandLineImpl::Copy() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return new CefCommandLineImpl(
new CommandLine(const_value().argv()), true, false);
}
void CefCommandLineImpl::InitFromArgv(int argc, const char* const* argv) {
#if !defined(OS_WIN)
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->InitFromArgv(argc, argv);
#else
NOTREACHED() << "method not supported on this platform";
#endif
}
void CefCommandLineImpl::InitFromString(const CefString& command_line) {
#if defined(OS_WIN)
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->ParseFromString(command_line);
#else
NOTREACHED() << "method not supported on this platform";
#endif
}
void CefCommandLineImpl::Reset() {
CEF_VALUE_VERIFY_RETURN_VOID(true);
CommandLine::StringVector argv;
argv.push_back(mutable_value()->GetProgram().value());
mutable_value()->InitFromArgv(argv);
const CommandLine::SwitchMap& map = mutable_value()->GetSwitches();
const_cast<CommandLine::SwitchMap*>(&map)->clear();
}
CefString CefCommandLineImpl::GetCommandLineString() {
CEF_VALUE_VERIFY_RETURN(false, CefString());
return const_value().GetCommandLineString();
}
CefString CefCommandLineImpl::GetProgram() {
CEF_VALUE_VERIFY_RETURN(false, CefString());
return const_value().GetProgram().value();
}
void CefCommandLineImpl::SetProgram(const CefString& program) {
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->SetProgram(FilePath(program));
}
bool CefCommandLineImpl::HasSwitches() {
CEF_VALUE_VERIFY_RETURN(false, false);
return (const_value().GetSwitches().size() > 0);
}
bool CefCommandLineImpl::HasSwitch(const CefString& name) {
CEF_VALUE_VERIFY_RETURN(false, false);
return const_value().HasSwitch(name);
}
CefString CefCommandLineImpl::GetSwitchValue(const CefString& name) {
CEF_VALUE_VERIFY_RETURN(false, CefString());
return const_value().GetSwitchValueNative(name);
}
void CefCommandLineImpl::GetSwitches(SwitchMap& switches) {
CEF_VALUE_VERIFY_RETURN_VOID(false);
const CommandLine::SwitchMap& map = const_value().GetSwitches();
CommandLine::SwitchMap::const_iterator it = map.begin();
for (; it != map.end(); ++it)
switches.insert(std::make_pair(it->first, it->second));
}
void CefCommandLineImpl::AppendSwitch(const CefString& name) {
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->AppendSwitch(name);
}
void CefCommandLineImpl::AppendSwitchWithValue(const CefString& name,
const CefString& value) {
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->AppendSwitchNative(name, value);
}
bool CefCommandLineImpl::HasArguments() {
CEF_VALUE_VERIFY_RETURN(false, false);
return (const_value().GetArgs().size() > 0);
}
void CefCommandLineImpl::GetArguments(ArgumentList& arguments) {
CEF_VALUE_VERIFY_RETURN_VOID(false);
const CommandLine::StringVector& vec = const_value().GetArgs();
CommandLine::StringVector::const_iterator it = vec.begin();
for (; it != vec.end(); ++it)
arguments.push_back(*it);
}
void CefCommandLineImpl::AppendArgument(const CefString& argument) {
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->AppendArgNative(argument);
}
// CefCommandLine implementation.
// static
CefRefPtr<CefCommandLine> CefCommandLine::CreateCommandLine() {
return new CefCommandLineImpl(
new CommandLine(CommandLine::NO_PROGRAM), true, false);
}
// static
CefRefPtr<CefCommandLine> CefCommandLine::GetGlobalCommandLine() {
// Uses a singleton reference object.
static CefRefPtr<CefCommandLineImpl> commandLinePtr;
if (!commandLinePtr.get()) {
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line)
commandLinePtr = new CefCommandLineImpl(command_line, false, true);
}
return commandLinePtr.get();
}

View File

@@ -0,0 +1,45 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_COMMAND_LINE_IMPL_H_
#define CEF_LIBCEF_COMMON_COMMAND_LINE_IMPL_H_
#pragma once
#include "include/cef_command_line.h"
#include "libcef/common/value_base.h"
#include "base/command_line.h"
// CefCommandLine implementation
class CefCommandLineImpl : public CefValueBase<CefCommandLine, CommandLine> {
public:
CefCommandLineImpl(CommandLine* value,
bool will_delete,
bool read_only);
// CefCommandLine methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsReadOnly() OVERRIDE;
virtual CefRefPtr<CefCommandLine> Copy() OVERRIDE;
virtual void InitFromArgv(int argc, const char* const* argv) OVERRIDE;
virtual void InitFromString(const CefString& command_line) OVERRIDE;
virtual void Reset() OVERRIDE;
virtual CefString GetCommandLineString() OVERRIDE;
virtual CefString GetProgram() OVERRIDE;
virtual void SetProgram(const CefString& program) OVERRIDE;
virtual bool HasSwitches() OVERRIDE;
virtual bool HasSwitch(const CefString& name) OVERRIDE;
virtual CefString GetSwitchValue(const CefString& name) OVERRIDE;
virtual void GetSwitches(SwitchMap& switches) OVERRIDE;
virtual void AppendSwitch(const CefString& name) OVERRIDE;
virtual void AppendSwitchWithValue(const CefString& name,
const CefString& value) OVERRIDE;
virtual bool HasArguments() OVERRIDE;
virtual void GetArguments(ArgumentList& arguments) OVERRIDE;
virtual void AppendArgument(const CefString& argument) OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(CefCommandLineImpl);
};
#endif // CEF_LIBCEF_COMMON_COMMAND_LINE_IMPL_H_

View File

@@ -0,0 +1,135 @@
// Copyright (c) 2012 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 "libcef/common/content_client.h"
#include "include/cef_stream.h"
#include "include/cef_version.h"
#include "libcef/common/cef_switches.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/string_piece.h"
#include "base/stringprintf.h"
#include "content/public/common/content_switches.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/glue/user_agent.h"
CefContentClient::CefContentClient(CefRefPtr<CefApp> application)
: application_(application),
pack_loading_disabled_(false) {
}
CefContentClient::~CefContentClient() {
}
// static
CefContentClient* CefContentClient::Get() {
return static_cast<CefContentClient*>(content::GetContentClient());
}
void CefContentClient::SetActiveURL(const GURL& url) {
}
void CefContentClient::SetGpuInfo(const content::GPUInfo& gpu_info) {
}
void CefContentClient::AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) {
}
void CefContentClient::AddNPAPIPlugins(
webkit::npapi::PluginList* plugin_list) {
}
bool CefContentClient::HasWebUIScheme(const GURL& url) const {
// There are no WebUI URLs in CEF.
return false;
}
bool CefContentClient::CanHandleWhileSwappedOut(const IPC::Message& msg) {
return false;
}
std::string CefContentClient::GetUserAgent(bool* overriding) const {
static CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kUserAgent)) {
*overriding = true;
return command_line.GetSwitchValueASCII(switches::kUserAgent);
} else {
std::string product_version;
if (command_line.HasSwitch(switches::kProductVersion)) {
*overriding = true;
product_version =
command_line.GetSwitchValueASCII(switches::kProductVersion);
} else {
*overriding = false;
product_version = base::StringPrintf("Chrome/%d.%d.%d.%d",
CHROME_VERSION_MAJOR, CHROME_VERSION_MINOR, CHROME_VERSION_BUILD,
CHROME_VERSION_PATCH);
}
return webkit_glue::BuildUserAgentFromProduct(product_version);
}
}
string16 CefContentClient::GetLocalizedString(int message_id) const {
string16 value;
if (application_.get()) {
CefRefPtr<CefResourceBundleHandler> handler =
application_->GetResourceBundleHandler();
if (handler.get()) {
CefString cef_str;
if (handler->GetLocalizedString(message_id, cef_str))
value = cef_str;
}
}
if (value.empty() && !pack_loading_disabled_)
value = ResourceBundle::GetSharedInstance().GetLocalizedString(message_id);
if (value.empty())
LOG(ERROR) << "No localized string available for id " << message_id;
return value;
}
base::StringPiece CefContentClient::GetDataResource(int resource_id) const {
base::StringPiece value;
if (application_.get()) {
CefRefPtr<CefResourceBundleHandler> handler =
application_->GetResourceBundleHandler();
if (handler.get()) {
void* data = NULL;
size_t data_size = 0;
if (handler->GetDataResource(resource_id, data, data_size))
value = base::StringPiece(static_cast<char*>(data), data_size);
}
}
if (value.empty() && !pack_loading_disabled_)
value = ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id);
if (value.empty())
LOG(ERROR) << "No data resource available for id " << resource_id;
return value;
}
#if defined(OS_WIN)
bool CefContentClient::SandboxPlugin(CommandLine* command_line,
sandbox::TargetPolicy* policy) {
return false;
}
#endif
#if defined(OS_MACOSX)
bool CefContentClient::GetSandboxProfileForSandboxType(
int sandbox_type,
int* sandbox_profile_resource_id) const {
return false;
}
#endif

View File

@@ -0,0 +1,58 @@
// Copyright (c) 2012 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.
#ifndef CEF_LIBCEF_COMMON_CONTENT_CLIENT_H_
#define CEF_LIBCEF_COMMON_CONTENT_CLIENT_H_
#pragma once
#include <string>
#include <vector>
#include "include/cef_app.h"
#include "base/compiler_specific.h"
#include "content/public/common/content_client.h"
class CefContentClient : public content::ContentClient {
public:
explicit CefContentClient(CefRefPtr<CefApp> application);
virtual ~CefContentClient();
// Returns the singleton CefContentClient instance.
static CefContentClient* Get();
virtual void SetActiveURL(const GURL& url) OVERRIDE;
virtual void SetGpuInfo(const content::GPUInfo& gpu_info) OVERRIDE;
virtual void AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) OVERRIDE;
virtual void AddNPAPIPlugins(
webkit::npapi::PluginList* plugin_list) OVERRIDE;
virtual bool HasWebUIScheme(const GURL& url) const OVERRIDE;
virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) OVERRIDE;
virtual std::string GetUserAgent(bool* overriding) const OVERRIDE;
virtual string16 GetLocalizedString(int message_id) const OVERRIDE;
virtual base::StringPiece GetDataResource(int resource_id) const OVERRIDE;
#if defined(OS_WIN)
virtual bool SandboxPlugin(CommandLine* command_line,
sandbox::TargetPolicy* policy) OVERRIDE;
#endif
#if defined(OS_MACOSX)
virtual bool GetSandboxProfileForSandboxType(
int sandbox_type,
int* sandbox_profile_resource_id) const OVERRIDE;
#endif
CefRefPtr<CefApp> application() const { return application_; }
void set_pack_loading_disabled(bool val) { pack_loading_disabled_ = val; }
bool pack_loading_disabled() const { return pack_loading_disabled_; }
private:
CefRefPtr<CefApp> application_;
bool pack_loading_disabled_;
};
#endif // CEF_LIBCEF_COMMON_CONTENT_CLIENT_H_

View File

@@ -0,0 +1,43 @@
// Copyright (c) 2011 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 "libcef/common/http_header_utils.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
using net::HttpResponseHeaders;
namespace HttpHeaderUtils {
std::string GenerateHeaders(const HeaderMap& map) {
std::string headers;
for (HeaderMap::const_iterator header = map.begin();
header != map.end();
++header) {
const CefString& key = header->first;
const CefString& value = header->second;
if (!key.empty()) {
// Delimit with "\r\n".
if (!headers.empty())
headers += "\r\n";
headers += std::string(key) + ": " + std::string(value);
}
}
return headers;
}
void ParseHeaders(const std::string& header_str, HeaderMap& map) {
// Parse the request header values
for (net::HttpUtil::HeadersIterator i(header_str.begin(),
header_str.end(), "\n");
i.GetNext(); ) {
map.insert(std::make_pair(i.name(), i.values()));
}
}
} // namespace HttpHeaderUtils

View File

@@ -0,0 +1,22 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_HTTP_HEADER_UTILS_H_
#define CEF_LIBCEF_COMMON_HTTP_HEADER_UTILS_H_
#pragma once
#include <string>
#include "include/cef_request.h"
namespace HttpHeaderUtils {
typedef CefRequest::HeaderMap HeaderMap;
std::string GenerateHeaders(const HeaderMap& map);
void ParseHeaders(const std::string& header_str, HeaderMap& map);
}; // namespace HttpHeaderUtils
#endif // CEF_LIBCEF_COMMON_HTTP_HEADER_UTILS_H_

View File

@@ -0,0 +1,311 @@
// Copyright (c) 2012 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 "libcef/common/main_delegate.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/command_line_impl.h"
#include "libcef/plugin/content_plugin_client.h"
#include "libcef/renderer/content_renderer_client.h"
#include "libcef/utility/content_utility_client.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#if defined(OS_MACOSX)
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "content/public/common/content_paths.h"
namespace {
FilePath GetFrameworksPath() {
// Start out with the path to the running executable.
FilePath path;
PathService::Get(base::FILE_EXE, &path);
// Up to Contents.
if (base::mac::IsBackgroundOnlyProcess()) {
// The running executable is the helper. Go up five steps:
// Contents/Frameworks/Helper.app/Contents/MacOS/Helper
// ^ to here ^ from here
path = path.DirName().DirName().DirName().DirName().DirName();
} else {
// One step up to MacOS, another to Contents.
path = path.DirName().DirName();
}
DCHECK_EQ(path.BaseName().value(), "Contents");
// Go into the frameworks directory.
return path.Append("Frameworks");
}
// The framework bundle path is used for loading resources, libraries, etc.
void OverrideFrameworkBundlePath() {
FilePath helper_path =
GetFrameworksPath().Append("Chromium Embedded Framework.framework");
base::mac::SetOverrideFrameworkBundlePath(helper_path);
}
void OverrideChildProcessPath() {
// Retrieve the name of the running executable.
FilePath path;
PathService::Get(base::FILE_EXE, &path);
std::string name = path.BaseName().value();
FilePath helper_path = GetFrameworksPath().Append(name+" Helper.app")
.Append("Contents")
.Append("MacOS")
.Append(name+" Helper");
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
}
} // namespace
#endif // OS_MACOSX
CefMainDelegate::CefMainDelegate(CefRefPtr<CefApp> application)
: content_client_(application) {
}
CefMainDelegate::~CefMainDelegate() {
}
bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
#if defined(OS_MACOSX)
OverrideFrameworkBundlePath();
#endif
CommandLine* command_line = CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
if (process_type.empty()) {
// In the browser process. Populate the global command-line object.
const CefSettings& settings = _Context->settings();
if (settings.command_line_args_disabled) {
// Remove any existing command-line arguments.
CommandLine::StringVector argv;
argv.push_back(command_line->GetProgram().value());
command_line->InitFromArgv(argv);
const CommandLine::SwitchMap& map = command_line->GetSwitches();
const_cast<CommandLine::SwitchMap*>(&map)->clear();
}
if (settings.single_process)
command_line->AppendSwitch(switches::kSingleProcess);
if (settings.browser_subprocess_path.length > 0) {
FilePath file_path =
FilePath(CefString(&settings.browser_subprocess_path));
if (!file_path.empty()) {
command_line->AppendSwitchPath(switches::kBrowserSubprocessPath,
file_path);
}
}
if (settings.user_agent.length > 0) {
command_line->AppendSwitchASCII(switches::kUserAgent,
CefString(&settings.user_agent));
} else if (settings.product_version.length > 0) {
command_line->AppendSwitchASCII(switches::kProductVersion,
CefString(&settings.product_version));
}
if (settings.locale.length > 0) {
command_line->AppendSwitchASCII(switches::kLocale,
CefString(&settings.locale));
}
if (settings.pack_loading_disabled) {
command_line->AppendSwitch(switches::kPackLoadingDisabled);
} else {
if (settings.pack_file_path.length > 0) {
FilePath file_path = FilePath(CefString(&settings.pack_file_path));
if (!file_path.empty())
command_line->AppendSwitchPath(switches::kPackFilePath, file_path);
}
if (settings.locales_dir_path.length > 0) {
FilePath file_path = FilePath(CefString(&settings.locales_dir_path));
if (!file_path.empty())
command_line->AppendSwitchPath(switches::kLocalesDirPath, file_path);
}
}
// TODO(cef): Figure out how to support the sandbox.
if (!command_line->HasSwitch(switches::kNoSandbox))
command_line->AppendSwitch(switches::kNoSandbox);
}
if (content_client_.application().get()) {
// Give the application a chance to view/modify the command line.
CefRefPtr<CefCommandLineImpl> commandLinePtr(
new CefCommandLineImpl(command_line, false, false));
content_client_.application()->OnBeforeCommandLineProcessing(
CefString(process_type), commandLinePtr.get());
commandLinePtr->Detach(NULL);
}
return false;
}
void CefMainDelegate::PreSandboxStartup() {
#if defined(OS_MACOSX)
OverrideChildProcessPath();
#endif
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
content::SetContentClient(&content_client_);
InitializeContentClient(process_type);
if (command_line.HasSwitch(switches::kPackLoadingDisabled))
content_client_.set_pack_loading_disabled(true);
else
InitializeResourceBundle();
}
void CefMainDelegate::SandboxInitialized(const std::string& process_type) {
}
int CefMainDelegate::RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) {
if (process_type.empty()) {
// Use our own browser process runner.
browser_runner_.reset(content::BrowserMainRunner::Create());
// Initialize browser process state. Results in a call to
// CefBrowserMain::GetMainMessageLoop().
int exit_code = browser_runner_->Initialize(main_function_params);
if (exit_code >= 0)
return exit_code;
return 0;
}
return -1;
}
void CefMainDelegate::ProcessExiting(const std::string& process_type) {
if (!content_client_.pack_loading_disabled())
ResourceBundle::CleanupSharedInstance();
}
#if defined(OS_MACOSX)
bool CefMainDelegate::ProcessRegistersWithSystemProcess(
const std::string& process_type) {
return false;
}
bool CefMainDelegate::ShouldSendMachPort(const std::string& process_type) {
return false;
}
bool CefMainDelegate::DelaySandboxInitialization(
const std::string& process_type) {
return false;
}
#elif defined(OS_POSIX)
content::ZygoteForkDelegate* CefMainDelegate::ZygoteStarting() {
return NULL;
}
void CefMainDelegate::ZygoteForked() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
InitializeContentClient(process_type);
}
#endif // OS_MACOSX
void CefMainDelegate::ShutdownBrowser() {
if (browser_runner_.get()) {
browser_runner_->Shutdown();
browser_runner_.reset(NULL);
}
}
void CefMainDelegate::InitializeContentClient(
const std::string& process_type) {
if (process_type.empty()) {
browser_client_.reset(new CefContentBrowserClient);
content::GetContentClient()->set_browser(browser_client_.get());
// Single-process is an unsupported and not fully tested mode.
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kSingleProcess)) {
content::RenderProcessHost::set_run_renderer_in_process(true);
renderer_client_.reset(new CefContentRendererClient);
content::GetContentClient()->set_renderer(renderer_client_.get());
}
} else if (process_type == switches::kRendererProcess) {
renderer_client_.reset(new CefContentRendererClient);
content::GetContentClient()->set_renderer(renderer_client_.get());
} else if (process_type == switches::kPluginProcess) {
plugin_client_.reset(new CefContentPluginClient);
content::GetContentClient()->set_plugin(plugin_client_.get());
} else if (process_type == switches::kUtilityProcess) {
utility_client_.reset(new CefContentUtilityClient);
content::GetContentClient()->set_utility(utility_client_.get());
}
}
void CefMainDelegate::InitializeResourceBundle() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
FilePath pak_file, locales_dir;
if (command_line.HasSwitch(switches::kPackFilePath))
pak_file = command_line.GetSwitchValuePath(switches::kPackFilePath);
if (pak_file.empty()) {
FilePath pak_dir;
PathService::Get(base::DIR_MODULE, &pak_dir);
pak_file = pak_dir.Append(FILE_PATH_LITERAL("cef.pak"));
}
if (!pak_file.empty())
PathService::Override(ui::FILE_RESOURCES_PAK, pak_file);
if (command_line.HasSwitch(switches::kLocalesDirPath))
locales_dir = command_line.GetSwitchValuePath(switches::kLocalesDirPath);
if (!locales_dir.empty())
PathService::Override(ui::DIR_LOCALES, locales_dir);
std::string locale = command_line.GetSwitchValueASCII(switches::kLocale);
if (locale.empty())
locale = "en-US";
const std::string loaded_locale =
ui::ResourceBundle::InitSharedInstanceWithLocale(locale);
CHECK(!loaded_locale.empty()) << "Locale could not be found for " << locale;
#if defined(OS_WIN)
// Explicitly load cef.pak on Windows.
if (file_util::PathExists(pak_file))
ResourceBundle::AddDataPackToSharedInstance(pak_file);
else
NOTREACHED() << "Could not load cef.pak";
#endif
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) 2011 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.
#ifndef CEF_LIBCEF_COMMON_MAIN_DELEGATE_H_
#define CEF_LIBCEF_COMMON_MAIN_DELEGATE_H_
#pragma once
#include <string>
#include "libcef/common/content_client.h"
#include "include/cef_app.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/app/content_main_delegate.h"
namespace content {
class BrowserMainRunner;
}
class CefContentBrowserClient;
class CefContentRendererClient;
class CefContentPluginClient;
class CefContentUtilityClient;
class MessageLoop;
class CefMainDelegate : public content::ContentMainDelegate {
public:
explicit CefMainDelegate(CefRefPtr<CefApp> application);
virtual ~CefMainDelegate();
virtual bool BasicStartupComplete(int* exit_code) OVERRIDE;
virtual void PreSandboxStartup() OVERRIDE;
virtual void SandboxInitialized(const std::string& process_type) OVERRIDE;
virtual int RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) OVERRIDE;
virtual void ProcessExiting(const std::string& process_type) OVERRIDE;
#if defined(OS_MACOSX)
virtual bool ProcessRegistersWithSystemProcess(
const std::string& process_type) OVERRIDE;
virtual bool ShouldSendMachPort(const std::string& process_type) OVERRIDE;
virtual bool DelaySandboxInitialization(
const std::string& process_type) OVERRIDE;
#elif defined(OS_POSIX)
virtual content::ZygoteForkDelegate* ZygoteStarting() OVERRIDE;
virtual void ZygoteForked() OVERRIDE;
#endif // OS_MACOSX
// Shut down the browser runner.
void ShutdownBrowser();
CefContentBrowserClient* browser_client() { return browser_client_.get(); }
CefContentClient* content_client() { return &content_client_; }
private:
void InitializeContentClient(const std::string& process_type);
void InitializeResourceBundle();
scoped_ptr<content::BrowserMainRunner> browser_runner_;
scoped_ptr<CefContentBrowserClient> browser_client_;
scoped_ptr<CefContentRendererClient> renderer_client_;
scoped_ptr<CefContentPluginClient> plugin_client_;
scoped_ptr<CefContentUtilityClient> utility_client_;
CefContentClient content_client_;
DISALLOW_COPY_AND_ASSIGN(CefMainDelegate);
};
#endif // CEF_LIBCEF_COMMON_MAIN_DELEGATE_H_

View File

@@ -0,0 +1,76 @@
// 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 "libcef/common/process_message_impl.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/values_impl.h"
#include "base/logging.h"
namespace {
void CopyList(const base::ListValue& source,
base::ListValue& target) {
base::ListValue::const_iterator it = source.begin();
for (; it != source.end(); ++it)
target.Append((*it)->DeepCopy());
}
void CopyValue(const Cef_Request_Params& source,
Cef_Request_Params& target) {
target.name = source.name;
CopyList(source.arguments, target.arguments);
}
} // namespace
// static
CefRefPtr<CefProcessMessage> CefProcessMessage::Create(const CefString& name) {
Cef_Request_Params* params = new Cef_Request_Params();
params->name = name;
return new CefProcessMessageImpl(params, true, false);
}
CefProcessMessageImpl::CefProcessMessageImpl(Cef_Request_Params* value,
bool will_delete,
bool read_only)
: CefValueBase<CefProcessMessage, Cef_Request_Params>(
value, NULL, will_delete ? kOwnerWillDelete : kOwnerNoDelete,
read_only, NULL) {
}
bool CefProcessMessageImpl::CopyTo(Cef_Request_Params& target) {
CEF_VALUE_VERIFY_RETURN(false, false);
CopyValue(const_value(), target);
return true;
}
bool CefProcessMessageImpl::IsValid() {
return !detached();
}
bool CefProcessMessageImpl::IsReadOnly() {
return read_only();
}
CefRefPtr<CefProcessMessage> CefProcessMessageImpl::Copy() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
Cef_Request_Params* params = new Cef_Request_Params();
CopyValue(const_value(), *params);
return new CefProcessMessageImpl(params, true, false);
}
CefString CefProcessMessageImpl::GetName() {
CEF_VALUE_VERIFY_RETURN(false, CefString());
return const_value().name;
}
CefRefPtr<CefListValue> CefProcessMessageImpl::GetArgumentList() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return CefListValueImpl::GetOrCreateRef(
const_cast<base::ListValue*>(&(const_value().arguments)),
const_cast<Cef_Request_Params*>(&const_value()),
read_only(),
controller());
}

View File

@@ -0,0 +1,35 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_PROCESS_MESSAGE_IMPL_H_
#define CEF_LIBCEF_COMMON_PROCESS_MESSAGE_IMPL_H_
#pragma once
#include "include/cef_process_message.h"
#include "libcef/common/value_base.h"
struct Cef_Request_Params;
// CefProcessMessage implementation
class CefProcessMessageImpl
: public CefValueBase<CefProcessMessage, Cef_Request_Params> {
public:
CefProcessMessageImpl(Cef_Request_Params* value,
bool will_delete,
bool read_only);
// Copies the underlying value to the specified |target| structure.
bool CopyTo(Cef_Request_Params& target);
// CefProcessMessage methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsReadOnly() OVERRIDE;
virtual CefRefPtr<CefProcessMessage> Copy() OVERRIDE;
virtual CefString GetName() OVERRIDE;
virtual CefRefPtr<CefListValue> GetArgumentList() OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(CefProcessMessageImpl);
};
#endif // CEF_LIBCEF_COMMON_PROCESS_MESSAGE_IMPL_H_

View File

@@ -0,0 +1,368 @@
// Copyright (c) 2008-2009 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 <string>
#include <vector>
#include "libcef/common/http_header_utils.h"
#include "libcef/common/request_impl.h"
#include "base/logging.h"
#include "net/url_request/url_request.h"
CefRefPtr<CefRequest> CefRequest::CreateRequest() {
CefRefPtr<CefRequest> request(new CefRequestImpl());
return request;
}
CefRequestImpl::CefRequestImpl()
: method_("GET"),
flags_(WUR_FLAG_NONE) {
}
CefString CefRequestImpl::GetURL() {
AutoLock lock_scope(this);
return url_;
}
void CefRequestImpl::SetURL(const CefString& url) {
AutoLock lock_scope(this);
url_ = url;
}
CefString CefRequestImpl::GetMethod() {
AutoLock lock_scope(this);
return method_;
}
void CefRequestImpl::SetMethod(const CefString& method) {
AutoLock lock_scope(this);
method_ = method;
}
CefRefPtr<CefPostData> CefRequestImpl::GetPostData() {
AutoLock lock_scope(this);
return postdata_;
}
void CefRequestImpl::SetPostData(CefRefPtr<CefPostData> postData) {
AutoLock lock_scope(this);
postdata_ = postData;
}
void CefRequestImpl::GetHeaderMap(HeaderMap& headerMap) {
AutoLock lock_scope(this);
headerMap = headermap_;
}
void CefRequestImpl::SetHeaderMap(const HeaderMap& headerMap) {
AutoLock lock_scope(this);
headermap_ = headerMap;
}
void CefRequestImpl::Set(const CefString& url,
const CefString& method,
CefRefPtr<CefPostData> postData,
const HeaderMap& headerMap) {
AutoLock lock_scope(this);
url_ = url;
method_ = method;
postdata_ = postData;
headermap_ = headerMap;
}
#define SETBOOLFLAG(obj, flags, method, FLAG) \
obj.method((flags & (FLAG)) == (FLAG))
CefRequest::RequestFlags CefRequestImpl::GetFlags() {
AutoLock lock_scope(this);
return flags_;
}
void CefRequestImpl::SetFlags(RequestFlags flags) {
AutoLock lock_scope(this);
flags_ = flags;
}
CefString CefRequestImpl::GetFirstPartyForCookies() {
AutoLock lock_scope(this);
return first_party_for_cookies_;
}
void CefRequestImpl::SetFirstPartyForCookies(const CefString& url) {
AutoLock lock_scope(this);
first_party_for_cookies_ = url;
}
void CefRequestImpl::Set(net::URLRequest* request) {
AutoLock lock_scope(this);
url_ = request->url().spec();
method_ = request->method();
first_party_for_cookies_ = request->first_party_for_cookies().spec();
net::HttpRequestHeaders headers = request->extra_request_headers();
// Ensure that we do not send username and password fields in the referrer.
GURL referrer(request->GetSanitizedReferrer());
// Strip Referer from request_info_.extra_headers to prevent, e.g., plugins
// from overriding headers that are controlled using other means. Otherwise a
// plugin could set a referrer although sending the referrer is inhibited.
headers.RemoveHeader(net::HttpRequestHeaders::kReferer);
// Our consumer should have made sure that this is a safe referrer. See for
// instance WebCore::FrameLoader::HideReferrer.
if (referrer.is_valid())
headers.SetHeader(net::HttpRequestHeaders::kReferer, referrer.spec());
// Transfer request headers
GetHeaderMap(headers, headermap_);
// Transfer post data, if any
net::UploadData* data = request->get_upload();
if (data) {
postdata_ = CefPostData::CreatePostData();
static_cast<CefPostDataImpl*>(postdata_.get())->Set(*data);
} else if (postdata_.get()) {
postdata_ = NULL;
}
}
void CefRequestImpl::Get(net::URLRequest* request) {
AutoLock lock_scope(this);
request->set_method(method_);
if (!first_party_for_cookies_.empty()) {
request->set_first_party_for_cookies(
GURL(std::string(first_party_for_cookies_)));
}
CefString referrerStr;
referrerStr.FromASCII("Referrer");
HeaderMap headerMap = headermap_;
HeaderMap::iterator it = headerMap.find(referrerStr);
if (it == headerMap.end()) {
request->set_referrer("");
} else {
request->set_referrer(it->second);
headerMap.erase(it);
}
net::HttpRequestHeaders headers;
headers.AddHeadersFromString(HttpHeaderUtils::GenerateHeaders(headerMap));
request->SetExtraRequestHeaders(headers);
if (postdata_.get()) {
net::UploadData* upload = new net::UploadData();
static_cast<CefPostDataImpl*>(postdata_.get())->Get(*upload);
request->set_upload(upload);
} else if (request->get_upload()) {
request->set_upload(NULL);
}
}
// static
void CefRequestImpl::GetHeaderMap(const net::HttpRequestHeaders& headers,
HeaderMap& map) {
net::HttpRequestHeaders::Iterator it(headers);
do {
map.insert(std::make_pair(it.name(), it.value()));
} while (it.GetNext());
}
CefRefPtr<CefPostData> CefPostData::CreatePostData() {
CefRefPtr<CefPostData> postdata(new CefPostDataImpl());
return postdata;
}
CefPostDataImpl::CefPostDataImpl() {
}
size_t CefPostDataImpl::GetElementCount() {
AutoLock lock_scope(this);
return elements_.size();
}
void CefPostDataImpl::GetElements(ElementVector& elements) {
AutoLock lock_scope(this);
elements = elements_;
}
bool CefPostDataImpl::RemoveElement(CefRefPtr<CefPostDataElement> element) {
AutoLock lock_scope(this);
ElementVector::iterator it = elements_.begin();
for (; it != elements_.end(); ++it) {
if (it->get() == element.get()) {
elements_.erase(it);
return true;
}
}
return false;
}
bool CefPostDataImpl::AddElement(CefRefPtr<CefPostDataElement> element) {
bool found = false;
AutoLock lock_scope(this);
// check that the element isn't already in the list before adding
ElementVector::const_iterator it = elements_.begin();
for (; it != elements_.end(); ++it) {
if (it->get() == element.get()) {
found = true;
break;
}
}
if (!found)
elements_.push_back(element);
return !found;
}
void CefPostDataImpl::RemoveElements() {
AutoLock lock_scope(this);
elements_.clear();
}
void CefPostDataImpl::Set(net::UploadData& data) {
AutoLock lock_scope(this);
CefRefPtr<CefPostDataElement> postelem;
std::vector<net::UploadData::Element>* elements = data.elements();
std::vector<net::UploadData::Element>::const_iterator it = elements->begin();
for (; it != elements->end(); ++it) {
postelem = CefPostDataElement::CreatePostDataElement();
static_cast<CefPostDataElementImpl*>(postelem.get())->Set(*it);
AddElement(postelem);
}
}
void CefPostDataImpl::Get(net::UploadData& data) {
AutoLock lock_scope(this);
net::UploadData::Element element;
std::vector<net::UploadData::Element> data_elements;
ElementVector::iterator it = elements_.begin();
for (; it != elements_.end(); ++it) {
static_cast<CefPostDataElementImpl*>(it->get())->Get(element);
data_elements.push_back(element);
}
data.SetElements(data_elements);
}
CefRefPtr<CefPostDataElement> CefPostDataElement::CreatePostDataElement() {
CefRefPtr<CefPostDataElement> element(new CefPostDataElementImpl());
return element;
}
CefPostDataElementImpl::CefPostDataElementImpl() {
type_ = PDE_TYPE_EMPTY;
memset(&data_, 0, sizeof(data_));
}
CefPostDataElementImpl::~CefPostDataElementImpl() {
SetToEmpty();
}
void CefPostDataElementImpl::SetToEmpty() {
AutoLock lock_scope(this);
if (type_ == PDE_TYPE_BYTES)
free(data_.bytes.bytes);
else if (type_ == PDE_TYPE_FILE)
cef_string_clear(&data_.filename);
type_ = PDE_TYPE_EMPTY;
memset(&data_, 0, sizeof(data_));
}
void CefPostDataElementImpl::SetToFile(const CefString& fileName) {
AutoLock lock_scope(this);
// Clear any data currently in the element
SetToEmpty();
// Assign the new data
type_ = PDE_TYPE_FILE;
cef_string_copy(fileName.c_str(), fileName.length(), &data_.filename);
}
void CefPostDataElementImpl::SetToBytes(size_t size, const void* bytes) {
AutoLock lock_scope(this);
// Clear any data currently in the element
SetToEmpty();
// Assign the new data
void* data = malloc(size);
DCHECK(data != NULL);
if (data == NULL)
return;
memcpy(data, bytes, size);
type_ = PDE_TYPE_BYTES;
data_.bytes.bytes = data;
data_.bytes.size = size;
}
CefPostDataElement::Type CefPostDataElementImpl::GetType() {
AutoLock lock_scope(this);
return type_;
}
CefString CefPostDataElementImpl::GetFile() {
AutoLock lock_scope(this);
DCHECK(type_ == PDE_TYPE_FILE);
CefString filename;
if (type_ == PDE_TYPE_FILE)
filename.FromString(data_.filename.str, data_.filename.length, false);
return filename;
}
size_t CefPostDataElementImpl::GetBytesCount() {
AutoLock lock_scope(this);
DCHECK(type_ == PDE_TYPE_BYTES);
size_t size = 0;
if (type_ == PDE_TYPE_BYTES)
size = data_.bytes.size;
return size;
}
size_t CefPostDataElementImpl::GetBytes(size_t size, void* bytes) {
AutoLock lock_scope(this);
DCHECK(type_ == PDE_TYPE_BYTES);
size_t rv = 0;
if (type_ == PDE_TYPE_BYTES) {
rv = (size < data_.bytes.size ? size : data_.bytes.size);
memcpy(bytes, data_.bytes.bytes, rv);
}
return rv;
}
void CefPostDataElementImpl::Set(const net::UploadData::Element& element) {
AutoLock lock_scope(this);
if (element.type() == net::UploadData::TYPE_BYTES) {
SetToBytes(element.bytes().size(),
static_cast<const void*>(
std::string(element.bytes().begin(),
element.bytes().end()).c_str()));
} else if (element.type() == net::UploadData::TYPE_FILE) {
SetToFile(element.file_path().value());
} else {
NOTREACHED();
}
}
void CefPostDataElementImpl::Get(net::UploadData::Element& element) {
AutoLock lock_scope(this);
if (type_ == PDE_TYPE_BYTES) {
element.SetToBytes(static_cast<char*>(data_.bytes.bytes), data_.bytes.size);
} else if (type_ == PDE_TYPE_FILE) {
FilePath path = FilePath(CefString(&data_.filename));
element.SetToFilePath(path);
} else {
NOTREACHED();
}
}

View File

@@ -0,0 +1,118 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_REQUEST_IMPL_H_
#define CEF_LIBCEF_COMMON_REQUEST_IMPL_H_
#pragma once
#include "include/cef_request.h"
#include "net/base/upload_data.h"
#include "net/http/http_request_headers.h"
namespace net {
class URLRequest;
};
// Implementation of CefRequest
class CefRequestImpl : public CefRequest {
public:
CefRequestImpl();
~CefRequestImpl() {}
virtual CefString GetURL() OVERRIDE;
virtual void SetURL(const CefString& url) OVERRIDE;
virtual CefString GetMethod() OVERRIDE;
virtual void SetMethod(const CefString& method) OVERRIDE;
virtual CefRefPtr<CefPostData> GetPostData() OVERRIDE;
virtual void SetPostData(CefRefPtr<CefPostData> postData) OVERRIDE;
virtual void GetHeaderMap(HeaderMap& headerMap) OVERRIDE;
virtual void SetHeaderMap(const HeaderMap& headerMap) OVERRIDE;
virtual void Set(const CefString& url,
const CefString& method,
CefRefPtr<CefPostData> postData,
const HeaderMap& headerMap) OVERRIDE;
virtual RequestFlags GetFlags() OVERRIDE;
virtual void SetFlags(RequestFlags flags) OVERRIDE;
virtual CefString GetFirstPartyForCookies() OVERRIDE;
virtual void SetFirstPartyForCookies(const CefString& url) OVERRIDE;
// Populate this object from the URLRequest object.
void Set(net::URLRequest* request);
// Populate the URLRequest object from this object.
void Get(net::URLRequest* request);
static void GetHeaderMap(const net::HttpRequestHeaders& headers,
HeaderMap& map);
protected:
CefString url_;
CefString method_;
CefRefPtr<CefPostData> postdata_;
HeaderMap headermap_;
// The below methods are used by WebURLRequest.
RequestFlags flags_;
CefString first_party_for_cookies_;
IMPLEMENT_REFCOUNTING(CefRequestImpl);
IMPLEMENT_LOCKING(CefRequestImpl);
};
// Implementation of CefPostData
class CefPostDataImpl : public CefPostData {
public:
CefPostDataImpl();
~CefPostDataImpl() {}
virtual size_t GetElementCount() OVERRIDE;
virtual void GetElements(ElementVector& elements) OVERRIDE;
virtual bool RemoveElement(CefRefPtr<CefPostDataElement> element) OVERRIDE;
virtual bool AddElement(CefRefPtr<CefPostDataElement> element) OVERRIDE;
virtual void RemoveElements();
void Set(net::UploadData& data);
void Get(net::UploadData& data);
protected:
ElementVector elements_;
IMPLEMENT_REFCOUNTING(CefPostDataImpl);
IMPLEMENT_LOCKING(CefPostDataImpl);
};
// Implementation of CefPostDataElement
class CefPostDataElementImpl : public CefPostDataElement {
public:
CefPostDataElementImpl();
~CefPostDataElementImpl();
virtual void SetToEmpty() OVERRIDE;
virtual void SetToFile(const CefString& fileName) OVERRIDE;
virtual void SetToBytes(size_t size, const void* bytes) OVERRIDE;
virtual Type GetType() OVERRIDE;
virtual CefString GetFile() OVERRIDE;
virtual size_t GetBytesCount() OVERRIDE;
virtual size_t GetBytes(size_t size, void* bytes) OVERRIDE;
void* GetBytes() { return data_.bytes.bytes; }
void Set(const net::UploadData::Element& element);
void Get(net::UploadData::Element& element);
protected:
Type type_;
union {
struct {
void* bytes;
size_t size;
} bytes;
cef_string_t filename;
} data_;
IMPLEMENT_REFCOUNTING(CefPostDataElementImpl);
IMPLEMENT_LOCKING(CefPostDataElementImpl);
};
#endif // CEF_LIBCEF_COMMON_REQUEST_IMPL_H_

View File

@@ -0,0 +1,98 @@
// 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 "libcef/common/response_impl.h"
#include "base/logging.h"
#include "base/stringprintf.h"
#include "net/http/http_response_headers.h"
CefResponseImpl::CefResponseImpl()
: status_code_(0) {
}
int CefResponseImpl::GetStatus() {
AutoLock lock_scope(this);
return status_code_;
}
void CefResponseImpl::SetStatus(int status) {
AutoLock lock_scope(this);
status_code_ = status;
}
CefString CefResponseImpl::GetStatusText() {
AutoLock lock_scope(this);
return status_text_;
}
void CefResponseImpl::SetStatusText(const CefString& statusText) {
AutoLock lock_scope(this);
status_text_ = statusText;
}
CefString CefResponseImpl::GetMimeType() {
AutoLock lock_scope(this);
return mime_type_;
}
void CefResponseImpl::SetMimeType(const CefString& mimeType) {
AutoLock lock_scope(this);
mime_type_ = mimeType;
}
CefString CefResponseImpl::GetHeader(const CefString& name) {
AutoLock lock_scope(this);
CefString value;
HeaderMap::const_iterator it = header_map_.find(name);
if (it != header_map_.end())
value = it->second;
return value;
}
void CefResponseImpl::GetHeaderMap(HeaderMap& map) {
AutoLock lock_scope(this);
map = header_map_;
}
void CefResponseImpl::SetHeaderMap(const HeaderMap& headerMap) {
AutoLock lock_scope(this);
header_map_ = headerMap;
}
net::HttpResponseHeaders* CefResponseImpl::GetResponseHeaders() {
AutoLock lock_scope(this);
std::string response;
std::string status_text;
if (status_text_.empty())
status_text = (status_code_ == 200)?"OK":"ERROR";
else
status_text = status_text_;
base::SStringPrintf(&response, "HTTP/1.1 %d %s", status_code_,
status_text.c_str());
if (header_map_.size() > 0) {
for (HeaderMap::const_iterator header = header_map_.begin();
header != header_map_.end();
++header) {
const CefString& key = header->first;
const CefString& value = header->second;
if (!key.empty()) {
// Delimit with "\0" as required by net::HttpResponseHeaders.
std::string key_str(key);
std::string value_str(value);
base::StringAppendF(&response, "%c%s: %s", '\0', key_str.c_str(),
value_str.c_str());
}
}
}
return new net::HttpResponseHeaders(response);
}

View File

@@ -0,0 +1,44 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_RESPONSE_IMPL_H_
#define CEF_LIBCEF_COMMON_RESPONSE_IMPL_H_
#pragma once
#include "include/cef_response.h"
namespace net {
class HttpResponseHeaders;
}
// Implementation of CefResponse.
class CefResponseImpl : public CefResponse {
public:
CefResponseImpl();
~CefResponseImpl() {}
// CefResponse API
virtual int GetStatus();
virtual void SetStatus(int status);
virtual CefString GetStatusText();
virtual void SetStatusText(const CefString& statusText);
virtual CefString GetMimeType();
virtual void SetMimeType(const CefString& mimeType);
virtual CefString GetHeader(const CefString& name);
virtual void GetHeaderMap(HeaderMap& headerMap);
virtual void SetHeaderMap(const HeaderMap& headerMap);
net::HttpResponseHeaders* GetResponseHeaders();
protected:
int status_code_;
CefString status_text_;
CefString mime_type_;
HeaderMap header_map_;
IMPLEMENT_REFCOUNTING(CefResponseImpl);
IMPLEMENT_LOCKING(CefResponseImpl);
};
#endif // CEF_LIBCEF_COMMON_RESPONSE_IMPL_H_

View File

@@ -0,0 +1,54 @@
// 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 "libcef/common/response_manager.h"
#include "libcef/common/cef_messages.h"
#include "base/logging.h"
CefResponseManager::CefResponseManager()
: next_request_id_(0) {
}
int CefResponseManager::GetNextRequestId() {
DCHECK(CalledOnValidThread());
return ++next_request_id_;
}
int CefResponseManager::RegisterHandler(CefRefPtr<Handler> handler) {
DCHECK(CalledOnValidThread());
int request_id = GetNextRequestId();
handlers_.insert(std::make_pair(request_id, handler));
return request_id;
}
bool CefResponseManager::RunHandler(const Cef_Response_Params& params) {
DCHECK(CalledOnValidThread());
DCHECK_GT(params.request_id, 0);
HandlerMap::iterator it = handlers_.find(params.request_id);
if (it != handlers_.end()) {
it->second->OnResponse(params);
handlers_.erase(it);
return true;
}
return false;
}
void CefResponseManager::RegisterAckHandler(int request_id,
CefRefPtr<AckHandler> handler) {
DCHECK(CalledOnValidThread());
ack_handlers_.insert(std::make_pair(request_id, handler));
}
bool CefResponseManager::RunAckHandler(int request_id) {
DCHECK(CalledOnValidThread());
DCHECK_GT(request_id, 0);
AckHandlerMap::iterator it = ack_handlers_.find(request_id);
if (it != ack_handlers_.end()) {
it->second->OnResponseAck();
ack_handlers_.erase(it);
return true;
}
return false;
}

View File

@@ -0,0 +1,62 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_RESPONSE_MANAGER_H_
#define CEF_LIBCEF_COMMON_RESPONSE_MANAGER_H_
#pragma once
#include <map>
#include "include/cef_base.h"
#include "base/threading/non_thread_safe.h"
struct Cef_Response_Params;
// This class is not thread-safe.
class CefResponseManager : base::NonThreadSafe {
public:
// Used for handling response messages.
class Handler : public virtual CefBase {
public:
virtual void OnResponse(const Cef_Response_Params& params) =0;
};
// Used for handling response ack messages.
class AckHandler : public virtual CefBase {
public:
virtual void OnResponseAck() =0;
};
CefResponseManager();
// Returns the next unique request id.
int GetNextRequestId();
// Register a response handler and return the unique request id.
int RegisterHandler(CefRefPtr<Handler> handler);
// Run the response handler for the specified request id. Returns true if a
// handler was run.
bool RunHandler(const Cef_Response_Params& params);
// Register a response ack handler for the specified request id.
void RegisterAckHandler(int request_id, CefRefPtr<AckHandler> handler);
// Run the response ack handler for the specified request id. Returns true if
// a handler was run.
bool RunAckHandler(int request_id);
private:
// Used for generating unique request ids.
int next_request_id_;
// Map of unique request ids to Handler references.
typedef std::map<int, CefRefPtr<Handler> > HandlerMap;
HandlerMap handlers_;
// Map of unique request ids to AckHandler references.
typedef std::map<int, CefRefPtr<AckHandler> > AckHandlerMap;
AckHandlerMap ack_handlers_;
};
#endif // CEF_LIBCEF_COMMON_RESPONSE_MANAGER_H_

View File

@@ -0,0 +1,58 @@
// Copyright (c) 2009 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 <vector>
#include "include/internal/cef_string_list.h"
#include "base/logging.h"
typedef std::vector<CefString> StringList;
CEF_EXPORT cef_string_list_t cef_string_list_alloc() {
return new StringList;
}
CEF_EXPORT int cef_string_list_size(cef_string_list_t list) {
DCHECK(list);
StringList* impl = reinterpret_cast<StringList*>(list);
return impl->size();
}
CEF_EXPORT int cef_string_list_value(cef_string_list_t list, int index,
cef_string_t* value) {
DCHECK(list);
DCHECK(value);
StringList* impl = reinterpret_cast<StringList*>(list);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return false;
const CefString& str = (*impl)[index];
return cef_string_copy(str.c_str(), str.length(), value);
}
CEF_EXPORT void cef_string_list_append(cef_string_list_t list,
const cef_string_t* value) {
DCHECK(list);
DCHECK(value);
StringList* impl = reinterpret_cast<StringList*>(list);
impl->push_back(CefString(value));
}
CEF_EXPORT void cef_string_list_clear(cef_string_list_t list) {
DCHECK(list);
StringList* impl = reinterpret_cast<StringList*>(list);
impl->clear();
}
CEF_EXPORT void cef_string_list_free(cef_string_list_t list) {
DCHECK(list);
StringList* impl = reinterpret_cast<StringList*>(list);
delete impl;
}
CEF_EXPORT cef_string_list_t cef_string_list_copy(cef_string_list_t list) {
DCHECK(list);
StringList* impl = reinterpret_cast<StringList*>(list);
return new StringList(*impl);
}

View File

@@ -0,0 +1,92 @@
// Copyright (c) 2009 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 <map>
#include "include/internal/cef_string_map.h"
#include "base/logging.h"
typedef std::map<CefString, CefString> StringMap;
CEF_EXPORT cef_string_map_t cef_string_map_alloc() {
return new StringMap;
}
CEF_EXPORT int cef_string_map_size(cef_string_map_t map) {
DCHECK(map);
StringMap* impl = reinterpret_cast<StringMap*>(map);
return impl->size();
}
CEF_EXPORT int cef_string_map_find(cef_string_map_t map,
const cef_string_t* key,
cef_string_t* value) {
DCHECK(map);
DCHECK(value);
StringMap* impl = reinterpret_cast<StringMap*>(map);
StringMap::const_iterator it = impl->find(CefString(key));
if (it == impl->end())
return 0;
const CefString& val = it->second;
return cef_string_set(val.c_str(), val.length(), value, true);
}
CEF_EXPORT int cef_string_map_key(cef_string_map_t map, int index,
cef_string_t* key) {
DCHECK(map);
DCHECK(key);
StringMap* impl = reinterpret_cast<StringMap*>(map);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return 0;
StringMap::const_iterator it = impl->begin();
for (int ct = 0; it != impl->end(); ++it, ct++) {
if (ct == index)
return cef_string_set(it->first.c_str(), it->first.length(), key, true);
}
return 0;
}
CEF_EXPORT int cef_string_map_value(cef_string_map_t map, int index,
cef_string_t* value) {
DCHECK(map);
DCHECK(value);
StringMap* impl = reinterpret_cast<StringMap*>(map);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return 0;
StringMap::const_iterator it = impl->begin();
for (int ct = 0; it != impl->end(); ++it, ct++) {
if (ct == index) {
return cef_string_set(it->second.c_str(), it->second.length(), value,
true);
}
}
return 0;
}
CEF_EXPORT int cef_string_map_append(cef_string_map_t map,
const cef_string_t* key,
const cef_string_t* value) {
DCHECK(map);
StringMap* impl = reinterpret_cast<StringMap*>(map);
impl->insert(std::make_pair(CefString(key), CefString(value)));
return 1;
}
CEF_EXPORT void cef_string_map_clear(cef_string_map_t map) {
DCHECK(map);
StringMap* impl = reinterpret_cast<StringMap*>(map);
impl->clear();
}
CEF_EXPORT void cef_string_map_free(cef_string_map_t map) {
DCHECK(map);
StringMap* impl = reinterpret_cast<StringMap*>(map);
delete impl;
}

View File

@@ -0,0 +1,116 @@
// 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 <map>
#include "include/internal/cef_string_multimap.h"
#include "base/logging.h"
typedef std::multimap<CefString, CefString> StringMultimap;
CEF_EXPORT cef_string_multimap_t cef_string_multimap_alloc() {
return new StringMultimap;
}
CEF_EXPORT int cef_string_multimap_size(cef_string_multimap_t map) {
DCHECK(map);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
return impl->size();
}
CEF_EXPORT int cef_string_multimap_find_count(cef_string_multimap_t map,
const cef_string_t* key) {
DCHECK(map);
DCHECK(key);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
return impl->count(CefString(key));
}
CEF_EXPORT int cef_string_multimap_enumerate(cef_string_multimap_t map,
const cef_string_t* key,
int value_index,
cef_string_t* value) {
DCHECK(map);
DCHECK(key);
DCHECK(value);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
CefString key_str(key);
DCHECK_GE(value_index, 0);
DCHECK_LT(value_index, static_cast<int>(impl->count(key_str)));
if (value_index < 0 || value_index >= static_cast<int>(impl->count(key_str)))
return 0;
std::pair<StringMultimap::iterator, StringMultimap::iterator> range_it =
impl->equal_range(key_str);
int count = value_index;
while (count-- && range_it.first != range_it.second)
range_it.first++;
if (range_it.first == range_it.second)
return 0;
const CefString& val = range_it.first->second;
return cef_string_set(val.c_str(), val.length(), value, true);
}
CEF_EXPORT int cef_string_multimap_key(cef_string_multimap_t map, int index,
cef_string_t* key) {
DCHECK(map);
DCHECK(key);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return 0;
StringMultimap::const_iterator it = impl->begin();
for (int ct = 0; it != impl->end(); ++it, ct++) {
if (ct == index)
return cef_string_set(it->first.c_str(), it->first.length(), key, true);
}
return 0;
}
CEF_EXPORT int cef_string_multimap_value(cef_string_multimap_t map, int index,
cef_string_t* value) {
DCHECK(map);
DCHECK(value);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return 0;
StringMultimap::const_iterator it = impl->begin();
for (int ct = 0; it != impl->end(); ++it, ct++) {
if (ct == index) {
return cef_string_set(it->second.c_str(), it->second.length(), value,
true);
}
}
return 0;
}
CEF_EXPORT int cef_string_multimap_append(cef_string_multimap_t map,
const cef_string_t* key,
const cef_string_t* value) {
DCHECK(map);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
impl->insert(std::make_pair(CefString(key), CefString(value)));
return 1;
}
CEF_EXPORT void cef_string_multimap_clear(cef_string_multimap_t map) {
DCHECK(map);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
impl->clear();
}
CEF_EXPORT void cef_string_multimap_free(cef_string_multimap_t map) {
DCHECK(map);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
delete impl;
}

View File

@@ -0,0 +1,269 @@
// Copyright (c) 2010 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/internal/cef_string_types.h"
#include "base/logging.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
namespace {
void string_wide_dtor(wchar_t* str) {
delete [] str;
}
void string_utf8_dtor(char* str) {
delete [] str;
}
void string_utf16_dtor(char16* str) {
delete [] str;
}
} // namespace
CEF_EXPORT int cef_string_wide_set(const wchar_t* src, size_t src_len,
cef_string_wide_t* output, int copy) {
cef_string_wide_clear(output);
if (copy) {
if (src && src_len > 0) {
output->str = new wchar_t[src_len+1];
if (!output->str)
return 0;
memcpy(output->str, src, src_len * sizeof(wchar_t));
output->str[src_len] = 0;
output->length = src_len;
output->dtor = string_wide_dtor;
}
} else {
output->str = const_cast<wchar_t*>(src);
output->length = src_len;
output->dtor = NULL;
}
return 1;
}
CEF_EXPORT int cef_string_utf8_set(const char* src, size_t src_len,
cef_string_utf8_t* output, int copy) {
cef_string_utf8_clear(output);
if (copy) {
if (src && src_len > 0) {
output->str = new char[src_len+1];
if (!output->str)
return 0;
memcpy(output->str, src, src_len * sizeof(char));
output->str[src_len] = 0;
output->length = src_len;
output->dtor = string_utf8_dtor;
}
} else {
output->str = const_cast<char*>(src);
output->length = src_len;
output->dtor = NULL;
}
return 1;
}
CEF_EXPORT int cef_string_utf16_set(const char16* src, size_t src_len,
cef_string_utf16_t* output, int copy) {
cef_string_utf16_clear(output);
if (copy) {
if (src && src_len > 0) {
output->str = new char16[src_len+1];
if (!output->str)
return 0;
memcpy(output->str, src, src_len * sizeof(char16));
output->str[src_len] = 0;
output->length = src_len;
output->dtor = string_utf16_dtor;
}
} else {
output->str = const_cast<char16*>(src);
output->length = src_len;
output->dtor = NULL;
}
return 1;
}
CEF_EXPORT void cef_string_wide_clear(cef_string_wide_t* str) {
DCHECK(str != NULL);
if (str->dtor && str->str)
str->dtor(str->str);
str->str = NULL;
str->length = 0;
str->dtor = NULL;
}
CEF_EXPORT void cef_string_utf8_clear(cef_string_utf8_t* str) {
DCHECK(str != NULL);
if (str->dtor && str->str)
str->dtor(str->str);
str->str = NULL;
str->length = 0;
str->dtor = NULL;
}
CEF_EXPORT void cef_string_utf16_clear(cef_string_utf16_t* str) {
DCHECK(str != NULL);
if (str->dtor && str->str)
str->dtor(str->str);
str->str = NULL;
str->length = 0;
str->dtor = NULL;
}
CEF_EXPORT int cef_string_wide_cmp(const cef_string_wide_t* str1,
const cef_string_wide_t* str2) {
if (str1->length == 0 && str2->length == 0)
return 0;
int r = wcsncmp(str1->str, str2->str, std::min(str1->length, str2->length));
if (r == 0) {
if (str1->length > str2->length)
return 1;
else if (str1->length < str2->length)
return -1;
}
return r;
}
CEF_EXPORT int cef_string_utf8_cmp(const cef_string_utf8_t* str1,
const cef_string_utf8_t* str2) {
if (str1->length == 0 && str2->length == 0)
return 0;
int r = strncmp(str1->str, str2->str, std::min(str1->length, str2->length));
if (r == 0) {
if (str1->length > str2->length)
return 1;
else if (str1->length < str2->length)
return -1;
}
return r;
}
CEF_EXPORT int cef_string_utf16_cmp(const cef_string_utf16_t* str1,
const cef_string_utf16_t* str2) {
if (str1->length == 0 && str2->length == 0)
return 0;
#if defined(WCHAR_T_IS_UTF32)
int r = base::c16memcmp(str1->str, str2->str, std::min(str1->length,
str2->length));
#else
int r = wcsncmp(str1->str, str2->str, std::min(str1->length, str2->length));
#endif
if (r == 0) {
if (str1->length > str2->length)
return 1;
else if (str1->length < str2->length)
return -1;
}
return r;
}
CEF_EXPORT int cef_string_wide_to_utf8(const wchar_t* src, size_t src_len,
cef_string_utf8_t* output) {
std::string str;
bool ret = WideToUTF8(src, src_len, &str);
if (!cef_string_utf8_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_utf8_to_wide(const char* src, size_t src_len,
cef_string_wide_t* output) {
std::wstring str;
bool ret = UTF8ToWide(src, src_len, &str);
if (!cef_string_wide_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_wide_to_utf16(const wchar_t* src, size_t src_len,
cef_string_utf16_t* output) {
string16 str;
bool ret = WideToUTF16(src, src_len, &str);
if (!cef_string_utf16_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_utf16_to_wide(const char16* src, size_t src_len,
cef_string_wide_t* output) {
std::wstring str;
bool ret = UTF16ToWide(src, src_len, &str);
if (!cef_string_wide_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_utf8_to_utf16(const char* src, size_t src_len,
cef_string_utf16_t* output) {
string16 str;
bool ret = UTF8ToUTF16(src, src_len, &str);
if (!cef_string_utf16_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_utf16_to_utf8(const char16* src, size_t src_len,
cef_string_utf8_t* output) {
std::string str;
bool ret = UTF16ToUTF8(src, src_len, &str);
if (!cef_string_utf8_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_ascii_to_wide(const char* src, size_t src_len,
cef_string_wide_t* output) {
std::wstring str = ASCIIToWide(std::string(src, src_len));
return cef_string_wide_set(str.c_str(), str.length(), output, true);
}
CEF_EXPORT int cef_string_ascii_to_utf16(const char* src, size_t src_len,
cef_string_utf16_t* output) {
string16 str = ASCIIToUTF16(std::string(src, src_len));
return cef_string_utf16_set(str.c_str(), str.length(), output, true);
}
CEF_EXPORT cef_string_userfree_wide_t cef_string_userfree_wide_alloc() {
cef_string_wide_t* s = new cef_string_wide_t;
memset(s, 0, sizeof(cef_string_wide_t));
return s;
}
CEF_EXPORT cef_string_userfree_utf8_t cef_string_userfree_utf8_alloc() {
cef_string_utf8_t* s = new cef_string_utf8_t;
memset(s, 0, sizeof(cef_string_utf8_t));
return s;
}
CEF_EXPORT cef_string_userfree_utf16_t cef_string_userfree_utf16_alloc() {
cef_string_utf16_t* s = new cef_string_utf16_t;
memset(s, 0, sizeof(cef_string_utf16_t));
return s;
}
CEF_EXPORT void cef_string_userfree_wide_free(cef_string_userfree_wide_t str) {
cef_string_wide_clear(str);
delete str;
}
CEF_EXPORT void cef_string_userfree_utf8_free(cef_string_userfree_utf8_t str) {
cef_string_utf8_clear(str);
delete str;
}
CEF_EXPORT void cef_string_userfree_utf16_free(
cef_string_userfree_utf16_t str) {
cef_string_utf16_clear(str);
delete str;
}

106
libcef/common/task_impl.cc Normal file
View File

@@ -0,0 +1,106 @@
// 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/cef_task.h"
#include "libcef/browser/thread_util.h"
#include "libcef/renderer/thread_util.h"
#include "base/bind.h"
using content::BrowserThread;
namespace {
const int kRenderThreadId = -1;
const int kInvalidThreadId = -10;
int GetThreadId(CefThreadId threadId) {
int id = kInvalidThreadId;
switch (threadId) {
case TID_UI:
id = BrowserThread::UI;
break;
case TID_DB:
id = BrowserThread::DB;
break;
case TID_FILE:
id = BrowserThread::FILE;
break;
case TID_FILE_USER_BLOCKING:
id = BrowserThread::FILE_USER_BLOCKING;
break;
case TID_PROCESS_LAUNCHER:
id = BrowserThread::PROCESS_LAUNCHER;
break;
case TID_CACHE:
id = BrowserThread::CACHE;
break;
case TID_IO:
id = BrowserThread::IO;
break;
case TID_RENDERER:
id = kRenderThreadId;
break;
default:
NOTREACHED() << "invalid thread id " << threadId;
return kInvalidThreadId;
};
if (id >= 0) {
// Verify that we're on the browser process.
if (content::GetContentClient()->browser())
return id;
NOTREACHED() << "called on invalid process";
} else if (id == kRenderThreadId) {
// Verify that we're on the renderer process.
if (content::GetContentClient()->renderer())
return id;
NOTREACHED() << "called on invalid process";
}
return kInvalidThreadId;
}
} // namespace
bool CefCurrentlyOn(CefThreadId threadId) {
int id = GetThreadId(threadId);
if (id >= 0) {
// Browser process.
return CEF_CURRENTLY_ON(static_cast<BrowserThread::ID>(id));
} else if (id == kRenderThreadId) {
// Renderer process.
return CEF_CURRENTLY_ON_RT();
}
return false;
}
bool CefPostTask(CefThreadId threadId, CefRefPtr<CefTask> task) {
int id = GetThreadId(threadId);
if (id >= 0) {
// Browser process.
return CEF_POST_TASK(static_cast<BrowserThread::ID>(id),
base::Bind(&CefTask::Execute, task, threadId));
} else if (id == kRenderThreadId) {
// Renderer process.
return CEF_POST_TASK_RT(base::Bind(&CefTask::Execute, task, threadId));
}
return false;
}
bool CefPostDelayedTask(CefThreadId threadId, CefRefPtr<CefTask> task,
int64 delay_ms) {
int id = GetThreadId(threadId);
if (id >= 0) {
// Browser process.
return CEF_POST_DELAYED_TASK(static_cast<BrowserThread::ID>(id),
base::Bind(&CefTask::Execute, task, threadId), delay_ms);
} else if (id == kRenderThreadId) {
// Renderer process.
return CEF_POST_DELAYED_TASK_RT(
base::Bind(&CefTask::Execute, task, threadId), delay_ms);
}
return false;
}

View File

@@ -0,0 +1,73 @@
// 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 "libcef/common/time_util.h"
void cef_time_to_basetime(const cef_time_t& cef_time, base::Time& time) {
base::Time::Exploded exploded;
exploded.year = cef_time.year;
exploded.month = cef_time.month;
#if !defined(OS_MACOSX)
exploded.day_of_week = cef_time.day_of_week;
#endif
exploded.day_of_month = cef_time.day_of_month;
exploded.hour = cef_time.hour;
exploded.minute = cef_time.minute;
exploded.second = cef_time.second;
exploded.millisecond = cef_time.millisecond;
time = base::Time::FromUTCExploded(exploded);
}
void cef_time_from_basetime(const base::Time& time, cef_time_t& cef_time) {
base::Time::Exploded exploded;
time.UTCExplode(&exploded);
cef_time.year = exploded.year;
cef_time.month = exploded.month;
#if !defined(OS_MACOSX)
cef_time.day_of_week = exploded.day_of_week;
#endif
cef_time.day_of_month = exploded.day_of_month;
cef_time.hour = exploded.hour;
cef_time.minute = exploded.minute;
cef_time.second = exploded.second;
cef_time.millisecond = exploded.millisecond;
}
CEF_EXPORT int cef_time_to_timet(const cef_time_t* cef_time, time_t* time) {
if (!cef_time || !time)
return 0;
base::Time base_time;
cef_time_to_basetime(*cef_time, base_time);
*time = base_time.ToTimeT();
return 1;
}
CEF_EXPORT int cef_time_from_timet(time_t time, cef_time_t* cef_time) {
if (!cef_time)
return 0;
base::Time base_time = base::Time::FromTimeT(time);
cef_time_from_basetime(base_time, *cef_time);
return 1;
}
CEF_EXPORT int cef_time_to_doublet(const cef_time_t* cef_time, double* time) {
if (!cef_time || !time)
return 0;
base::Time base_time;
cef_time_to_basetime(*cef_time, base_time);
*time = base_time.ToDoubleT();
return 1;
}
CEF_EXPORT int cef_time_from_doublet(double time, cef_time_t* cef_time) {
if (!cef_time)
return 0;
base::Time base_time = base::Time::FromDoubleT(time);
cef_time_from_basetime(base_time, *cef_time);
return 1;
}

16
libcef/common/time_util.h Normal file
View File

@@ -0,0 +1,16 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_TIME_UTIL_H_
#define CEF_LIBCEF_COMMON_TIME_UTIL_H_
#pragma once
#include "include/internal/cef_time.h"
#include "base/time.h"
// Converts cef_time_t to/from a base::Time object.
void cef_time_to_basetime(const cef_time_t& cef_time, base::Time& time);
void cef_time_from_basetime(const base::Time& time, cef_time_t& cef_time);
#endif // CEF_LIBCEF_COMMON_TIME_UTIL_H_

83
libcef/common/tracker.cc Normal file
View File

@@ -0,0 +1,83 @@
// 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 "libcef/common/tracker.h"
// CefTrackNode implementation.
CefTrackNode::CefTrackNode()
: track_next_(NULL),
track_prev_(NULL) {
}
CefTrackNode::~CefTrackNode() {
}
void CefTrackNode::InsertTrackPrev(CefTrackNode* object) {
if (track_prev_)
track_prev_->SetTrackNext(object);
object->SetTrackNext(this);
object->SetTrackPrev(track_prev_);
track_prev_ = object;
}
void CefTrackNode::InsertTrackNext(CefTrackNode* object) {
if (track_next_)
track_next_->SetTrackPrev(object);
object->SetTrackPrev(this);
object->SetTrackNext(track_next_);
track_next_ = object;
}
void CefTrackNode::RemoveTracking() {
if (track_next_)
track_next_->SetTrackPrev(track_prev_);
if (track_prev_)
track_prev_->SetTrackNext(track_next_);
track_next_ = NULL;
track_prev_ = NULL;
}
// CefTrackManager implementation.
CefTrackManager::CefTrackManager()
: object_count_(0) {
}
CefTrackManager::~CefTrackManager() {
DeleteAll();
}
void CefTrackManager::Add(CefTrackNode* object) {
AutoLock lock_scope(this);
if (!object->IsTracked()) {
tracker_.InsertTrackNext(object);
++object_count_;
}
}
bool CefTrackManager::Delete(CefTrackNode* object) {
AutoLock lock_scope(this);
if (object->IsTracked()) {
object->RemoveTracking();
delete object;
--object_count_;
return true;
}
return false;
}
void CefTrackManager::DeleteAll() {
AutoLock lock_scope(this);
CefTrackNode* next;
do {
next = tracker_.GetTrackNext();
if (next) {
next->RemoveTracking();
delete next;
}
} while (next != NULL);
object_count_ = 0;
}

74
libcef/common/tracker.h Normal file
View File

@@ -0,0 +1,74 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_TRACKER_H_
#define CEF_LIBCEF_COMMON_TRACKER_H_
#pragma once
#include "include/cef_base.h"
// Class extended by objects that must be tracked. After creating a tracked
// object you should add it to the appropriate track manager.
class CefTrackNode {
public:
CefTrackNode();
virtual ~CefTrackNode();
// Returns true if the object is currently being tracked.
inline bool IsTracked() { return (track_prev_ || track_next_); }
private:
inline CefTrackNode* GetTrackPrev() { return track_prev_; }
inline void SetTrackPrev(CefTrackNode* base) { track_prev_ = base; }
inline CefTrackNode* GetTrackNext() { return track_next_; }
inline void SetTrackNext(CefTrackNode* base) { track_next_ = base; }
// Insert a new object into the tracking list before this object.
void InsertTrackPrev(CefTrackNode* object);
// Insert a new object into the tracking list after this object.
void InsertTrackNext(CefTrackNode* object);
// Remove this object from the tracking list.
void RemoveTracking();
private:
CefTrackNode* track_next_;
CefTrackNode* track_prev_;
friend class CefTrackManager;
};
// Class used to manage tracked objects. A single instance of this class
// should be created for each intended usage. Any objects that have not been
// removed by explicit calls to the Destroy() method will be removed when the
// manager object is destroyed. A manager object can be created as either a
// member variable of another class or by using lazy initialization:
// base::LazyInstance<CefTrackManager> g_singleton = LAZY_INSTANCE_INITIALIZER;
class CefTrackManager : public CefBase {
public:
CefTrackManager();
virtual ~CefTrackManager();
// Add an object to be tracked by this manager.
void Add(CefTrackNode* object);
// Delete an object tracked by this manager.
bool Delete(CefTrackNode* object);
// Delete all objects tracked by this manager.
void DeleteAll();
// Returns the number of objects currently being tracked.
inline int GetCount() { return object_count_; }
private:
CefTrackNode tracker_;
int object_count_;
IMPLEMENT_REFCOUNTING(CefTrackManager);
IMPLEMENT_LOCKING(CefTrackManager);
};
#endif // CEF_LIBCEF_COMMON_TRACKER_H_

68
libcef/common/url_impl.cc Normal file
View File

@@ -0,0 +1,68 @@
// 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 <sstream>
#include "include/cef_url.h"
#include "googleurl/src/gurl.h"
bool CefParseURL(const CefString& url,
CefURLParts& parts) {
GURL gurl(url.ToString());
if (!gurl.is_valid())
return false;
CefString(&parts.spec).FromString(gurl.spec());
CefString(&parts.scheme).FromString(gurl.scheme());
CefString(&parts.username).FromString(gurl.username());
CefString(&parts.password).FromString(gurl.password());
CefString(&parts.host).FromString(gurl.host());
CefString(&parts.port).FromString(gurl.port());
CefString(&parts.path).FromString(gurl.path());
CefString(&parts.query).FromString(gurl.query());
return true;
}
bool CefCreateURL(const CefURLParts& parts,
CefString& url) {
std::string spec = CefString(parts.spec.str, parts.spec.length, false);
std::string scheme = CefString(parts.scheme.str, parts.scheme.length, false);
std::string username =
CefString(parts.username.str, parts.username.length, false);
std::string password =
CefString(parts.password.str, parts.password.length, false);
std::string host = CefString(parts.host.str, parts.host.length, false);
std::string port = CefString(parts.port.str, parts.port.length, false);
std::string path = CefString(parts.path.str, parts.path.length, false);
std::string query = CefString(parts.query.str, parts.query.length, false);
GURL gurl;
if (!spec.empty()) {
gurl = GURL(spec);
} else if (!scheme.empty() && !host.empty()) {
std::stringstream ss;
ss << scheme << "://";
if (!username.empty()) {
ss << username;
if (!password.empty())
ss << ":" << password;
ss << "@";
}
ss << host;
if (!port.empty())
ss << ":" << port;
if (!path.empty())
ss << path;
if (!query.empty())
ss << "?" << query;
gurl = GURL(ss.str());
}
if (gurl.is_valid()) {
url = gurl.spec();
return true;
}
return false;
}

201
libcef/common/value_base.cc Normal file
View File

@@ -0,0 +1,201 @@
// 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 "libcef/common/value_base.h"
CefValueController::CefValueController()
: owner_value_(NULL),
owner_object_(NULL) {
}
CefValueController::~CefValueController() {
// Everything should already have been removed.
DCHECK(!owner_value_ && !owner_object_);
DCHECK(reference_map_.empty());
DCHECK(dependency_map_.empty());
}
void CefValueController::SetOwner(void* value, Object* object) {
DCHECK(value && object);
// Controller should already be locked.
DCHECK(locked());
// Owner should only be set once.
DCHECK(!owner_value_ && !owner_object_);
owner_value_ = value;
owner_object_ = object;
}
void CefValueController::AddReference(void* value, Object* object) {
DCHECK(value && object);
// Controller should already be locked.
DCHECK(locked());
// Controller should currently have an owner.
DCHECK(owner_value_);
// Values should only be added once.
DCHECK(reference_map_.find(value) == reference_map_.end());
DCHECK(value != owner_value_);
reference_map_.insert(std::make_pair(value, object));
}
void CefValueController::Remove(void* value, bool notify_object) {
DCHECK(value);
// Controller should already be locked.
DCHECK(locked());
// Controller should currently have an owner.
DCHECK(owner_value_);
if (value == owner_value_) {
// Should never notify when removing the owner object.
DCHECK(!notify_object);
owner_value_ = NULL;
owner_object_ = NULL;
// Remove all references.
if (reference_map_.size() > 0) {
ReferenceMap::iterator it = reference_map_.begin();
for (; it != reference_map_.end(); ++it)
it->second->OnControlRemoved();
reference_map_.clear();
}
// Remove all dependencies.
dependency_map_.clear();
} else {
ReferenceMap::iterator it = reference_map_.find(value);
if (it != reference_map_.end()) {
// Remove the reference.
if (notify_object)
it->second->OnControlRemoved();
reference_map_.erase(it);
}
}
}
CefValueController::Object* CefValueController::Get(void* value) {
DCHECK(value);
// Controller should already be locked.
DCHECK(locked());
if (value == owner_value_) {
return owner_object_;
} else {
ReferenceMap::iterator it = reference_map_.find(value);
if (it != reference_map_.end())
return it->second;
return NULL;
}
}
void CefValueController::AddDependency(void* parent, void* child) {
DCHECK(parent && child && parent != child);
// Controller should already be locked.
DCHECK(locked());
DependencyMap::iterator it = dependency_map_.find(parent);
if (it == dependency_map_.end()) {
// New set.
DependencySet set;
set.insert(child);
dependency_map_.insert(std::make_pair(parent, set));
} else if (it->second.find(child) == it->second.end()) {
// Update existing set.
it->second.insert(child);
}
}
void CefValueController::RemoveDependencies(void* value) {
DCHECK(value);
// Controller should already be locked.
DCHECK(locked());
if (dependency_map_.empty())
return;
DependencyMap::iterator it_dependency = dependency_map_.find(value);
if (it_dependency == dependency_map_.end())
return;
// Start with the set of dependencies for the current value.
DependencySet remove_set = it_dependency->second;
dependency_map_.erase(it_dependency);
DependencySet::iterator it_value;
ReferenceMap::iterator it_reference;
while (remove_set.size() > 0) {
it_value = remove_set.begin();
value = *it_value;
remove_set.erase(it_value);
// Does the current value have dependencies?
it_dependency = dependency_map_.find(value);
if (it_dependency != dependency_map_.end()) {
// Append the dependency set to the remove set.
remove_set.insert(it_dependency->second.begin(),
it_dependency->second.end());
dependency_map_.erase(it_dependency);
}
// Does the current value have a reference?
it_reference = reference_map_.find(value);
if (it_reference != reference_map_.end()) {
// Remove the reference.
it_reference->second->OnControlRemoved();
reference_map_.erase(it_reference);
}
}
}
void CefValueController::TakeFrom(CefValueController* other) {
DCHECK(other);
// Both controllers should already be locked.
DCHECK(locked());
DCHECK(other->locked());
if (!other->reference_map_.empty()) {
// Transfer references from the other to this.
ReferenceMap::iterator it = other->reference_map_.begin();
for (; it != other->reference_map_.end(); ++it) {
// References should only be added once.
DCHECK(reference_map_.find(it->first) == reference_map_.end());
reference_map_.insert(std::make_pair(it->first, it->second));
}
other->reference_map_.empty();
}
if (!other->dependency_map_.empty()) {
// Transfer dependencies from the other to this.
DependencyMap::iterator it_other = other->dependency_map_.begin();
for (; it_other != other->dependency_map_.end(); ++it_other) {
DependencyMap::iterator it_me = dependency_map_.find(it_other->first);
if (it_me == dependency_map_.end()) {
// All children are new.
dependency_map_.insert(
std::make_pair(it_other->first, it_other->second));
} else {
// Evaluate each child.
DependencySet::iterator it_other_set = it_other->second.begin();
for (; it_other_set != it_other->second.end(); ++it_other_set) {
if (it_me->second.find(*it_other_set) == it_me->second.end())
it_me->second.insert(*it_other_set);
}
}
}
}
}

411
libcef/common/value_base.h Normal file
View File

@@ -0,0 +1,411 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_VALUE_BASE_H_
#define CEF_LIBCEF_COMMON_VALUE_BASE_H_
#pragma once
#include <map>
#include <set>
#include "include/cef_base.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
// Controller implementation base class.
class CefValueController
: public base::RefCountedThreadSafe<CefValueController> {
public:
// Implemented by a class controlled using the access controller.
class Object {
public:
virtual ~Object() {}
// Called when the value has been removed.
virtual void OnControlRemoved() =0;
};
// Encapsulates context locking and verification logic.
class AutoLock {
public:
explicit AutoLock(CefValueController* impl)
: impl_(impl),
verified_(impl && impl->VerifyThread()) {
DCHECK(impl);
if (verified_)
impl_->lock();
}
virtual ~AutoLock() {
if (verified_)
impl_->unlock();
}
inline bool verified() { return verified_; }
private:
scoped_refptr<CefValueController> impl_;
bool verified_;
DISALLOW_COPY_AND_ASSIGN(AutoLock);
};
CefValueController();
virtual ~CefValueController();
// Returns true if this controller is thread safe.
virtual bool thread_safe() =0;
// Returns true if the current thread is allowed to access this controller.
virtual bool on_correct_thread() =0;
// Lock the controller.
virtual void lock() =0;
// Unlock the controller.
virtual void unlock() =0;
// Returns true if the controller is locked on the current thread.
virtual bool locked() =0;
// Verify that the current thread is correct for accessing the controller.
inline bool VerifyThread() {
if (!thread_safe() && !on_correct_thread()) {
// This object should only be accessed from the thread that created it.
NOTREACHED() << "object accessed from incorrect thread.";
return false;
}
return true;
}
// The controller must already be locked before calling the below methods.
// Set the owner for this controller.
void SetOwner(void* value, Object* object);
// Add a reference value and associated object.
void AddReference(void* value, Object* object);
// Remove the value. If |notify_object| is true the removed object will be
// notified. If |value| is the owner all reference objects will be removed.
// If |value| has dependencies those objects will also be removed.
void Remove(void* value, bool notify_object);
// Returns the object for the specified value.
Object* Get(void* value);
// Add a dependency between |parent| and |child|.
void AddDependency(void* parent, void* child);
// Recursively removes any dependent values.
void RemoveDependencies(void* value);
// Takes ownership of all references and dependencies currently controlled by
// |other|. The |other| controller must already be locked.
void TakeFrom(CefValueController* other);
private:
// Owner object.
void* owner_value_;
Object* owner_object_;
// Map of reference objects.
typedef std::map<void*, Object*> ReferenceMap;
ReferenceMap reference_map_;
// Map of dependency objects.
typedef std::set<void*> DependencySet;
typedef std::map<void*, DependencySet> DependencyMap;
DependencyMap dependency_map_;
DISALLOW_COPY_AND_ASSIGN(CefValueController);
};
// Thread-safe access control implementation.
class CefValueControllerThreadSafe : public CefValueController {
public:
explicit CefValueControllerThreadSafe()
: locked_thread_id_(0) {}
// CefValueController methods.
virtual bool thread_safe() OVERRIDE { return true; }
virtual bool on_correct_thread() OVERRIDE { return true; }
virtual void lock() OVERRIDE {
lock_.Acquire();
locked_thread_id_ = base::PlatformThread::CurrentId();
}
virtual void unlock() OVERRIDE {
locked_thread_id_ = 0;
lock_.Release();
}
virtual bool locked() OVERRIDE {
return (locked_thread_id_ == base::PlatformThread::CurrentId());
}
private:
base::Lock lock_;
base::PlatformThreadId locked_thread_id_;
DISALLOW_COPY_AND_ASSIGN(CefValueControllerThreadSafe);
};
// Non-thread-safe access control implementation.
class CefValueControllerNonThreadSafe : public CefValueController {
public:
explicit CefValueControllerNonThreadSafe()
: thread_id_(base::PlatformThread::CurrentId()) {}
// CefValueController methods.
virtual bool thread_safe() OVERRIDE { return false; }
virtual bool on_correct_thread() OVERRIDE {
return (thread_id_ == base::PlatformThread::CurrentId());
}
virtual void lock() OVERRIDE {}
virtual void unlock() OVERRIDE {}
virtual bool locked() OVERRIDE { return on_correct_thread(); }
private:
base::PlatformThreadId thread_id_;
DISALLOW_COPY_AND_ASSIGN(CefValueControllerNonThreadSafe);
};
// Helper macros for verifying context.
#define CEF_VALUE_VERIFY_RETURN_VOID_EX(object, modify) \
if (!VerifyAttached()) \
return; \
AutoLock auto_lock(object, modify); \
if (!auto_lock.verified()) \
return;
#define CEF_VALUE_VERIFY_RETURN_VOID(modify) \
CEF_VALUE_VERIFY_RETURN_VOID_EX(this, modify)
#define CEF_VALUE_VERIFY_RETURN_EX(object, modify, error_val) \
if (!VerifyAttached()) \
return error_val; \
AutoLock auto_lock(object, modify); \
if (!auto_lock.verified()) \
return error_val;
#define CEF_VALUE_VERIFY_RETURN(modify, error_val) \
CEF_VALUE_VERIFY_RETURN_EX(this, modify, error_val)
// Template class for implementing CEF wrappers of other types.
template<class CefType, class ValueType>
class CefValueBase : public CefType, public CefValueController::Object {
public:
// Specifies how the value will be used.
enum ValueMode {
// A reference to a value managed by an existing controller. These values
// can be safely detached but ownership should not be transferred (make a
// copy of the value instead).
kReference,
// The value has its own controller and will be deleted on destruction.
// These values can only be detached to another controller otherwise any
// references will not be properly managed.
kOwnerWillDelete,
// The value has its own controller and will not be deleted on destruction.
// This should only be used for global values or scope-limited values that
// will be explicitly detached.
kOwnerNoDelete,
};
// Create a new object.
// If |read_only| is true mutable access will not be allowed.
// If |parent_value| is non-NULL and the value mode is kReference a dependency
// will be added.
CefValueBase(ValueType* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller)
: value_(value),
value_mode_(value_mode),
read_only_(read_only),
controller_(controller) {
DCHECK(value_);
// Specifying a parent value for a non-reference doesn't make sense.
DCHECK(!(!reference() && parent_value));
if (!reference() && !controller_) {
// For owned values default to using a new multi-threaded controller.
controller_ = new CefValueControllerThreadSafe();
CefValueController::AutoLock lock_scope(controller_);
if (lock_scope.verified())
controller_->SetOwner(value_, this);
}
// A controller is required.
DCHECK(controller_);
if (reference()) {
// Register the reference with the controller.
controller_->AddReference(value_, this);
// Add a dependency on the parent value.
if (parent_value)
controller_->AddDependency(parent_value, value_);
}
}
virtual ~CefValueBase() {
if (controller_ && value_)
Delete();
}
// True if the underlying value is referenced instead of owned.
inline bool reference() const { return (value_mode_ == kReference); }
// True if the underlying value will be deleted.
inline bool will_delete() const { return (value_mode_ == kOwnerWillDelete); }
// True if access to the underlying value is read-only.
inline bool read_only() const { return read_only_; }
// True if the underlying value has been detached.
inline bool detached() { return (controller_ == NULL); }
// Returns the controller.
inline CefValueController* controller() { return controller_; }
// Deletes the underlying value.
void Delete() {
CEF_VALUE_VERIFY_RETURN_VOID(false);
// Remove the object from the controller. If this is the owner object any
// references will be detached.
controller()->Remove(value_, false);
if (will_delete()) {
// Remove any dependencies.
controller()->RemoveDependencies(value_);
// Delete the value.
DeleteValue(value_);
}
controller_ = NULL;
value_ = NULL;
}
// Detaches the underlying value and returns a pointer to it. If this is an
// owner and a |new_controller| value is specified any existing references
// will be passed to the new controller.
ValueType* Detach(CefValueController* new_controller) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
// A |new_controller| value is required for mode kOwnerWillDelete.
DCHECK(!will_delete() || new_controller);
if (new_controller && !reference()) {
// Pass any existing references and dependencies to the new controller.
// They will be removed from this controller.
new_controller->TakeFrom(controller());
}
// Remove the object from the controller. If this is the owner object any
// references will be detached.
controller()->Remove(value_, false);
controller_ = NULL;
// Return the old value.
ValueType* old_val = value_;
value_ = NULL;
return old_val;
}
// Verify that the value is attached.
inline bool VerifyAttached() {
if (detached()) {
// This object should not be accessed after being detached.
NOTREACHED() << "object accessed after being detached.";
return false;
}
return true;
}
protected:
// CefValueController::Object methods.
virtual void OnControlRemoved() {
DCHECK(controller()->locked());
// Only references should be removed in this manner.
DCHECK(reference());
controller_ = NULL;
value_ = NULL;
}
// Override to customize value deletion.
virtual void DeleteValue(ValueType* value) { delete value; }
// Returns a mutable reference to the value.
inline ValueType* mutable_value() {
DCHECK(value_);
DCHECK(!read_only_);
DCHECK(controller()->locked());
return value_;
}
// Returns a const reference to the value.
inline const ValueType& const_value() {
DCHECK(value_);
DCHECK(controller()->locked());
return *value_;
}
// Verify that the value can be accessed.
inline bool VerifyAccess(bool modify) {
// The controller must already be locked.
DCHECK(controller()->locked());
if (read_only() && modify) {
// This object cannot be modified.
NOTREACHED() << "mutation attempted on read-only object.";
return false;
}
return true;
}
// Encapsulates value locking and verification logic.
class AutoLock {
public:
explicit AutoLock(CefValueBase* impl, bool modify)
: auto_lock_(impl->controller()),
verified_(auto_lock_.verified() && impl->VerifyAccess(modify)) {
}
virtual ~AutoLock() {}
inline bool verified() { return verified_; }
private:
CefValueController::AutoLock auto_lock_;
bool verified_;
DISALLOW_COPY_AND_ASSIGN(AutoLock);
};
private:
ValueType* value_;
ValueMode value_mode_;
bool read_only_;
scoped_refptr<CefValueController> controller_;
IMPLEMENT_REFCOUNTING(CefValueBase);
DISALLOW_COPY_AND_ASSIGN(CefValueBase);
};
#endif // CEF_LIBCEF_COMMON_VALUE_BASE_H_

View File

@@ -0,0 +1,812 @@
// 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 "libcef/common/values_impl.h"
#include <algorithm>
#include <vector>
// CefBinaryValueImpl implementation.
CefRefPtr<CefBinaryValue> CefBinaryValue::Create(const void* data,
size_t data_size) {
DCHECK(data);
DCHECK_GT(data_size, (size_t)0);
if (!data || data_size == 0)
return NULL;
return new CefBinaryValueImpl(static_cast<char*>(const_cast<void*>(data)),
data_size, true);
}
// static
CefRefPtr<CefBinaryValue> CefBinaryValueImpl::GetOrCreateRef(
base::BinaryValue* value,
void* parent_value,
CefValueController* controller) {
DCHECK(value);
DCHECK(parent_value);
DCHECK(controller);
CefValueController::Object* object = controller->Get(value);
if (object)
return static_cast<CefBinaryValueImpl*>(object);
return new CefBinaryValueImpl(value, parent_value,
CefBinaryValueImpl::kReference, controller);
}
base::BinaryValue* CefBinaryValueImpl::CopyValue() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return const_value().DeepCopy();
}
base::BinaryValue* CefBinaryValueImpl::CopyOrDetachValue(
CefValueController* new_controller) {
base::BinaryValue* new_value;
if (!will_delete()) {
// Copy the value.
new_value = CopyValue();
} else {
// Take ownership of the value.
new_value = Detach(new_controller);
}
DCHECK(new_value);
return new_value;
}
bool CefBinaryValueImpl::IsValid() {
return !detached();
}
bool CefBinaryValueImpl::IsOwned() {
return !will_delete();
}
CefRefPtr<CefBinaryValue> CefBinaryValueImpl::Copy() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return new CefBinaryValueImpl(const_value().DeepCopy(), NULL,
CefBinaryValueImpl::kOwnerWillDelete, NULL);
}
size_t CefBinaryValueImpl::GetSize() {
CEF_VALUE_VERIFY_RETURN(false, 0);
return const_value().GetSize();
}
size_t CefBinaryValueImpl::GetData(void* buffer,
size_t buffer_size,
size_t data_offset) {
DCHECK(buffer);
DCHECK_GT(buffer_size, (size_t)0);
if (!buffer || buffer_size == 0)
return 0;
CEF_VALUE_VERIFY_RETURN(false, 0);
size_t size = const_value().GetSize();
DCHECK_LT(data_offset, size);
if (data_offset >= size)
return 0;
size = std::min(buffer_size, size-data_offset);
const char* data = const_value().GetBuffer();
memcpy(buffer, data+data_offset, size);
return size;
}
CefBinaryValueImpl::CefBinaryValueImpl(base::BinaryValue* value,
void* parent_value,
ValueMode value_mode,
CefValueController* controller)
: CefValueBase<CefBinaryValue, base::BinaryValue>(
value, parent_value, value_mode, true, controller) {
}
CefBinaryValueImpl::CefBinaryValueImpl(char* data,
size_t data_size,
bool copy)
: CefValueBase<CefBinaryValue, base::BinaryValue>(
copy ? base::BinaryValue::CreateWithCopiedBuffer(data, data_size) :
base::BinaryValue::Create(data, data_size),
NULL, kOwnerWillDelete, true, NULL) {
}
// CefDictionaryValueImpl implementation.
// static
CefRefPtr<CefDictionaryValue> CefDictionaryValue::Create() {
return new CefDictionaryValueImpl(new base::DictionaryValue(),
NULL, CefDictionaryValueImpl::kOwnerWillDelete, false, NULL);
}
// static
CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::GetOrCreateRef(
base::DictionaryValue* value,
void* parent_value,
bool read_only,
CefValueController* controller) {
CefValueController::Object* object = controller->Get(value);
if (object)
return static_cast<CefDictionaryValueImpl*>(object);
return new CefDictionaryValueImpl(value, parent_value,
CefDictionaryValueImpl::kReference, read_only, controller);
}
base::DictionaryValue* CefDictionaryValueImpl::CopyValue() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return const_value().DeepCopy();
}
base::DictionaryValue* CefDictionaryValueImpl::CopyOrDetachValue(
CefValueController* new_controller) {
base::DictionaryValue* new_value;
if (!will_delete()) {
// Copy the value.
new_value = CopyValue();
} else {
// Take ownership of the value.
new_value = Detach(new_controller);
}
DCHECK(new_value);
return new_value;
}
bool CefDictionaryValueImpl::IsValid() {
return !detached();
}
bool CefDictionaryValueImpl::IsOwned() {
return !will_delete();
}
bool CefDictionaryValueImpl::IsReadOnly() {
return read_only();
}
CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::Copy(
bool exclude_empty_children) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::DictionaryValue* value;
if (exclude_empty_children) {
value = const_cast<base::DictionaryValue&>(
const_value()).DeepCopyWithoutEmptyChildren();
} else {
value = const_value().DeepCopy();
}
return new CefDictionaryValueImpl(value, NULL,
CefDictionaryValueImpl::kOwnerWillDelete, false, NULL);
}
size_t CefDictionaryValueImpl::GetSize() {
CEF_VALUE_VERIFY_RETURN(false, 0);
return const_value().size();
}
bool CefDictionaryValueImpl::Clear() {
CEF_VALUE_VERIFY_RETURN(true, false);
// Detach any dependent values.
controller()->RemoveDependencies(mutable_value());
mutable_value()->Clear();
return true;
}
bool CefDictionaryValueImpl::HasKey(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, 0);
return const_value().HasKey(key);
}
bool CefDictionaryValueImpl::GetKeys(KeyList& keys) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::DictionaryValue::key_iterator it = const_value().begin_keys();
for (; it != const_value().end_keys(); ++it)
keys.push_back(*it);
return true;
}
bool CefDictionaryValueImpl::Remove(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(true, false);
return RemoveInternal(key);
}
CefValueType CefDictionaryValueImpl::GetType(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, VTYPE_INVALID);
base::Value* out_value = NULL;
if (const_value().GetWithoutPathExpansion(key, &out_value)) {
switch (out_value->GetType()) {
case base::Value::TYPE_NULL:
return VTYPE_NULL;
case base::Value::TYPE_BOOLEAN:
return VTYPE_BOOL;
case base::Value::TYPE_INTEGER:
return VTYPE_INT;
case base::Value::TYPE_DOUBLE:
return VTYPE_DOUBLE;
case base::Value::TYPE_STRING:
return VTYPE_STRING;
case base::Value::TYPE_BINARY:
return VTYPE_BINARY;
case base::Value::TYPE_DICTIONARY:
return VTYPE_DICTIONARY;
case base::Value::TYPE_LIST:
return VTYPE_LIST;
}
}
return VTYPE_INVALID;
}
bool CefDictionaryValueImpl::GetBool(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, false);
base::Value* out_value = NULL;
bool ret_value = false;
if (const_value().GetWithoutPathExpansion(key, &out_value))
out_value->GetAsBoolean(&ret_value);
return ret_value;
}
int CefDictionaryValueImpl::GetInt(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::Value* out_value = NULL;
int ret_value = 0;
if (const_value().GetWithoutPathExpansion(key, &out_value))
out_value->GetAsInteger(&ret_value);
return ret_value;
}
double CefDictionaryValueImpl::GetDouble(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::Value* out_value = NULL;
double ret_value = 0;
if (const_value().GetWithoutPathExpansion(key, &out_value))
out_value->GetAsDouble(&ret_value);
return ret_value;
}
CefString CefDictionaryValueImpl::GetString(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, CefString());
base::Value* out_value = NULL;
string16 ret_value;
if (const_value().GetWithoutPathExpansion(key, &out_value))
out_value->GetAsString(&ret_value);
return ret_value;
}
CefRefPtr<CefBinaryValue> CefDictionaryValueImpl::GetBinary(
const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().GetWithoutPathExpansion(key, &out_value) &&
out_value->IsType(base::Value::TYPE_BINARY)) {
base::BinaryValue* binary_value =
static_cast<base::BinaryValue*>(out_value);
return CefBinaryValueImpl::GetOrCreateRef(binary_value,
const_cast<base::DictionaryValue*>(&const_value()), controller());
}
return NULL;
}
CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::GetDictionary(
const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().GetWithoutPathExpansion(key, &out_value) &&
out_value->IsType(base::Value::TYPE_DICTIONARY)) {
base::DictionaryValue* dict_value =
static_cast<base::DictionaryValue*>(out_value);
return CefDictionaryValueImpl::GetOrCreateRef(
dict_value,
const_cast<base::DictionaryValue*>(&const_value()),
read_only(),
controller());
}
return NULL;
}
CefRefPtr<CefListValue> CefDictionaryValueImpl::GetList(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().GetWithoutPathExpansion(key, &out_value) &&
out_value->IsType(base::Value::TYPE_LIST)) {
base::ListValue* list_value = static_cast<base::ListValue*>(out_value);
return CefListValueImpl::GetOrCreateRef(
list_value,
const_cast<base::DictionaryValue*>(&const_value()),
read_only(),
controller());
}
return NULL;
}
bool CefDictionaryValueImpl::SetNull(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key, base::Value::CreateNullValue());
return true;
}
bool CefDictionaryValueImpl::SetBool(const CefString& key, bool value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key,
base::Value::CreateBooleanValue(value));
return true;
}
bool CefDictionaryValueImpl::SetInt(const CefString& key, int value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key,
base::Value::CreateIntegerValue(value));
return true;
}
bool CefDictionaryValueImpl::SetDouble(const CefString& key, double value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key,
base::Value::CreateDoubleValue(value));
return true;
}
bool CefDictionaryValueImpl::SetString(const CefString& key,
const CefString& value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key,
base::Value::CreateStringValue(value.ToString16()));
return true;
}
bool CefDictionaryValueImpl::SetBinary(const CefString& key,
CefRefPtr<CefBinaryValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
CefBinaryValueImpl* impl = static_cast<CefBinaryValueImpl*>(value.get());
DCHECK(impl);
mutable_value()->SetWithoutPathExpansion(key,
impl->CopyOrDetachValue(controller()));
return true;
}
bool CefDictionaryValueImpl::SetDictionary(
const CefString& key, CefRefPtr<CefDictionaryValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
CefDictionaryValueImpl* impl =
static_cast<CefDictionaryValueImpl*>(value.get());
DCHECK(impl);
mutable_value()->SetWithoutPathExpansion(key,
impl->CopyOrDetachValue(controller()));
return true;
}
bool CefDictionaryValueImpl::SetList(const CefString& key,
CefRefPtr<CefListValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
CefListValueImpl* impl = static_cast<CefListValueImpl*>(value.get());
DCHECK(impl);
mutable_value()->SetWithoutPathExpansion(key,
impl->CopyOrDetachValue(controller()));
return true;
}
bool CefDictionaryValueImpl::RemoveInternal(const CefString& key) {
base::Value* out_value = NULL;
if (!mutable_value()->RemoveWithoutPathExpansion(key, &out_value))
return false;
// Remove the value.
controller()->Remove(out_value, true);
// Only list and dictionary types may have dependencies.
if (out_value->IsType(base::Value::TYPE_LIST) ||
out_value->IsType(base::Value::TYPE_DICTIONARY)) {
controller()->RemoveDependencies(out_value);
}
delete out_value;
return true;
}
CefDictionaryValueImpl::CefDictionaryValueImpl(
base::DictionaryValue* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller)
: CefValueBase<CefDictionaryValue, base::DictionaryValue>(
value, parent_value, value_mode, read_only, controller) {
}
// CefListValueImpl implementation.
// static
CefRefPtr<CefListValue> CefListValue::Create() {
return new CefListValueImpl(new base::ListValue(),
NULL, CefListValueImpl::kOwnerWillDelete, false, NULL);
}
// static
CefRefPtr<CefListValue> CefListValueImpl::GetOrCreateRef(
base::ListValue* value,
void* parent_value,
bool read_only,
CefValueController* controller) {
CefValueController::Object* object = controller->Get(value);
if (object)
return static_cast<CefListValueImpl*>(object);
return new CefListValueImpl(value, parent_value,
CefListValueImpl::kReference, read_only, controller);
}
base::ListValue* CefListValueImpl::CopyValue() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return const_value().DeepCopy();
}
base::ListValue* CefListValueImpl::CopyOrDetachValue(
CefValueController* new_controller) {
base::ListValue* new_value;
if (!will_delete()) {
// Copy the value.
new_value = CopyValue();
} else {
// Take ownership of the value.
new_value = Detach(new_controller);
}
DCHECK(new_value);
return new_value;
}
bool CefListValueImpl::IsValid() {
return !detached();
}
bool CefListValueImpl::IsOwned() {
return !will_delete();
}
bool CefListValueImpl::IsReadOnly() {
return read_only();
}
CefRefPtr<CefListValue> CefListValueImpl::Copy() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return new CefListValueImpl(const_value().DeepCopy(), NULL,
CefListValueImpl::kOwnerWillDelete, false, NULL);
}
bool CefListValueImpl::SetSize(size_t size) {
CEF_VALUE_VERIFY_RETURN(true, false);
size_t current_size = const_value().GetSize();
if (size < current_size) {
// Clean up any values above the requested size.
for (size_t i = current_size-1; i >= size; --i)
RemoveInternal(i);
} else if (size > 0) {
// Expand the list size.
mutable_value()->Set(size-1, base::Value::CreateNullValue());
}
return true;
}
size_t CefListValueImpl::GetSize() {
CEF_VALUE_VERIFY_RETURN(false, 0);
return const_value().GetSize();
}
bool CefListValueImpl::Clear() {
CEF_VALUE_VERIFY_RETURN(true, false);
// Detach any dependent values.
controller()->RemoveDependencies(mutable_value());
mutable_value()->Clear();
return true;
}
bool CefListValueImpl::Remove(int index) {
CEF_VALUE_VERIFY_RETURN(true, false);
return RemoveInternal(index);
}
CefValueType CefListValueImpl::GetType(int index) {
CEF_VALUE_VERIFY_RETURN(false, VTYPE_INVALID);
base::Value* out_value = NULL;
if (const_value().Get(index, &out_value)) {
switch (out_value->GetType()) {
case base::Value::TYPE_NULL:
return VTYPE_NULL;
case base::Value::TYPE_BOOLEAN:
return VTYPE_BOOL;
case base::Value::TYPE_INTEGER:
return VTYPE_INT;
case base::Value::TYPE_DOUBLE:
return VTYPE_DOUBLE;
case base::Value::TYPE_STRING:
return VTYPE_STRING;
case base::Value::TYPE_BINARY:
return VTYPE_BINARY;
case base::Value::TYPE_DICTIONARY:
return VTYPE_DICTIONARY;
case base::Value::TYPE_LIST:
return VTYPE_LIST;
}
}
return VTYPE_INVALID;
}
bool CefListValueImpl::GetBool(int index) {
CEF_VALUE_VERIFY_RETURN(false, false);
base::Value* out_value = NULL;
bool ret_value = false;
if (const_value().Get(index, &out_value))
out_value->GetAsBoolean(&ret_value);
return ret_value;
}
int CefListValueImpl::GetInt(int index) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::Value* out_value = NULL;
int ret_value = 0;
if (const_value().Get(index, &out_value))
out_value->GetAsInteger(&ret_value);
return ret_value;
}
double CefListValueImpl::GetDouble(int index) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::Value* out_value = NULL;
double ret_value = 0;
if (const_value().Get(index, &out_value))
out_value->GetAsDouble(&ret_value);
return ret_value;
}
CefString CefListValueImpl::GetString(int index) {
CEF_VALUE_VERIFY_RETURN(false, CefString());
base::Value* out_value = NULL;
string16 ret_value;
if (const_value().Get(index, &out_value))
out_value->GetAsString(&ret_value);
return ret_value;
}
CefRefPtr<CefBinaryValue> CefListValueImpl::GetBinary(int index) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().Get(index, &out_value) &&
out_value->IsType(base::Value::TYPE_BINARY)) {
base::BinaryValue* binary_value =
static_cast<base::BinaryValue*>(out_value);
return CefBinaryValueImpl::GetOrCreateRef(binary_value,
const_cast<base::ListValue*>(&const_value()), controller());
}
return NULL;
}
CefRefPtr<CefDictionaryValue> CefListValueImpl::GetDictionary(int index) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().Get(index, &out_value) &&
out_value->IsType(base::Value::TYPE_DICTIONARY)) {
base::DictionaryValue* dict_value =
static_cast<base::DictionaryValue*>(out_value);
return CefDictionaryValueImpl::GetOrCreateRef(
dict_value,
const_cast<base::ListValue*>(&const_value()),
read_only(),
controller());
}
return NULL;
}
CefRefPtr<CefListValue> CefListValueImpl::GetList(int index) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().Get(index, &out_value) &&
out_value->IsType(base::Value::TYPE_LIST)) {
base::ListValue* list_value = static_cast<base::ListValue*>(out_value);
return CefListValueImpl::GetOrCreateRef(
list_value,
const_cast<base::ListValue*>(&const_value()),
read_only(),
controller());
}
return NULL;
}
bool CefListValueImpl::SetNull(int index) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateNullValue();
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetBool(int index, bool value) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateBooleanValue(value);
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetInt(int index, int value) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateIntegerValue(value);
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetDouble(int index, double value) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateDoubleValue(value);
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetString(int index, const CefString& value) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateStringValue(value.ToString16());
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetBinary(int index, CefRefPtr<CefBinaryValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
CefBinaryValueImpl* impl = static_cast<CefBinaryValueImpl*>(value.get());
DCHECK(impl);
base::Value* new_value = impl->CopyOrDetachValue(controller());
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetDictionary(int index,
CefRefPtr<CefDictionaryValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
CefDictionaryValueImpl* impl =
static_cast<CefDictionaryValueImpl*>(value.get());
DCHECK(impl);
base::Value* new_value = impl->CopyOrDetachValue(controller());
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetList(int index, CefRefPtr<CefListValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
CefListValueImpl* impl = static_cast<CefListValueImpl*>(value.get());
DCHECK(impl);
base::Value* new_value = impl->CopyOrDetachValue(controller());
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::RemoveInternal(int index) {
base::Value* out_value = NULL;
if (!mutable_value()->Remove(index, &out_value))
return false;
// Remove the value.
controller()->Remove(out_value, true);
// Only list and dictionary types may have dependencies.
if (out_value->IsType(base::Value::TYPE_LIST) ||
out_value->IsType(base::Value::TYPE_DICTIONARY)) {
controller()->RemoveDependencies(out_value);
}
delete out_value;
return true;
}
CefListValueImpl::CefListValueImpl(
base::ListValue* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller)
: CefValueBase<CefListValue, base::ListValue>(
value, parent_value, value_mode, read_only, controller) {
}

194
libcef/common/values_impl.h Normal file
View File

@@ -0,0 +1,194 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_VALUES_IMPL_H_
#define CEF_LIBCEF_COMMON_VALUES_IMPL_H_
#pragma once
#include <vector>
#include "include/cef_values.h"
#include "libcef/common/value_base.h"
#include "base/values.h"
#include "base/threading/platform_thread.h"
// CefBinaryValue implementation
class CefBinaryValueImpl
: public CefValueBase<CefBinaryValue, base::BinaryValue> {
public:
// Get or create a reference value.
static CefRefPtr<CefBinaryValue> GetOrCreateRef(
base::BinaryValue* value,
void* parent_value,
CefValueController* controller);
// Return a copy of the value.
base::BinaryValue* CopyValue();
// If a reference return a copy of the value otherwise detach the value to the
// specified |new_controller|.
base::BinaryValue* CopyOrDetachValue(CefValueController* new_controller);
// CefBinaryValue methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsOwned() OVERRIDE;
virtual CefRefPtr<CefBinaryValue> Copy() OVERRIDE;
virtual size_t GetSize() OVERRIDE;
virtual size_t GetData(void* buffer,
size_t buffer_size,
size_t data_offset) OVERRIDE;
private:
// See the CefValueBase constructor for usage. Binary values are always
// read-only.
CefBinaryValueImpl(base::BinaryValue* value,
void* parent_value,
ValueMode value_mode,
CefValueController* controller);
// If |copy| is false this object will take ownership of the specified |data|
// buffer instead of copying it.
CefBinaryValueImpl(char* data,
size_t data_size,
bool copy);
// For the Create() method.
friend class CefBinaryValue;
DISALLOW_COPY_AND_ASSIGN(CefBinaryValueImpl);
};
// CefDictionaryValue implementation
class CefDictionaryValueImpl
: public CefValueBase<CefDictionaryValue, base::DictionaryValue> {
public:
// Get or create a reference value.
static CefRefPtr<CefDictionaryValue> GetOrCreateRef(
base::DictionaryValue* value,
void* parent_value,
bool read_only,
CefValueController* controller);
// Return a copy of the value.
base::DictionaryValue* CopyValue();
// If a reference return a copy of the value otherwise detach the value to the
// specified |new_controller|.
base::DictionaryValue* CopyOrDetachValue(CefValueController* new_controller);
// CefDictionaryValue methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsOwned() OVERRIDE;
virtual bool IsReadOnly() OVERRIDE;
virtual CefRefPtr<CefDictionaryValue> Copy(
bool exclude_empty_children) OVERRIDE;
virtual size_t GetSize() OVERRIDE;
virtual bool Clear() OVERRIDE;
virtual bool HasKey(const CefString& key) OVERRIDE;
virtual bool GetKeys(KeyList& keys) OVERRIDE;
virtual bool Remove(const CefString& key) OVERRIDE;
virtual CefValueType GetType(const CefString& key) OVERRIDE;
virtual bool GetBool(const CefString& key) OVERRIDE;
virtual int GetInt(const CefString& key) OVERRIDE;
virtual double GetDouble(const CefString& key) OVERRIDE;
virtual CefString GetString(const CefString& key) OVERRIDE;
virtual CefRefPtr<CefBinaryValue> GetBinary(const CefString& key) OVERRIDE;
virtual CefRefPtr<CefDictionaryValue> GetDictionary(
const CefString& key) OVERRIDE;
virtual CefRefPtr<CefListValue> GetList(const CefString& key) OVERRIDE;
virtual bool SetNull(const CefString& key) OVERRIDE;
virtual bool SetBool(const CefString& key, bool value) OVERRIDE;
virtual bool SetInt(const CefString& key, int value) OVERRIDE;
virtual bool SetDouble(const CefString& key, double value) OVERRIDE;
virtual bool SetString(const CefString& key,
const CefString& value) OVERRIDE;
virtual bool SetBinary(const CefString& key,
CefRefPtr<CefBinaryValue> value) OVERRIDE;
virtual bool SetDictionary(const CefString& key,
CefRefPtr<CefDictionaryValue> value) OVERRIDE;
virtual bool SetList(const CefString& key,
CefRefPtr<CefListValue> value) OVERRIDE;
private:
// See the CefValueBase constructor for usage.
CefDictionaryValueImpl(base::DictionaryValue* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller);
bool RemoveInternal(const CefString& key);
// For the Create() method.
friend class CefDictionaryValue;
DISALLOW_COPY_AND_ASSIGN(CefDictionaryValueImpl);
};
// CefListValue implementation
class CefListValueImpl
: public CefValueBase<CefListValue, base::ListValue> {
public:
// Get or create a reference value.
static CefRefPtr<CefListValue> GetOrCreateRef(
base::ListValue* value,
void* parent_value,
bool read_only,
CefValueController* controller);
// Return a copy of the value.
base::ListValue* CopyValue();
// If a reference return a copy of the value otherwise detach the value to the
// specified |new_controller|.
base::ListValue* CopyOrDetachValue(CefValueController* new_controller);
/// CefListValue methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsOwned() OVERRIDE;
virtual bool IsReadOnly() OVERRIDE;
virtual CefRefPtr<CefListValue> Copy() OVERRIDE;
virtual bool SetSize(size_t size) OVERRIDE;
virtual size_t GetSize() OVERRIDE;
virtual bool Clear() OVERRIDE;
virtual bool Remove(int index) OVERRIDE;
virtual CefValueType GetType(int index) OVERRIDE;
virtual bool GetBool(int index) OVERRIDE;
virtual int GetInt(int index) OVERRIDE;
virtual double GetDouble(int index) OVERRIDE;
virtual CefString GetString(int index) OVERRIDE;
virtual CefRefPtr<CefBinaryValue> GetBinary(int index) OVERRIDE;
virtual CefRefPtr<CefDictionaryValue> GetDictionary(int index) OVERRIDE;
virtual CefRefPtr<CefListValue> GetList(int index) OVERRIDE;
virtual bool SetNull(int index) OVERRIDE;
virtual bool SetBool(int index, bool value) OVERRIDE;
virtual bool SetInt(int index, int value) OVERRIDE;
virtual bool SetDouble(int index, double value) OVERRIDE;
virtual bool SetString(int index, const CefString& value) OVERRIDE;
virtual bool SetBinary(int index, CefRefPtr<CefBinaryValue> value) OVERRIDE;
virtual bool SetDictionary(int index,
CefRefPtr<CefDictionaryValue> value) OVERRIDE;
virtual bool SetList(int index, CefRefPtr<CefListValue> value) OVERRIDE;
private:
// See the CefValueBase constructor for usage.
CefListValueImpl(base::ListValue* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller);
bool RemoveInternal(int index);
// For the Create() method.
friend class CefListValue;
DISALLOW_COPY_AND_ASSIGN(CefListValueImpl);
};
#endif // CEF_LIBCEF_COMMON_VALUES_IMPL_H_