diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:20:51 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:20:51 +0000 |
commit | f5b16fed647e941aa66933178da85db2860d639b (patch) | |
tree | f00e9856c04aad3b558a140955e7674add33f051 /webkit/glue/cpp_variant.cc | |
parent | 920c091ac3ee15079194c82ae8a7a18215f3f23c (diff) | |
download | chromium_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.cc | 276 |
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; +} |