// Copyright (c) 2010 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 "content/test/plugin/plugin_test.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "content/test/plugin/npapi_constants.h"
namespace NPAPIClient {
PluginTest::PluginTest(NPP id, NPNetscapeFuncs *host_functions) {
id_ = id;
id_->pdata = this;
host_functions_ = host_functions;
test_completed_ = false;
}
PluginTest::~PluginTest() {}
bool PluginTest::IsWindowless() const { return false; }
NPError PluginTest::New(uint16 mode, int16 argc, const char* argn[],
const char* argv[], NPSavedData* saved) {
test_name_ = this->GetArgValue("name", argc, argn, argv);
const char* id = this->GetArgValue("id", argc, argn, argv);
if (id) // NULL for NP_FULL
test_id_ = id;
return NPERR_NO_ERROR;
}
NPError PluginTest::Destroy() {
return NPERR_NO_ERROR;
}
NPError PluginTest::SetWindow(NPWindow* pNPWindow) {
return NPERR_NO_ERROR;
}
// It's a shame I have to implement URLEncode. But, using webkit's
// or using chrome's means a ball of string of dlls and dependencies that
// is very very long. After spending far too much time on it,
// I'll just encode it myself. Too bad Microsoft doesn't implement
// this in a reusable way either. Both webkit and chrome will
// end up using libicu, which is a string of dependencies we don't
// want.
inline unsigned char toHex(const unsigned char x) {
return x > 9 ? (x + 'A' - 10) : (x + '0');
}
std::string URLEncode(const std::string &sIn) {
std::string sOut;
const size_t length = sIn.length();
for (size_t idx = 0; idx < length;) {
const char ch = sIn.at(idx);
if (isalnum(ch)) {
sOut.append(1, ch);
} else if (isspace(ch) && ((ch != '\n') && (ch != '\r'))) {
sOut.append(1, '+');
} else {
sOut.append(1, '%');
sOut.append(1, toHex(ch>>4));
sOut.append(1, toHex(ch%16));
}
idx++;
}
return sOut;
}
void PluginTest::SignalTestCompleted() {
NPObject *window_obj = NULL;
host_functions_->getvalue(id_, NPNVWindowNPObject, &window_obj);
if (!window_obj)
return;
test_completed_ = true;
// To signal test completion, we expect a couple of
// javascript functions to be defined in the webpage
// which hosts this plugin:
// onSuccess(test_name, test_id)
// onFailure(test_name, test_id, error_message)
std::string script("javascript:");
if (Succeeded()) {
script.append("onSuccess(\"");
script.append(test_name_);
script.append("\",\"");
script.append(test_id_);
script.append("\");");
} else {
script.append("onFailure(\"");
script.append(test_name_);
script.append("\",\"");
script.append(test_id_);
script.append("\",\"");
script.append(test_status_);
script.append("\");");
}
NPString script_string;
script_string.UTF8Characters = script.c_str();
script_string.UTF8Length = static_cast<unsigned int>(script.length());
NPVariant result_var;
host_functions_->evaluate(id_, window_obj, &script_string, &result_var);
}
const char *PluginTest::GetArgValue(const char *name, const int16 argc,
const char *argn[], const char *argv[]) {
for (int idx = 0; idx < argc; idx++)
if (base::strcasecmp(argn[idx], name) == 0)
return argv[idx];
return NULL;
}
void PluginTest::SetError(const std::string &msg) {
test_status_.append(msg);
}
void PluginTest::ExpectStringLowerCaseEqual(const std::string &val1,
const std::string &val2) {
if (!LowerCaseEqualsASCII(val1, val2.c_str())) {
std::string err;
err = "Expected Equal for '";
err.append(val1);
err.append("' and '");
err.append(val2);
err.append("'");
SetError(err);
}
}
void PluginTest::ExpectAsciiStringNotEqual(const char *val1, const char *val2) {
if (val1 == val2) {
std::string err;
err = "Expected Not Equal for '";
err.append(val1);
err.append("' and '");
err.append(val2);
err.append("'");
SetError(err);
}
}
void PluginTest::ExpectIntegerEqual(int val1, int val2) {
if (val1 != val2) {
std::string err;
err = "Expected Equal for '";
err.append(base::IntToString(val1));
err.append("' and '");
err.append(base::IntToString(val2));
err.append("'");
SetError(err);
}
}
NPError PluginTest::NewStream(NPMIMEType type, NPStream* stream,
NPBool seekable, uint16* stype) {
// There is no default action here.
return NPERR_NO_ERROR;
}
int32 PluginTest::WriteReady(NPStream *stream) {
// Take data in small chunks
return 4096;
}
int32 PluginTest::Write(NPStream *stream, int32 offset, int32 len,
void *buffer) {
// Pretend that we took all the data.
return len;
}
NPError PluginTest::DestroyStream(NPStream *stream, NPError reason) {
// There is no default action.
return NPERR_NO_ERROR;
}
void PluginTest::StreamAsFile(NPStream* stream, const char* fname) {
// There is no default action.
}
void PluginTest::URLNotify(const char* url, NPReason reason, void* data) {
// There is no default action
}
int16 PluginTest::HandleEvent(void* event) {
// There is no default action
return 0;
}
void PluginTest::URLRedirectNotify(const char* url, int32_t status,
void* notify_data) {
// There is no default action
}
} // namespace NPAPIClient