summaryrefslogtreecommitdiffstats
path: root/webkit/glue/cpp_variant.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:20:51 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:20:51 +0000
commitf5b16fed647e941aa66933178da85db2860d639b (patch)
treef00e9856c04aad3b558a140955e7674add33f051 /webkit/glue/cpp_variant.cc
parent920c091ac3ee15079194c82ae8a7a18215f3f23c (diff)
downloadchromium_src-f5b16fed647e941aa66933178da85db2860d639b.zip
chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.gz
chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.bz2
Add webkit to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/cpp_variant.cc')
-rw-r--r--webkit/glue/cpp_variant.cc276
1 files changed, 276 insertions, 0 deletions
diff --git a/webkit/glue/cpp_variant.cc b/webkit/glue/cpp_variant.cc
new file mode 100644
index 0000000..0fb43e1
--- /dev/null
+++ b/webkit/glue/cpp_variant.cc
@@ -0,0 +1,276 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file contains definitions for CppVariant.
+
+#include <limits>
+#include "config.h"
+#include "webkit/glue/cpp_variant.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+
+#include "npruntime_priv.h" // for NPN_InitializeVariantWithStringCopy
+
+#if USE(JAVASCRIPTCORE_BINDINGS)
+#define _NPN_InitializeVariantWithStringCopy NPN_InitializeVariantWithStringCopy
+#endif
+
+CppVariant::CppVariant() {
+ type = NPVariantType_Null;
+}
+
+// Note that Set() performs a deep copy, which is necessary to safely
+// call FreeData() on the value in the destructor.
+CppVariant::CppVariant(const CppVariant& original) {
+ type = NPVariantType_Null;
+ Set(original);
+}
+
+// See comment for copy constructor, above.
+CppVariant& CppVariant::operator=(const CppVariant& original) {
+ if (&original != this)
+ Set(original);
+ return *this;
+}
+
+CppVariant::~CppVariant() {
+ FreeData();
+}
+
+void CppVariant::FreeData() {
+ NPN_ReleaseVariantValue(this);
+}
+
+bool CppVariant::isEqual(const CppVariant& other) const {
+ if (type != other.type)
+ return false;
+
+ switch (type) {
+ case NPVariantType_Bool: {
+ return (value.boolValue == other.value.boolValue);
+ }
+ case NPVariantType_Int32: {
+ return (value.intValue == other.value.intValue);
+ }
+ case NPVariantType_Double: {
+ return (value.doubleValue == other.value.doubleValue);
+ }
+ case NPVariantType_String: {
+ const NPString *this_value = &value.stringValue;
+ const NPString *other_value = &other.value.stringValue;
+ uint32_t len = this_value->UTF8Length;
+ return (len == other_value->UTF8Length &&
+ !strncmp(this_value->UTF8Characters, other_value->UTF8Characters,
+ len));
+ }
+ case NPVariantType_Null:
+ case NPVariantType_Void: {
+ return true;
+ }
+ case NPVariantType_Object: {
+ NPObject *this_value = value.objectValue;
+ NPObject *other_value = other.value.objectValue;
+ return (this_value->_class == other_value->_class &&
+ this_value->referenceCount == other_value->referenceCount);
+ }
+ }
+ return false;
+}
+
+void CppVariant::CopyToNPVariant(NPVariant* result) const {
+ result->type = type;
+ switch (type) {
+ case NPVariantType_Bool:
+ result->value.boolValue = value.boolValue;
+ break;
+ case NPVariantType_Int32:
+ result->value.intValue = value.intValue;
+ break;
+ case NPVariantType_Double:
+ result->value.doubleValue = value.doubleValue;
+ break;
+ case NPVariantType_String:
+ _NPN_InitializeVariantWithStringCopy(result, &value.stringValue);
+ break;
+ case NPVariantType_Null:
+ case NPVariantType_Void:
+ // Nothing to set.
+ break;
+ case NPVariantType_Object:
+ result->type = NPVariantType_Object;
+ result->value.objectValue = NPN_RetainObject(value.objectValue);
+ break;
+ }
+}
+
+void CppVariant::Set(const NPVariant& new_value) {
+ FreeData();
+ switch (new_value.type) {
+ case NPVariantType_Bool:
+ Set(new_value.value.boolValue);
+ break;
+ case NPVariantType_Int32:
+ Set(new_value.value.intValue);
+ break;
+ case NPVariantType_Double:
+ Set(new_value.value.doubleValue);
+ break;
+ case NPVariantType_String:
+ Set(new_value.value.stringValue);
+ break;
+ case NPVariantType_Null:
+ case NPVariantType_Void:
+ type = new_value.type;
+ break;
+ case NPVariantType_Object:
+ Set(new_value.value.objectValue);
+ break;
+ }
+}
+
+void CppVariant::SetNull() {
+ FreeData();
+ type = NPVariantType_Null;
+}
+
+void CppVariant::Set(bool new_value) {
+ FreeData();
+ type = NPVariantType_Bool;
+ value.boolValue = new_value;
+}
+
+void CppVariant::Set(int32_t new_value) {
+ FreeData();
+ type = NPVariantType_Int32;
+ value.intValue = new_value;
+}
+
+void CppVariant::Set(double new_value) {
+ FreeData();
+ type = NPVariantType_Double;
+ value.doubleValue = new_value;
+}
+
+// The new_value must be a null-terminated string.
+void CppVariant::Set(const char* new_value) {
+ FreeData();
+ type = NPVariantType_String;
+ NPString new_string = {new_value,
+ static_cast<uint32_t>(strlen(new_value))};
+ _NPN_InitializeVariantWithStringCopy(this, &new_string);
+}
+
+void CppVariant::Set(const std::string& new_value) {
+ FreeData();
+ type = NPVariantType_String;
+ NPString new_string = {new_value.data(),
+ static_cast<uint32_t>(new_value.size())};
+ _NPN_InitializeVariantWithStringCopy(this, &new_string);
+}
+void CppVariant::Set(const NPString& new_value) {
+ FreeData();
+ type = NPVariantType_String;
+ _NPN_InitializeVariantWithStringCopy(this, &new_value);
+}
+
+void CppVariant::Set(NPObject* new_value) {
+ FreeData();
+ type = NPVariantType_Object;
+ value.objectValue = NPN_RetainObject(new_value);
+}
+
+std::string CppVariant::ToString() const {
+ DCHECK(isString());
+ return std::string(value.stringValue.UTF8Characters,
+ value.stringValue.UTF8Length);
+}
+
+int32_t CppVariant::ToInt32() const {
+ if (isInt32()) {
+ return value.intValue;
+ } else if (isDouble()) {
+ return static_cast<int32_t>(value.doubleValue);
+ } else {
+ NOTREACHED();
+ return 0;
+ }
+}
+
+double CppVariant::ToDouble() const {
+ if (isInt32()) {
+ return static_cast<double>(value.intValue);
+ } else if (isDouble()) {
+ return value.doubleValue;
+ } else {
+ NOTREACHED();
+ return 0.0;
+ }
+}
+
+bool CppVariant::ToBoolean() const {
+ DCHECK(isBool());
+ return value.boolValue;
+}
+
+std::vector<std::wstring> CppVariant::ToStringVector() const {
+
+ DCHECK(isObject());
+ std::vector<std::wstring> wstring_vector;
+ NPObject* np_value = value.objectValue;
+ NPIdentifier length_id = NPN_GetStringIdentifier("length");
+
+ if (NPN_HasProperty(NULL, np_value, length_id)) {
+ NPVariant length_value;
+ if (NPN_GetProperty(NULL, np_value, length_id, &length_value)) {
+ int length = 0;
+ // The length is a double in some cases.
+ if (NPVARIANT_IS_DOUBLE(length_value))
+ length = static_cast<int>(NPVARIANT_TO_DOUBLE(length_value));
+ else if (NPVARIANT_IS_INT32(length_value))
+ length = NPVARIANT_TO_INT32(length_value);
+ // For sanity, only allow 100 items.
+ length = std::min(100, length);
+ for (int i = 0; i < length; ++i) {
+ // Get each of the items.
+ std::string index = StringPrintf("%d", i);
+ NPIdentifier index_id = NPN_GetStringIdentifier(index.c_str());
+ if (NPN_HasProperty(NULL, np_value, index_id)) {
+ NPVariant index_value;
+ if (NPN_GetProperty(NULL, np_value, index_id, &index_value) &&
+ NPVARIANT_IS_STRING(index_value)) {
+ std::string string(NPVARIANT_TO_STRING(index_value).UTF8Characters,
+ NPVARIANT_TO_STRING(index_value).UTF8Length);
+ wstring_vector.push_back(UTF8ToWide(string));
+ }
+ }
+ }
+ }
+ }
+ return wstring_vector;
+}