| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 ACTIVEMQ_UTIL_PRIMITIVEMAP_H_ |
| #define ACTIVEMQ_UTIL_PRIMITIVEMAP_H_ |
| |
| #include <string> |
| #include <activemq/util/Map.h> |
| |
| namespace activemq{ |
| namespace util{ |
| |
| /** |
| * Map of named primitives. |
| */ |
| class PrimitiveMap |
| { |
| public: |
| |
| /** |
| * Enumeration for the various primitive types. |
| */ |
| enum ValueTypeEnum{ |
| NULL_TYPE = 0, |
| BOOLEAN_TYPE = 1, |
| BYTE_TYPE = 2, |
| CHAR_TYPE = 3, |
| SHORT_TYPE = 4, |
| INTEGER_TYPE = 5, |
| LONG_TYPE = 6, |
| DOUBLE_TYPE = 7, |
| FLOAT_TYPE = 8, |
| STRING_TYPE = 9, |
| BYTE_ARRAY_TYPE = 10, |
| MAP_TYPE = 11, |
| LIST_TYPE = 12, |
| BIG_STRING_TYPE = 13 |
| }; |
| |
| /** |
| * Define a union type comprised of the various types. |
| */ |
| union Value { |
| |
| bool boolValue; |
| unsigned char byteValue; |
| char charValue; |
| short shortValue; |
| int intValue; |
| long long longValue; |
| double doubleValue; |
| float floatValue; |
| std::string* stringValue; |
| std::vector<unsigned char>* byteArrayValue; |
| }; |
| |
| /** |
| * Class that wraps around a single value of one of the |
| * many types. Manages memory for complex types, such |
| * as strings. Note: the destructor was left non-virtual |
| * so no virtual table will be created. This probaly isn't |
| * necessary, but will avoid needless memory allocation. Since |
| * we'll never extend this class, not having a virtual |
| * destructor isn't a concern. |
| */ |
| class ValueNode{ |
| private: |
| |
| ValueTypeEnum valueType; |
| Value value; |
| |
| public: |
| |
| ValueNode(){ |
| valueType = NULL_TYPE; |
| memset( &value, 0, sizeof(value) ); |
| } |
| |
| ValueNode( const ValueNode& node ){ |
| valueType = NULL_TYPE; |
| memset( &value, 0, sizeof(value) ); |
| (*this) = node; |
| } |
| |
| ~ValueNode(){ |
| clear(); |
| } |
| |
| ValueNode& operator =( const ValueNode& node ){ |
| clear(); |
| valueType = node.valueType; |
| |
| if( valueType == STRING_TYPE && node.value.stringValue != NULL ){ |
| value.stringValue = new std::string( *node.value.stringValue ); |
| } else if( valueType == BYTE_ARRAY_TYPE && node.value.byteArrayValue != NULL ){ |
| value.byteArrayValue = new std::vector<unsigned char>( *node.value.byteArrayValue ); |
| } else{ |
| value = node.value; |
| } |
| |
| return *this; |
| } |
| |
| bool operator==( const ValueNode& node ) const{ |
| |
| if( valueType != node.valueType ) { |
| return false; |
| } |
| |
| if( valueType == BOOLEAN_TYPE && |
| value.boolValue == node.value.boolValue ) { |
| return true; |
| } else if( valueType == BYTE_TYPE && |
| value.byteValue == node.value.byteValue ) { |
| return true; |
| } else if( valueType == CHAR_TYPE && |
| value.charValue == node.value.charValue ) { |
| return true; |
| } else if( valueType == SHORT_TYPE && |
| value.shortValue == node.value.shortValue ) { |
| return true; |
| } else if( valueType == INTEGER_TYPE && |
| value.intValue == node.value.intValue ) { |
| return true; |
| } else if( valueType == LONG_TYPE && |
| value.longValue == node.value.longValue ) { |
| return true; |
| } else if( valueType == DOUBLE_TYPE && |
| value.doubleValue == node.value.doubleValue ) { |
| return true; |
| } else if( valueType == FLOAT_TYPE && |
| value.floatValue == node.value.floatValue ) { |
| return true; |
| } else if( valueType == STRING_TYPE && |
| *value.stringValue == *node.value.stringValue ) { |
| return true; |
| } else if( valueType == BYTE_ARRAY_TYPE && |
| *value.byteArrayValue == *node.value.byteArrayValue ) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| ValueTypeEnum getValueType() const { return valueType; } |
| |
| void clear(){ |
| if( valueType == STRING_TYPE && value.stringValue != NULL ){ |
| delete value.stringValue; |
| } |
| if( valueType == BYTE_ARRAY_TYPE && value.byteArrayValue != NULL ){ |
| delete value.byteArrayValue; |
| } |
| valueType = NULL_TYPE; |
| memset( &value, 0, sizeof(value) ); |
| } |
| |
| void setBool( bool lvalue ){ |
| clear(); |
| valueType = BOOLEAN_TYPE; |
| value.boolValue = lvalue; |
| } |
| |
| bool getBool() const throw(activemq::exceptions::NoSuchElementException){ |
| if( valueType != BOOLEAN_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( __FILE__, |
| __LINE__, "Value is not BOOLEAN_TYPE" ); |
| } |
| |
| return value.boolValue; |
| } |
| |
| void setByte( unsigned char lvalue ){ |
| clear(); |
| valueType = BYTE_TYPE; |
| value.byteValue = lvalue; |
| } |
| |
| unsigned char getByte() const throw(activemq::exceptions::NoSuchElementException){ |
| if( valueType != BYTE_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( __FILE__, |
| __LINE__, "Value is not BYTE_TYPE" ); |
| } |
| |
| return value.byteValue; |
| } |
| |
| void setChar( char lvalue ){ |
| clear(); |
| valueType = CHAR_TYPE; |
| value.charValue = lvalue; |
| } |
| |
| char getChar() const throw(activemq::exceptions::NoSuchElementException){ |
| if( valueType != CHAR_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( __FILE__, |
| __LINE__, "Value is not CHAR_TYPE" ); |
| } |
| |
| return value.charValue; |
| } |
| |
| void setShort( short lvalue ){ |
| clear(); |
| valueType = SHORT_TYPE; |
| value.shortValue = lvalue; |
| } |
| |
| short getShort() const throw(activemq::exceptions::NoSuchElementException){ |
| if( valueType != SHORT_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( __FILE__, |
| __LINE__, "Value is not SHORT_TYPE" ); |
| } |
| |
| return value.shortValue; |
| } |
| |
| void setInt( int lvalue ){ |
| clear(); |
| valueType = INTEGER_TYPE; |
| value.intValue = lvalue; |
| } |
| |
| int getInt() const throw(activemq::exceptions::NoSuchElementException){ |
| if( valueType != INTEGER_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( __FILE__, |
| __LINE__, "Value is not INTEGER_TYPE" ); |
| } |
| |
| return value.intValue; |
| } |
| |
| void setLong( long long lvalue ){ |
| clear(); |
| valueType = LONG_TYPE; |
| value.longValue = lvalue; |
| } |
| |
| long long getLong() const throw(activemq::exceptions::NoSuchElementException){ |
| if( valueType != LONG_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( __FILE__, |
| __LINE__, "Value is not LONG_TYPE" ); |
| } |
| |
| return value.longValue; |
| } |
| |
| void setDouble( double lvalue ){ |
| clear(); |
| valueType = DOUBLE_TYPE; |
| value.doubleValue = lvalue; |
| } |
| |
| double getDouble() const throw(activemq::exceptions::NoSuchElementException){ |
| if( valueType != DOUBLE_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( __FILE__, |
| __LINE__, "Value is not DOUBLE_TYPE" ); |
| } |
| |
| return value.doubleValue; |
| } |
| |
| void setFloat( float lvalue ){ |
| clear(); |
| valueType = FLOAT_TYPE; |
| value.floatValue = lvalue; |
| } |
| |
| float getFloat() const throw(activemq::exceptions::NoSuchElementException){ |
| if( valueType != FLOAT_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( __FILE__, |
| __LINE__, "Value is not FLOAT_TYPE" ); |
| } |
| |
| return value.floatValue; |
| } |
| |
| void setString( const std::string& lvalue ){ |
| clear(); |
| valueType = STRING_TYPE; |
| value.stringValue = new std::string( lvalue ); |
| } |
| |
| std::string getString() const throw(activemq::exceptions::NoSuchElementException){ |
| if( valueType != STRING_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( __FILE__, |
| __LINE__, "Value is not STRING_TYPE" ); |
| } |
| |
| if( value.stringValue == NULL ){ |
| return std::string(); |
| } |
| |
| return *value.stringValue; |
| } |
| |
| void setByteArray( const std::vector<unsigned char>& lvalue ){ |
| clear(); |
| valueType = BYTE_ARRAY_TYPE; |
| value.byteArrayValue = new std::vector<unsigned char>( lvalue ); |
| } |
| |
| std::vector<unsigned char> getByteArray() const throw( activemq::exceptions::NoSuchElementException ) { |
| |
| if( valueType != BYTE_ARRAY_TYPE ){ |
| throw activemq::exceptions::NoSuchElementException( |
| __FILE__, |
| __LINE__, |
| "Value is not BYTE_ARRAY_TYPE" ); |
| } |
| |
| if( value.byteArrayValue == NULL ){ |
| return std::vector<unsigned char>(); |
| } |
| |
| return *value.byteArrayValue; |
| } |
| |
| std::string toString() const { |
| std::ostringstream stream; |
| |
| if( valueType == BOOLEAN_TYPE ) { |
| stream << value.boolValue; |
| } else if( valueType == BYTE_TYPE ) { |
| stream << value.byteValue; |
| } else if( valueType == CHAR_TYPE ) { |
| stream << value.charValue; |
| } else if( valueType == SHORT_TYPE ) { |
| stream << value.shortValue; |
| } else if( valueType == INTEGER_TYPE ) { |
| stream << value.intValue; |
| } else if( valueType == LONG_TYPE ) { |
| stream << value.longValue; |
| } else if( valueType == DOUBLE_TYPE ) { |
| stream << value.doubleValue; |
| } else if( valueType == FLOAT_TYPE ) { |
| stream << value.floatValue; |
| } else if( valueType == STRING_TYPE ) { |
| stream << *value.stringValue; |
| } else if( valueType == BYTE_ARRAY_TYPE ) { |
| std::vector<unsigned char>::const_iterator iter = |
| value.byteArrayValue->begin(); |
| for( ; iter != value.byteArrayValue->end(); ++iter ) { |
| stream << '[' << (int)(*iter) << ']'; |
| } |
| } |
| |
| return stream.str(); |
| } |
| |
| }; |
| |
| |
| private: |
| |
| activemq::util::Map<std::string, ValueNode> valueNodeMap; |
| |
| public: |
| |
| PrimitiveMap(); |
| virtual ~PrimitiveMap(); |
| |
| /** |
| * Copy Constructor |
| * @param map - the PrimitiveMap to copy |
| */ |
| PrimitiveMap( const PrimitiveMap& src ); |
| |
| /** |
| * Compares this PrimitiveMap to another |
| * @param source - Map to compare to |
| * @return true if the maps are equeal |
| */ |
| bool equals( const PrimitiveMap& source ) const; |
| |
| /** |
| * Converts the contents into a formatted string that can be output |
| * in a Log File or other debugging tool. |
| * @returns formatted String of all elements in the map. |
| */ |
| std::string toString() const; |
| |
| /** |
| * Comparison Operator |
| * @param src - Map to compare to this one. |
| * @returns true if Maps are equal. |
| */ |
| void copy( const PrimitiveMap& src ); |
| |
| /** |
| * Removes all keys and values from all maps. |
| */ |
| virtual void clear(); |
| |
| /** |
| * Indicates whether or this map contains a value for the |
| * given key. |
| * @param key The key to look up. |
| * @return true if this map contains the value, otherwise false. |
| */ |
| virtual bool contains( const std::string& key ) const; |
| |
| /** |
| * @return The number of elements (key/value pairs) in this map. |
| */ |
| virtual std::size_t size() const; |
| |
| /** |
| * @returns if there are any entries in the map. |
| */ |
| virtual bool isEmpty() const; |
| |
| virtual bool getBool( const std::string& key ) const |
| throw(activemq::exceptions::NoSuchElementException); |
| virtual void setBool( const std::string& key, bool value ); |
| |
| virtual unsigned char getByte( const std::string& key ) const |
| throw(activemq::exceptions::NoSuchElementException); |
| virtual void setByte( const std::string& key, unsigned char value ); |
| |
| virtual char getChar( const std::string& key ) const |
| throw(activemq::exceptions::NoSuchElementException); |
| virtual void setChar( const std::string& key, char value ); |
| |
| virtual short getShort( const std::string& key ) const |
| throw(activemq::exceptions::NoSuchElementException); |
| virtual void setShort( const std::string& key, short value ); |
| |
| virtual int getInt( const std::string& key ) const |
| throw(activemq::exceptions::NoSuchElementException); |
| virtual void setInt( const std::string& key, int value ); |
| |
| virtual long long getLong( const std::string& key ) const |
| throw(activemq::exceptions::NoSuchElementException); |
| virtual void setLong( const std::string& key, long long value ); |
| |
| virtual double getDouble( const std::string& key ) const |
| throw(activemq::exceptions::NoSuchElementException); |
| virtual void setDouble( const std::string& key, double value ); |
| |
| virtual float getFloat( const std::string& key ) const |
| throw(activemq::exceptions::NoSuchElementException); |
| virtual void setFloat( const std::string& key, float value ); |
| |
| virtual std::string getString( const std::string& key ) const |
| throw(activemq::exceptions::NoSuchElementException); |
| virtual void setString( const std::string& key, const std::string& value ); |
| |
| virtual std::vector<unsigned char> getByteArray( const std::string& key ) const |
| throw( activemq::exceptions::NoSuchElementException ); |
| virtual void setByteArray( const std::string& key, const std::vector<unsigned char>& value ); |
| |
| /** |
| * Removes the value (key/value pair) for the specified key from |
| * the map. |
| * @param key The search key. |
| */ |
| virtual void remove( const std::string& key ); |
| |
| /** |
| * @return the entire set of keys in this map as a std::vector. |
| */ |
| virtual std::vector<std::string> getKeys() const; |
| |
| /** |
| * @return the entire set of values in this map as a std::vector. |
| */ |
| virtual std::vector<ValueNode> getValues() const; |
| |
| /** |
| * Get a Value from the Map, or throws a NoSuchElementException |
| * @param key - string key to lookup |
| * @returns the concrete Value |
| * @throws NoSuchElementException |
| */ |
| ValueNode getValue( const std::string& key ) const |
| throw( activemq::exceptions::NoSuchElementException ); |
| |
| }; |
| |
| }} |
| |
| #endif /*ACTIVEMQ_UTIL_PRIMITIVEMAP_H_*/ |