cefclient:

- Add Mac support for binary resource loading (issue #198).
- Simplify binary resource loading usage.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@197 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2011-03-04 02:14:04 +00:00
parent 377bd880b4
commit 91a46104f9
7 changed files with 217 additions and 73 deletions

View File

@ -51,6 +51,10 @@
'tests/cefclient/mac/English.lproj/InfoPlist.strings',
'tests/cefclient/mac/English.lproj/MainMenu.xib',
'tests/cefclient/mac/Info.plist',
'tests/cefclient/res/domaccess.html',
'tests/cefclient/res/localstorage.html',
'tests/cefclient/res/logo.png',
'tests/cefclient/res/xmlhttprequest.html',
],
'mac_bundle_resources!': [
# TODO(mark): Come up with a fancier way to do this (mac_info_plist?)
@ -155,6 +159,7 @@
},
'sources': [
'tests/cefclient/cefclient_mac.mm',
'tests/cefclient/resource_util_mac.mm',
],
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {

View File

@ -8,6 +8,7 @@
#include "cefclient.h"
#include "binding_test.h"
#include "extension_test.h"
#include "resource_util.h"
#include "scheme_test.h"
#include "string_util.h"
#import <Cocoa/Cocoa.h>
@ -163,6 +164,9 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
- (IBAction)testJSExtension:(id)sender;
- (IBAction)testJSExecute:(id)sender;
- (IBAction)testRequest:(id)sender;
- (IBAction)testLocalStorage:(id)sender;
- (IBAction)testXMLHttpRequest:(id)sender;
- (IBAction)testDOMAccess:(id)sender;
- (IBAction)testSchemeHandler:(id)sender;
- (IBAction)testPopupWindow:(id)sender;
- (IBAction)testAccelerated2DCanvas:(id)sender;
@ -205,14 +209,23 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
[testMenu addItemWithTitle:@"JavaScript Execute"
action:@selector(testJSExecute:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Popup Window"
action:@selector(testPopupWindow:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Request"
action:@selector(testRequest:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Scheme Handler"
action:@selector(testSchemeHandler:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Popup Window"
action:@selector(testPopupWindow:)
[testMenu addItemWithTitle:@"Local Storage"
action:@selector(testLocalStorage:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"XMLHttpRequest"
action:@selector(testXMLHttpRequest:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"DOM Access"
action:@selector(testDOMAccess:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Accelerated 2D Canvas"
action:@selector(testAccelerated2DCanvas:)
@ -351,6 +364,21 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
RunRequestTest(g_handler->GetBrowser());
}
- (IBAction)testLocalStorage:(id)sender {
if(g_handler.get() && g_handler->GetBrowserHwnd())
RunLocalStorageTest(g_handler->GetBrowser());
}
- (IBAction)testXMLHttpRequest:(id)sender {
if(g_handler.get() && g_handler->GetBrowserHwnd())
RunXMLHTTPRequestTest(g_handler->GetBrowser());
}
- (IBAction)testDOMAccess:(id)sender {
if(g_handler.get() && g_handler->GetBrowserHwnd())
RunDOMAccessTest(g_handler->GetBrowser());
}
- (IBAction)testSchemeHandler:(id)sender {
if(g_handler.get() && g_handler->GetBrowserHwnd())
RunSchemeTest(g_handler->GetBrowser());
@ -490,7 +518,24 @@ CefHandler::RetVal ClientHandler::HandleBeforeResourceLoad(
resourceStream = CefStreamReader::CreateForData(
(void*)dump.c_str(), dump.size());
mimeType = "text/plain";
} else if (strstr(url.c_str(), "/ps_logo2.png") != NULL) {
// Any time we find "ps_logo2.png" in the URL substitute in our own image
resourceStream = GetBinaryResourceReader("logo.png");
mimeType = "image/png";
} else if(url == "http://tests/localstorage") {
// Show the localstorage contents
resourceStream = GetBinaryResourceReader("localstorage.html");
mimeType = "text/html";
} else if(url == "http://tests/xmlhttprequest") {
// Show the xmlhttprequest HTML contents
resourceStream = GetBinaryResourceReader("xmlhttprequest.html");
mimeType = "text/html";
} else if(url == "http://tests/domaccess") {
// Show the domaccess HTML contents
resourceStream = GetBinaryResourceReader("domaccess.html");
mimeType = "text/html";
}
return RV_CONTINUE;
}

View File

@ -688,9 +688,6 @@ CefHandler::RetVal ClientHandler::HandleBeforeResourceLoad(
{
REQUIRE_IO_THREAD();
DWORD dwSize;
LPBYTE pBytes;
std::string url = request->GetURL();
if(url == "http://tests/request") {
// Show the request contents
@ -699,48 +696,30 @@ CefHandler::RetVal ClientHandler::HandleBeforeResourceLoad(
resourceStream =
CefStreamReader::CreateForData((void*)dump.c_str(), dump.size());
mimeType = "text/plain";
} else if(url == "http://tests/uiapp") {
// Show the uiapp contents
if(LoadBinaryResource(IDS_UIPLUGIN, dwSize, pBytes)) {
resourceStream = CefStreamReader::CreateForHandler(
new CefByteReadHandler(pBytes, dwSize, NULL));
mimeType = "text/html";
}
} else if(url == "http://tests/localstorage") {
// Show the localstorage contents
if(LoadBinaryResource(IDS_LOCALSTORAGE, dwSize, pBytes)) {
resourceStream = CefStreamReader::CreateForHandler(
new CefByteReadHandler(pBytes, dwSize, NULL));
mimeType = "text/html";
}
} else if(url == "http://tests/xmlhttprequest") {
// Show the xmlhttprequest HTML contents
if(LoadBinaryResource(IDS_XMLHTTPREQUEST, dwSize, pBytes)) {
resourceStream = CefStreamReader::CreateForHandler(
new CefByteReadHandler(pBytes, dwSize, NULL));
mimeType = "text/html";
}
} else if(url == "http://tests/domaccess") {
// Show the domaccess HTML contents
if(LoadBinaryResource(IDS_DOMACCESS, dwSize, pBytes)) {
resourceStream = CefStreamReader::CreateForHandler(
new CefByteReadHandler(pBytes, dwSize, NULL));
mimeType = "text/html";
}
} else if(strstr(url.c_str(), "/ps_logo2.png") != NULL) {
// Any time we find "ps_logo2.png" in the URL substitute in our own image
if(LoadBinaryResource(IDS_LOGO, dwSize, pBytes)) {
resourceStream = CefStreamReader::CreateForHandler(
new CefByteReadHandler(pBytes, dwSize, NULL));
mimeType = "image/png";
}
resourceStream = GetBinaryResourceReader(IDS_LOGO);
mimeType = "image/png";
} else if(url == "http://tests/uiapp") {
// Show the uiapp contents
resourceStream = GetBinaryResourceReader(IDS_UIPLUGIN);
mimeType = "text/html";
} else if(url == "http://tests/localstorage") {
// Show the localstorage contents
resourceStream = GetBinaryResourceReader(IDS_LOCALSTORAGE);
mimeType = "text/html";
} else if(url == "http://tests/xmlhttprequest") {
// Show the xmlhttprequest HTML contents
resourceStream = GetBinaryResourceReader(IDS_XMLHTTPREQUEST);
mimeType = "text/html";
} else if(url == "http://tests/domaccess") {
// Show the domaccess HTML contents
resourceStream = GetBinaryResourceReader(IDS_DOMACCESS);
mimeType = "text/html";
} else if(strstr(url.c_str(), "/logoball.png") != NULL) {
// Load the "logoball.png" image resource.
if(LoadBinaryResource(IDS_LOGOBALL, dwSize, pBytes)) {
resourceStream = CefStreamReader::CreateForHandler(
new CefByteReadHandler(pBytes, dwSize, NULL));
mimeType = "image/png";
}
resourceStream = GetBinaryResourceReader(IDS_LOGOBALL);
mimeType = "image/png";
}
return RV_CONTINUE;
}

View File

@ -7,11 +7,20 @@
#include "include/cef.h"
#ifdef _WIN32
#if defined(_WIN32)
// Load a resource of type BINARY
bool LoadBinaryResource(int binaryId, DWORD &dwSize, LPBYTE &pBytes);
CefRefPtr<CefStreamReader> GetBinaryResourceReader(int binaryId);
#endif // _WIN32
// end of _WIN32
#elif defined(__APPLE__)
// Load the resource with the specified name.
bool LoadBinaryResource(const char* resource_name, std::string& resource_data);
CefRefPtr<CefStreamReader> GetBinaryResourceReader(const char* resource_name);
// end of __APPLE__
#endif
#endif // _CEFCLIENT_RESOURCE_UTIL

View File

@ -0,0 +1,97 @@
// Copyright (c) 2011 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.
#include "resource_util.h"
#include "util.h"
#import <Foundation/Foundation.h>
#include <mach-o/dyld.h>
#include <stdio.h>
namespace {
bool AmIBundled() {
// Implementation adapted from Chromium's base/mac/foundation_util.mm
ProcessSerialNumber psn = {0, kCurrentProcess};
FSRef fsref;
OSStatus pbErr;
if ((pbErr = GetProcessBundleLocation(&psn, &fsref)) != noErr) {
ASSERT(false);
return false;
}
FSCatalogInfo info;
OSErr fsErr;
if ((fsErr = FSGetCatalogInfo(&fsref, kFSCatInfoNodeFlags, &info,
NULL, NULL, NULL)) != noErr) {
ASSERT(false);
return false;
}
return (info.nodeFlags & kFSNodeIsDirectoryMask);
}
bool GetResourceDir(std::string& dir) {
// Implementation adapted from Chromium's base/base_path_mac.mm
if (AmIBundled()) {
// Retrieve the executable directory.
uint32_t pathSize = 0;
_NSGetExecutablePath(NULL, &pathSize);
if (pathSize > 0) {
dir.resize(pathSize);
_NSGetExecutablePath(const_cast<char*>(dir.c_str()), &pathSize);
}
// Trim executable name up to the last separator
std::string::size_type last_separator = dir.find_last_of("/");
dir.resize(last_separator);
dir.append("/../Resources");
return true;
} else {
// TODO: Provide unbundled path
ASSERT(false);
return false;
}
}
bool ReadFileToString(const char* path, std::string& data) {
// Implementation adapted from base/file_util.cc
FILE* file = fopen(path, "rb");
if (!file)
return false;
char buf[1 << 16];
size_t len;
while ((len = fread(buf, 1, sizeof(buf), file)) > 0)
data.append(buf, len);
fclose(file);
return true;
}
} // namespace
bool LoadBinaryResource(const char* resource_name, std::string& resource_data) {
std::string path;
if (!GetResourceDir(path))
return false;
path.append("/");
path.append(resource_name);
return ReadFileToString(path.c_str(), resource_data);
}
CefRefPtr<CefStreamReader> GetBinaryResourceReader(const char* resource_name) {
std::string path;
if (!GetResourceDir(path))
return NULL;
path.append("/");
path.append(resource_name);
return CefStreamReader::CreateForFile(path);
}

View File

@ -3,6 +3,7 @@
// can be found in the LICENSE file.
#include "resource_util.h"
#include "include/cef_wrapper.h"
#ifdef _WIN32
@ -26,4 +27,17 @@ bool LoadBinaryResource(int binaryId, DWORD &dwSize, LPBYTE &pBytes)
return false;
}
CefRefPtr<CefStreamReader> GetBinaryResourceReader(int binaryId)
{
DWORD dwSize;
LPBYTE pBytes;
if(LoadBinaryResource(binaryId, dwSize, pBytes)) {
return CefStreamReader::CreateForHandler(
new CefByteReadHandler(pBytes, dwSize, NULL));
}
return NULL;
}
#endif // _WIN32

View File

@ -17,7 +17,7 @@
class ClientSchemeHandler : public CefThreadSafeBase<CefSchemeHandler>
{
public:
ClientSchemeHandler() : size_(0), offset_(0), bytes_(NULL) {}
ClientSchemeHandler() : offset_(0) {}
// Process the request. All response generation should take place in this
// method. If there is no response set |response_length| to zero and
@ -39,23 +39,18 @@ public:
std::string url = request->GetURL();
if(strstr(url.c_str(), "handler.html") != NULL) {
// Build the response html
html_ = "<html><head><title>Client Scheme Handler</title></head><body>"
data_ = "<html><head><title>Client Scheme Handler</title></head><body>"
"This contents of this page page are served by the "
"ClientSchemeHandler class handling the client:// protocol.";
#ifdef _WIN32
html_.append("<br/>You should see an image:"
"<br/><img src=\"client://tests/client.gif\">");
#endif // _WIN32
html_.append("<pre>");
"ClientSchemeHandler class handling the client:// protocol."
"<br/>You should see an image:"
"<br/><img src=\"client://tests/client.png\"><pre>";
// Output a string representation of the request
std::string dump;
DumpRequestContents(request, dump);
html_.append(dump);
data_.append(dump);
html_.append("</pre><br/>Try the test form:"
data_.append("</pre><br/>Try the test form:"
"<form method=\"POST\" action=\"handler.html\">"
"<input type=\"text\" name=\"field1\">"
"<input type=\"text\" name=\"field2\">"
@ -63,29 +58,30 @@ public:
"</form></body></html>");
handled = true;
size_ = html_.size();
bytes_ = html_.c_str();
// Set the resulting mime type
mime_type = "text/html";
}
#ifdef _WIN32
else if(strstr(url.c_str(), "client.gif") != NULL) {
else if(strstr(url.c_str(), "client.png") != NULL) {
// Load the response image
#if defined(_WIN32)
DWORD dwSize;
LPBYTE pBytes;
if(LoadBinaryResource(IDS_LOGO, dwSize, pBytes)) {
size_ = dwSize;
bytes_ = reinterpret_cast<const char*>(pBytes);
data_ = std::string(reinterpret_cast<const char*>(pBytes), dwSize);
handled = true;
// Set the resulting mime type
mime_type = "image/jpg";
mime_type = "image/png";
}
#elif defined(__APPLE__)
if(LoadBinaryResource("logo.png", data_)) {
handled = true;
mime_type = "image/png";
}
#endif
}
#endif // _WIN32
// Set the resulting response length
*response_length = size_;
*response_length = data_.length();
Unlock();
return handled;
@ -110,11 +106,11 @@ public:
Lock();
if(offset_ < size_) {
if(offset_ < data_.length()) {
// Copy the next block of data into the buffer.
int transfer_size =
std::min(bytes_to_read, static_cast<int>(size_ - offset_));
memcpy(data_out, bytes_ + offset_, transfer_size);
std::min(bytes_to_read, static_cast<int>(data_.length() - offset_));
memcpy(data_out, data_.c_str() + offset_, transfer_size);
offset_ += transfer_size;
*bytes_read = transfer_size;
@ -127,9 +123,8 @@ public:
}
private:
size_t size_, offset_;
const char* bytes_;
std::string html_;
std::string data_;
size_t offset_;
};
// Implementation of the factory for for creating schema handlers.