blob: cea4da17c96159c1799b6d0f8d2cade8823c7bef [file] [log] [blame]
/**
* 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_*/