Initial checkin of OOPHM plugins into trunk. Testing of non-XPCOM plugins
is still required, and more platforms need to be built.
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5868 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/common/Value.h b/plugins/common/Value.h
new file mode 100644
index 0000000..4401893
--- /dev/null
+++ b/plugins/common/Value.h
@@ -0,0 +1,387 @@
+#ifndef _H_Value
+#define _H_Value
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#ifndef _WINDOWS
+// TODO(jat): remove; for abort() which should probably go away
+#include <stdlib.h>
+#endif
+
+#include <string>
+
+#include "Debug.h"
+
+#include "BrowserChannel.h"
+
+class Value {
+public:
+ enum ValueType {
+ NULL_TYPE = VALUE_TYPE_NULL,
+ BOOLEAN = VALUE_TYPE_BOOLEAN,
+ BYTE = VALUE_TYPE_BYTE,
+ CHAR = VALUE_TYPE_CHAR,
+ SHORT = VALUE_TYPE_SHORT,
+ INT = VALUE_TYPE_INT,
+ LONG = VALUE_TYPE_LONG,
+ FLOAT = VALUE_TYPE_FLOAT,
+ DOUBLE = VALUE_TYPE_DOUBLE,
+ STRING = VALUE_TYPE_STRING,
+ JAVA_OBJECT = VALUE_TYPE_JAVA_OBJECT,
+ JS_OBJECT = VALUE_TYPE_JS_OBJECT,
+ UNDEFINED = VALUE_TYPE_UNDEFINED
+ };
+
+private:
+ ValueType type;
+ union {
+ bool boolValue;
+ unsigned char byteValue;
+ unsigned short charValue;
+ double doubleValue;
+ float floatValue;
+ int32_t intValue;
+ int64_t longValue;
+ short shortValue;
+ std::string* stringValue;
+ } value;
+
+public:
+ Value() {
+ type = UNDEFINED;
+ }
+
+ Value(const Value& other) {
+ copyValue(other);
+ }
+
+ Value& operator=(const Value& other) {
+ clearOldValue();
+ copyValue(other);
+ return *this;
+ }
+
+ ~Value() {
+ clearOldValue();
+ }
+
+ bool getBoolean() const {
+ assertType(BOOLEAN);
+ return value.boolValue;
+ }
+
+ unsigned char getByte() const {
+ assertType(BYTE);
+ return value.byteValue;
+ }
+
+ unsigned short getChar() const {
+ assertType(CHAR);
+ return value.charValue;
+ }
+
+ double getDouble() const {
+ assertType(DOUBLE);
+ return value.doubleValue;
+ }
+
+ float getFloat() const {
+ assertType(FLOAT);
+ return value.floatValue;
+ }
+
+ int getInt() const {
+ assertType(INT);
+ return value.intValue;
+ }
+
+ int getJavaObjectId() const {
+ assertType(JAVA_OBJECT);
+ return value.intValue;
+ }
+
+ int getJsObjectId() const {
+ assertType(JS_OBJECT);
+ return value.intValue;
+ }
+
+ int64_t getLong() const {
+ assertType(LONG);
+ return value.longValue;
+ }
+
+ short getShort() const {
+ assertType(SHORT);
+ return value.shortValue;
+ }
+
+ const std::string getString() const {
+ assertType(STRING);
+ return std::string(*value.stringValue);
+ }
+
+ ValueType getType() const {
+ return type;
+ }
+
+ bool isBoolean() const {
+ return type == BOOLEAN;
+ }
+
+ bool isByte() const {
+ return type == BYTE;
+ }
+
+ bool isChar() const {
+ return type == CHAR;
+ }
+
+ bool isDouble() const {
+ return type == DOUBLE;
+ }
+
+ bool isFloat() const {
+ return type == FLOAT;
+ }
+
+ bool isInt() const {
+ return type == INT;
+ }
+
+ bool isJavaObject() const {
+ return type == JAVA_OBJECT;
+ }
+
+ bool isJsObject() const {
+ return type == JS_OBJECT;
+ }
+
+ bool isLong() const {
+ return type == LONG;
+ }
+
+ bool isNull() const {
+ return type == NULL_TYPE;
+ }
+
+ bool isNumber() const {
+ switch (type) {
+ case BYTE:
+ case CHAR:
+ case DOUBLE:
+ case FLOAT:
+ case INT:
+ case LONG:
+ case SHORT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool isPrimitive() const {
+ switch (type) {
+ case BOOLEAN:
+ case BYTE:
+ case CHAR:
+ case DOUBLE:
+ case FLOAT:
+ case INT:
+ case LONG:
+ case SHORT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool isShort() const {
+ return type == SHORT;
+ }
+
+ bool isString() const {
+ return type == STRING;
+ }
+
+ bool isUndefined() const {
+ return type == UNDEFINED;
+ }
+
+ void setBoolean(bool val) {
+ clearOldValue();
+ type = BOOLEAN;
+ value.boolValue = val;
+ }
+
+ void setByte(unsigned char val) {
+ clearOldValue();
+ type = BYTE;
+ value.byteValue = val;
+ }
+
+ void setChar(unsigned short val) {
+ clearOldValue();
+ type = CHAR;
+ value.charValue = val;
+ }
+
+ void setDouble(double val) {
+ clearOldValue();
+ type = DOUBLE;
+ value.doubleValue = val;
+ }
+
+ void setFloat(float val) {
+ clearOldValue();
+ type = FLOAT;
+ value.floatValue = val;
+ }
+
+ void setInt(int val) {
+ clearOldValue();
+ type = INT;
+ value.intValue = val;
+ }
+
+ void setJavaObject(int objectId) {
+ clearOldValue();
+ type = JAVA_OBJECT;
+ value.intValue = objectId;
+ }
+
+ void setJsObjectId(int val) {
+ clearOldValue();
+ type = JS_OBJECT;
+ value.intValue = val;
+ }
+
+ void setLong(int64_t val) {
+ clearOldValue();
+ type = LONG;
+ value.longValue = val;
+ }
+
+ void setNull() {
+ clearOldValue();
+ type = NULL_TYPE;
+ }
+
+ void setShort(short val) {
+ clearOldValue();
+ type = SHORT;
+ value.shortValue = val;
+ }
+
+ void setString(const char* chars, int len) {
+ setString(std::string(chars, len));
+ }
+
+ void setString(const std::string& val) {
+ clearOldValue();
+ type = STRING;
+ value.stringValue = new std::string(val);
+ }
+
+ void setUndefined() {
+ clearOldValue();
+ type = UNDEFINED;
+ }
+
+ std::string toString() const {
+ char buf[30];
+ switch (type) {
+ case NULL_TYPE:
+ return "null";
+ case BOOLEAN:
+ snprintf(buf, sizeof(buf), "boolean(%s)", getBoolean() ? "true"
+ : "false");
+ return std::string(buf);
+ case BYTE:
+ snprintf(buf, sizeof(buf), "byte(%d)", getByte());
+ return std::string(buf);
+ case CHAR:
+ snprintf(buf, sizeof(buf), "char(%d)", getChar());
+ return std::string(buf);
+ case SHORT:
+ snprintf(buf, sizeof(buf), "short(%d)", getShort());
+ return std::string(buf);
+ case INT:
+ snprintf(buf, sizeof(buf), "int(%d)", getInt());
+ return std::string(buf);
+ case LONG:
+ snprintf(buf, sizeof(buf), "long(%lld)",
+ static_cast<long long>(getLong()));
+ return std::string(buf);
+ case FLOAT:
+ snprintf(buf, sizeof(buf), "float(%f)", getFloat());
+ return std::string(buf);
+ case DOUBLE:
+ snprintf(buf, sizeof(buf), "double(%lf)", getDouble());
+ return std::string(buf);
+ case STRING:
+ snprintf(buf, sizeof(buf), "string(%.20s)", getString().c_str());
+ return std::string(buf);
+ case JAVA_OBJECT:
+ snprintf(buf, sizeof(buf), "JavaObj(%d)", getJavaObjectId());
+ return std::string(buf);
+ case JS_OBJECT:
+ snprintf(buf, sizeof(buf), "JsObj(%d)", getJsObjectId());
+ return std::string(buf);
+ case UNDEFINED:
+ return "undefined";
+ default:
+ return "Unknown type";
+ }
+ }
+
+private:
+ void assertType(ValueType reqType) const {
+ if (type != reqType) {
+ Debug::log(Debug::Error) << "Value::assertType - expecting type "
+ << int(reqType) << ", was " << int(type) << Debug::flush;
+ // TODO(jat): is this portable? Should we do something else here?
+ abort();
+ }
+ }
+
+ void clearOldValue() {
+ if (type == STRING) {
+ delete value.stringValue;
+ type = UNDEFINED;
+ }
+ }
+
+ // Precondition: existing value, if any, has been cleared
+ void copyValue(const Value& other) {
+ type = other.type;
+ value = other.value;
+ // handle deep copies of value types that need it
+ switch (type) {
+ case STRING:
+ value.stringValue = new std::string(*value.stringValue);
+ break;
+ default:
+ // no other values need deep copies
+ break;
+ }
+ }
+};
+
+inline Debug::DebugStream& operator<<(Debug::DebugStream& dbg, const Value& val) {
+ return dbg << val.toString();
+}
+
+#endif