Index: ppapi/native_client/tests/ppapi_geturl/module.cc |
=================================================================== |
--- ppapi/native_client/tests/ppapi_geturl/module.cc (revision 0) |
+++ ppapi/native_client/tests/ppapi_geturl/module.cc (revision 0) |
@@ -0,0 +1,323 @@ |
+// Copyright (c) 2011 The Native Client 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 "native_client/tests/ppapi_geturl/module.h" |
+ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+ |
+#include <string> |
+ |
+#include "native_client/src/include/nacl_macros.h" |
+#include "native_client/src/include/portability.h" |
+#include "native_client/src/shared/platform/nacl_check.h" |
+#include "native_client/src/untrusted/ppapi/nacl_file.h" |
+#include "native_client/tests/ppapi_geturl/nacl_file_main.h" |
+#include "native_client/tests/ppapi_geturl/url_load_request.h" |
+ |
+#include "ppapi/c/pp_completion_callback.h" |
+#include "ppapi/c/pp_errors.h" |
+#include "ppapi/c/pp_var.h" |
+#include "ppapi/c/ppp_instance.h" |
+#include "ppapi/c/ppp_messaging.h" |
+ |
+#if !defined(__native_client__) |
+int32_t LoadUrl(PP_Instance /*instance*/, const char* /*url*/, |
+ PP_CompletionCallback /*callback*/) { return PP_OK; } |
+#endif |
+ |
+namespace { |
+ |
+// These constants need to match their corresponding JavaScript values in |
+// ppapi_geturl.html. The JavaScript variables are all upper-case; for example |
+// kTrueStringValue corresponds to TRUE_STRING_VALUE. |
+const char* const kLoadUrlMethodId = "loadUrl"; |
+const char* const kTrueStringValue = "1"; |
+const char* const kFalseStringValue = "0"; |
+static const char kArgumentSeparator = '|'; |
+ |
+// A helper function to convert a bool to a string, used when assembling |
+// messages posted back to the browser. |true| is converted to "1", |false| to |
+// "0". |
+const std::string BoolToString(bool bool_value) { |
+ return bool_value ? kTrueStringValue : kFalseStringValue; |
+} |
+ |
+PPP_Instance instance_interface; |
+PPP_Messaging messaging_interface; |
+Module* singleton_ = NULL; |
+ |
+void RunTests(void* user_data) { |
+ int* count = reinterpret_cast<int*>(user_data); |
+ *count -= 1; |
+ if (*count == 0) |
+ test_nacl_file(); |
+} |
+} // namespace |
+ |
+void HTMLLoaded(void* user_data, int32_t result) { |
+ CHECK(PP_OK == result); |
+ printf("--- HTMLLoaded() SUCCESS: completion callback got PP_OK\n"); |
+ RunTests(user_data); |
+} |
+ |
+void RobotLoaded(void* user_data, int32_t result) { |
+ CHECK(PP_ERROR_NOACCESS == result); |
+ printf("--- RobotLoaded() SUCCESS: unable to LoadUrl on cross-domain\n"); |
+ RunTests(user_data); |
+} |
+ |
+void NonExistLoaded(void* user_data, int32_t result) { |
+ CHECK(PP_ERROR_FAILED == result); |
+ printf("--- NonExistLoaded() SUCCESS: callback got PP_ERROR_FAILED\n"); |
+ RunTests(user_data); |
+} |
+ |
+PP_Bool Instance_DidCreate(PP_Instance pp_instance, |
+ uint32_t /*argc*/, |
+ const char* /*argn*/[], |
+ const char* /*argv*/[]) { |
+ printf("--- Instance_DidCreate\n"); |
+ int* url_count = new int(3); |
+ PP_CompletionCallback html_cb = |
+ PP_MakeCompletionCallback(HTMLLoaded, url_count); |
+ int32_t result = LoadUrl(pp_instance, "ppapi_geturl_success.html", html_cb); |
+ |
+ PP_CompletionCallback robot_cb = |
+ PP_MakeCompletionCallback(RobotLoaded, url_count); |
+ result = LoadUrl(pp_instance, "http://www.google.com/robots.txt", robot_cb); |
+ |
+ PP_CompletionCallback non_exist_cb = |
+ PP_MakeCompletionCallback(NonExistLoaded, url_count); |
+ result = LoadUrl(pp_instance, "ppapi_nonexistent_url.html", non_exist_cb); |
+ |
+ return PP_TRUE; |
+} |
+ |
+void Instance_DidDestroy(PP_Instance /*instance*/) { |
+ printf("--- Instance_DidDestroy\n"); |
+} |
+ |
+void Instance_DidChangeView(PP_Instance /*pp_instance*/, |
+ const PP_Rect* /*position*/, |
+ const PP_Rect* /*clip*/) { |
+} |
+ |
+void Instance_DidChangeFocus(PP_Instance /*pp_instance*/, |
+ PP_Bool /*has_focus*/) { |
+} |
+ |
+PP_Bool Instance_HandleDocumentLoad(PP_Instance /*pp_instance*/, |
+ PP_Resource /*pp_url_loader*/) { |
+ return PP_FALSE; |
+} |
+ |
+void Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message) { |
+ if (var_message.type != PP_VARTYPE_STRING) |
+ return; |
+ std::string message = Module::Get()->VarToStr(var_message); |
+ printf("--- Messaging_HandleMessage(%s)\n", message.c_str()); |
+ // Look for the "loadUrl" message. The expected string format looks like: |
+ // loadUrl|<url>|<stream_as_file> |
+ // loadUrl is a string literal |
+ // <url> is the URL used to make the GET request in UrlLoader |
+ // <stream_as_file> represent Boolean true if it's a '1' or false if it's |
+ // anything else. |
+ if (message.find(kLoadUrlMethodId) != 0) |
+ return; |
+ |
+ size_t url_pos = message.find_first_of(kArgumentSeparator); |
+ if (url_pos == std::string::npos || url_pos + 1 >= message.length()) |
+ return; |
+ |
+ size_t as_file_pos = message.find_first_of(kArgumentSeparator, url_pos + 1); |
+ if (as_file_pos == std::string::npos || as_file_pos + 1 >= message.length()) |
+ return; |
+ |
+ size_t url_length = as_file_pos - url_pos; |
+ if (url_length == 0) |
+ return; |
+ std::string url = message.substr(url_pos + 1, url_length - 1); |
+ |
+ // If the second argument is a '1', assume it means |stream_as_file| is |
+ // true. Anything else means |stream_as_file| is false. |
+ bool stream_as_file = message.compare(as_file_pos + 1, |
+ 1, |
+ kTrueStringValue) == 0; |
+ |
+ printf("--- Messaging_HandleMessage(method='%s', " |
+ "url='%s', " |
+ "stream_as_file='%s')\n", |
+ message.c_str(), |
+ url.c_str(), |
+ stream_as_file ? "true" : "false"); |
+ fflush(stdout); |
+ |
+ UrlLoadRequest* url_load_request = new UrlLoadRequest(instance); |
+ if (NULL == url_load_request) { |
+ Module::Get()->ReportResult(instance, |
+ url.c_str(), |
+ stream_as_file, |
+ "LoadUrl: memory allocation failed", |
+ false); |
+ return; |
+ } |
+ // On success or failure url_load_request will call ReportResult(). |
+ // This is the time to clean it up. |
+ url_load_request->set_delete_this_after_report(); |
+ url_load_request->Load(stream_as_file, url); |
+} |
+ |
+Module* Module::Create(PP_Module module_id, |
+ PPB_GetInterface get_browser_interface) { |
+ if (NULL == singleton_) { |
+ singleton_ = new Module(module_id, get_browser_interface); |
+ } |
+ return singleton_; |
+} |
+ |
+Module* Module::Get() { |
+ return singleton_; |
+} |
+ |
+void Module::Free() { |
+ delete singleton_; |
+ singleton_ = NULL; |
+} |
+ |
+Module::Module(PP_Module module_id, PPB_GetInterface get_browser_interface) |
+ : module_id_(module_id), |
+ get_browser_interface_(get_browser_interface), |
+ ppb_core_interface_(NULL), |
+ ppb_messaging_interface_(NULL), |
+ ppb_var_interface_(NULL) { |
+ printf("--- Module::Module\n"); |
+ memset(&instance_interface, 0, sizeof(instance_interface)); |
+ instance_interface.DidCreate = Instance_DidCreate; |
+ instance_interface.DidDestroy = Instance_DidDestroy; |
+ instance_interface.DidChangeView = Instance_DidChangeView; |
+ instance_interface.DidChangeFocus = Instance_DidChangeFocus; |
+ instance_interface.HandleDocumentLoad = Instance_HandleDocumentLoad; |
+ |
+ memset(&messaging_interface, 0, sizeof(messaging_interface)); |
+ messaging_interface.HandleMessage = Messaging_HandleMessage; |
+ |
+ ppb_core_interface_ = |
+ static_cast<const PPB_Core*>( |
+ GetBrowserInterface(PPB_CORE_INTERFACE)); |
+ ppb_messaging_interface_ = |
+ static_cast<const PPB_Messaging*>( |
+ GetBrowserInterface(PPB_MESSAGING_INTERFACE)); |
+ ppb_var_interface_ = |
+ static_cast<const PPB_Var*>( |
+ GetBrowserInterface(PPB_VAR_INTERFACE)); |
+} |
+ |
+const void* Module::GetPluginInterface(const char* interface_name) { |
+ printf("--- Module::GetPluginInterface(%s)\n", interface_name); |
+ if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) |
+ return &instance_interface; |
+ if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) |
+ return &messaging_interface; |
+ return NULL; |
+} |
+ |
+const void* Module::GetBrowserInterface(const char* interface_name) { |
+ if (NULL == get_browser_interface_) |
+ return NULL; |
+ return (*get_browser_interface_)(interface_name); |
+} |
+ |
+char* Module::VarToCStr(const PP_Var& var) { |
+ Module* module = Get(); |
+ if (NULL == module) |
+ return NULL; |
+ const PPB_Var* ppb_var = module->ppb_var_interface(); |
+ if (NULL == ppb_var) |
+ return NULL; |
+ uint32_t len = 0; |
+ const char* pp_str = ppb_var->VarToUtf8(var, &len); |
+ if (NULL == pp_str) |
+ return NULL; |
+ char* str = static_cast<char*>(malloc(len + 1)); |
+ if (NULL == str) |
+ return NULL; |
+ memcpy(str, pp_str, len); |
+ str[len] = 0; |
+ return str; |
+} |
+ |
+std::string Module::VarToStr(const PP_Var& var) { |
+ std::string str; |
+ char* cstr = VarToCStr(var); |
+ if (NULL != cstr) { |
+ str = cstr; |
+ free(cstr); |
+ } |
+ return str; |
+} |
+ |
+PP_Var Module::StrToVar(const char* str) { |
+ Module* module = Get(); |
+ if (NULL == module) |
+ return PP_MakeUndefined(); |
+ const PPB_Var* ppb_var = module->ppb_var_interface(); |
+ if (NULL != ppb_var) |
+ return ppb_var->VarFromUtf8(module->module_id(), str, strlen(str)); |
+ return PP_MakeUndefined(); |
+} |
+ |
+PP_Var Module::StrToVar(const std::string& str) { |
+ return Module::StrToVar(str.c_str()); |
+} |
+ |
+std::string Module::ErrorCodeToStr(int32_t error_code) { |
+ switch (error_code) { |
+ case PP_OK: return "PP_OK"; |
+ case PP_OK_COMPLETIONPENDING: return "PP_OK_COMPLETIONPENDING"; |
+ case PP_ERROR_FAILED: return "PP_ERROR_FAILED"; |
+ case PP_ERROR_ABORTED: return "PP_ERROR_ABORTED"; |
+ case PP_ERROR_BADARGUMENT: return "PP_ERROR_BADARGUMENT"; |
+ case PP_ERROR_BADRESOURCE: return "PP_ERROR_BADRESOURCE"; |
+ case PP_ERROR_NOINTERFACE: return "PP_ERROR_NOINTERFACE"; |
+ case PP_ERROR_NOACCESS: return "PP_ERROR_NOACCESS"; |
+ case PP_ERROR_NOMEMORY: return "PP_ERROR_NOMEMORY"; |
+ case PP_ERROR_NOSPACE: return "PP_ERROR_NOSPACE"; |
+ case PP_ERROR_NOQUOTA: return "PP_ERROR_NOQUOTA"; |
+ case PP_ERROR_INPROGRESS: return "PP_ERROR_INPROGRESS"; |
+ case PP_ERROR_FILENOTFOUND: return "PP_ERROR_FILENOTFOUND"; |
+ case PP_ERROR_FILEEXISTS: return "PP_ERROR_FILEEXISTS"; |
+ case PP_ERROR_FILETOOBIG: return "PP_ERROR_FILETOOBIG"; |
+ case PP_ERROR_FILECHANGED: return "PP_ERROR_FILECHANGED"; |
+ case PP_ERROR_TIMEDOUT: return "PP_ERROR_TIMEDOUT"; |
+ } |
+ return "N/A"; |
+} |
+ |
+void Module::ReportResult(PP_Instance pp_instance, |
+ const char* url, |
+ bool as_file, |
+ const char* text, |
+ bool success) { |
+ printf("--- ReportResult('%s', as_file=%d, '%s', success=%d)\n", |
+ url, as_file, text, success); |
+ // Post a message with the results back to the browser. |
+ std::string result(url); |
+ result += kArgumentSeparator; |
+ result += BoolToString(as_file); |
+ result += kArgumentSeparator; |
+ result += text; |
+ result += kArgumentSeparator; |
+ result += BoolToString(success); |
+ printf("--- ReportResult posts result string:\n\t%s\n", result.c_str()); |
+ struct PP_Var var_result = StrToVar(result); |
+ ppb_messaging_interface()->PostMessage(pp_instance, var_result); |
+ // If the message was created using VarFromUtf8() it needs to be released. |
+ // See the comments about VarFromUtf8() in ppapi/c/ppb_var.h for more |
+ // information. |
+ if (var_result.type == PP_VARTYPE_STRING) { |
+ ppb_var_interface()->Release(var_result); |
+ } |
+} |