/*************************************************************** * * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department, * University of Wisconsin-Madison, WI. * * 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 __CLASSAD_VALUE_H__ #define __CLASSAD_VALUE_H__ #include "classad/common.h" #include "classad/util.h" BEGIN_NAMESPACE( classad ) class Literal; class ExprList; class ClassAd; /// Represents the result of an evaluation. class Value { public: /// Value types enum ValueType { NULL_VALUE = 0, /** The error value */ ERROR_VALUE = 1<<0, /** The undefined value */ UNDEFINED_VALUE = 1<<1, /** A boolean value (false, true)*/ BOOLEAN_VALUE = 1<<2, /** An integer value */ INTEGER_VALUE = 1<<3, /** A real value */ REAL_VALUE = 1<<4, /** A relative time value */ RELATIVE_TIME_VALUE = 1<<5, /** An absolute time value */ ABSOLUTE_TIME_VALUE = 1<<6, /** A string value */ STRING_VALUE = 1<<7, /** A classad value */ CLASSAD_VALUE = 1<<8, /** An expression list value */ LIST_VALUE = 1<<9 }; /// Number factors enum NumberFactor { /** No factor specified */ NO_FACTOR= 0, /** Byte factor */ B_FACTOR = 1, /** Kilo factor */ K_FACTOR = 2, /** Mega factor */ M_FACTOR = 3, /** Giga factor */ G_FACTOR = 4, /** Terra factor*/ T_FACTOR = 5 }; /// Values of number multiplication factors static const double ScaleFactor[]; /// Constructor Value(); /// Copy Constructor Value(const Value &value); /// Destructor ~Value(); /// Assignment operator Value& operator=(const Value &value); /** Discards the previous value and sets the value to UNDEFINED */ void Clear (void); /** Copies the value of another value object. @param v The value copied from. */ void CopyFrom( const Value &v ); /** Sets a boolean value; previous value discarded. @param b The boolean value. */ void SetBooleanValue(bool b); /** Sets a real value; previous value discarded. @param r The real value. */ void SetRealValue(double r); /** Sets an integer value; previous value discarded. @param i The integer value. */ void SetIntegerValue(int i); /** Sets the undefined value; previous value discarded. */ void SetUndefinedValue(void); /** Sets the error value; previous value discarded. */ void SetErrorValue(void); /** Sets an expression list value; previous value discarded. You still own the ExprList:: it is not owned by the Value class, so it is your responsibility to delete it. @param l The list value. */ void SetListValue(ExprList* l); /** Sets a ClassAd value; previous value discarded. You still own the ClassA:, it is not owned by the Value class, so it is your responsibility to delete it. @param c The ClassAd value. */ void SetClassAdValue(ClassAd* c); /** Sets a string value; previous value discarded. @param str The string value. */ void SetStringValue( const std::string &str ); /** Sets a string value; previous value discarded. The string is copied so you may feel free to delete the original if you wish. @param str The string value. */ void SetStringValue( const char *str ); /** Sets an absolute time value in seconds since the UNIX epoch, & the time zone it's measured in. @param secs - Absolute Time Literal(seconds since the UNIX epoch, timezone offset) . */ void SetAbsoluteTimeValue( abstime_t secs ); /** Sets a relative time value. @param secs Number of seconds. */ void SetRelativeTimeValue( time_t secs ); void SetRelativeTimeValue( double secs ); /** Gets the type of the value. @return The value type. @see ValueType */ inline ValueType GetType() const { return valueType; } /** Checks if the value is boolean. @param b The boolean value if the value is boolean. @return true iff the value is boolean. */ inline bool IsBooleanValue(bool& b) const; /** Checks if the value is boolean. @return true iff the value is boolean. */ inline bool IsBooleanValue() const; /** Checks if the value is boolean or something considered equivalent by implicit conversion (e.g. a number), if old ClassAd evaluation semantics are being used. If they're not being used, this method behaves like IsBooleanValue(). @param b The boolean value if return is true. @return true iff the value is boolean or equivalent */ bool IsBooleanValueEquiv(bool &b) const; /** Checks if the value is integral. @param i The integer value if the value is integer. @return true iff the value is an integer. */ inline bool IsIntegerValue(int &i) const; /** Checks if the value is integral. @return true iff the value is an integer. */ inline bool IsIntegerValue() const; /** Checks if the value is real. @param r The real value if the value is real. @return true iff the value is real. */ inline bool IsRealValue(double &r) const; /** Checks if the value is real. @return true iff the value is real. */ inline bool IsRealValue() const; /** Checks if the value is a string. @param str A reference to a string object, which is filled with the string value. @return true iff the value is a string. */ bool IsStringValue( std::string &str ) const; /** Checks if the value is a string. @param str A reference to a C string, which will point to the string value. This pointer must not be deallocated or tampered with. @return true iff the value is a string. */ bool IsStringValue( const char *&str ) const; /** Checks if the value is a string and provides a copy of it in a buffer you provide @param str A buffer to hold the string value. @param len The size of the buffer. @return true iff the value is a string. */ bool IsStringValue( char *str, int len ) const; /** Returns length of the string instead of the string @param size This is filled in with the size of the string @return true iff the value is string. */ inline bool IsStringValue( int &size ) const; /** Checks if the value is a string. @return true iff the value is string. */ inline bool IsStringValue() const; /** Checks if the value is an expression list. @param l The expression list if the value is an expression list. @return true iff the value is an expression list. */ inline bool IsListValue(const ExprList*& l) const; /** Checks if the value is an expression list. The ExprList returned is the original list put into the ClassAd, so you only own it if you own the original. @param l The expression list if the value is an expression list. @return true iff the value is an expression list. */ inline bool IsListValue(ExprList*& l); /** Checks if the value is an expression list. The ExprList returned is the original list put into the ClassAd, so you only own it if you own the original. @return true iff the value is an expression list. */ inline bool IsListValue() const; /** Checks if the value is a ClassAd. @param c The ClassAd if the value is a ClassAd. @return true iff the value is a ClassAd. */ inline bool IsClassAdValue(const ClassAd *&c) const; /** Checks if the value is a ClassAd. The ClassAd returned is the original list put into the ClassAd, so you only own it if you own the original. @param c The ClassAd if the value is a ClassAd. @return true iff the value is a ClassAd. */ inline bool IsClassAdValue(ClassAd *&c); /** Checks if the value is a ClassAd. @return true iff the value is a ClassAd value. */ inline bool IsClassAdValue() const; /** Checks if the value is the undefined value. @return true iff the value if the undefined value. */ inline bool IsUndefinedValue() const; /** Checks if the value is the error value. @return true iff the value if the error value. */ inline bool IsErrorValue() const; /** Checks if the value is exceptional. @return true iff the value is either undefined or error. */ inline bool IsExceptional() const; /** Checks if the value is numerical. @return true iff the value is a number */ bool IsNumber () const; /** Checks if the value is numerical. If the value is a real, it is converted to an integer through truncation. @param i The integer value of the value if the value is a number. @return true iff the value is a number */ bool IsNumber (int &i) const; /** Checks if the value is numerical. If the value is an integer, it is promoted to a real. @param r The real value of the value if the value is a number. @return true iff the value is a number */ bool IsNumber (double &r) const; /** Checks if the value is an absolute time value. @return true iff the value is an absolute time value. */ bool IsAbsoluteTimeValue( ) const; /** Checks if the value is an absolute time value. @param secs - Absolute time literal (Number of seconds since the UNIX epoch,timezone offset). @return true iff the value is an absolute time value. */ bool IsAbsoluteTimeValue( abstime_t& secs ) const; /** Checks if the value is a relative time value. @return true iff the value is a relative time value */ bool IsRelativeTimeValue( ) const; /** Checks if the value is a relative time value. @param secs Number of seconds @return true iff the value is a relative time value */ bool IsRelativeTimeValue( double& secs ) const; bool IsRelativeTimeValue( time_t& secs ) const; bool SameAs(const Value &otherValue) const; friend bool operator==(const Value &value1, const Value &value2); friend std::ostream& operator<<(std::ostream &stream, Value &value); private: friend class Literal; friend class ClassAd; friend class ExprTree; ValueType valueType; // the type of the value union { bool booleanValue; int integerValue; double realValue; ExprList *listValue; ClassAd *classadValue; double relTimeValueSecs; abstime_t absTimeValueSecs; }; std::string strValue; // has ctor/dtor cannot be in the union }; bool convertValueToRealValue(const Value value, Value &realValue); bool convertValueToIntegerValue(const Value value, Value &integerValue); bool convertValueToStringValue(const Value value, Value &stringValue); // implementations of the inlined functions inline bool Value:: IsBooleanValue( bool& b ) const { b = booleanValue; return( valueType == BOOLEAN_VALUE ); } inline bool Value:: IsBooleanValue() const { return( valueType == BOOLEAN_VALUE ); } inline bool Value:: IsIntegerValue (int &i) const { i = integerValue; return (valueType == INTEGER_VALUE); } inline bool Value:: IsIntegerValue () const { return (valueType == INTEGER_VALUE); } inline bool Value:: IsRealValue (double &r) const { r = realValue; return (valueType == REAL_VALUE); } inline bool Value:: IsRealValue () const { return (valueType == REAL_VALUE); } inline bool Value:: IsListValue( const ExprList *&l) const { if (valueType == LIST_VALUE) { l = listValue; return true; } else { return false; } } inline bool Value:: IsListValue( ExprList *&l) { if (valueType == LIST_VALUE) { l = listValue; return true; } else { return false; } } inline bool Value:: IsListValue () const { return (valueType == LIST_VALUE); } inline bool Value:: IsStringValue() const { return (valueType == STRING_VALUE); } inline bool Value:: IsStringValue( const char *&s ) const { // We want to be careful not to copy it in here. // People may accumulate in the "s" after this call, // So it best to only touch it if it exists. // (Example: the strcat classad function) if (valueType == STRING_VALUE) { s = strValue.c_str( ); return true; } else { return false; } } inline bool Value:: IsStringValue( char *s, int len ) const { if( valueType == STRING_VALUE ) { strncpy( s, strValue.c_str( ), len ); return( true ); } return( false ); } inline bool Value:: IsStringValue( std::string &s ) const { if ( valueType == STRING_VALUE ) { s = strValue; return true; } else { return false; } } inline bool Value:: IsStringValue( int &size ) const { if (valueType == STRING_VALUE) { size = strValue.size(); return true; } else { size = -1; return false; } } inline bool Value:: IsClassAdValue(const ClassAd *&ad) const { if ( valueType == CLASSAD_VALUE ) { ad = classadValue; return true; } else { return false; } } inline bool Value:: IsClassAdValue(ClassAd *&ad) { if ( valueType == CLASSAD_VALUE ) { ad = classadValue; return true; } else { return false; } } inline bool Value:: IsClassAdValue() const { return( valueType == CLASSAD_VALUE ); } inline bool Value:: IsUndefinedValue (void) const { return (valueType == UNDEFINED_VALUE); } inline bool Value:: IsErrorValue(void) const { return (valueType == ERROR_VALUE); } inline bool Value:: IsExceptional(void) const { return( valueType == UNDEFINED_VALUE || valueType == ERROR_VALUE ); } inline bool Value:: IsAbsoluteTimeValue( ) const { return( valueType == ABSOLUTE_TIME_VALUE ); } inline bool Value:: IsAbsoluteTimeValue( abstime_t &secs ) const { secs = absTimeValueSecs; return( valueType == ABSOLUTE_TIME_VALUE ); } inline bool Value:: IsRelativeTimeValue( ) const { return( valueType == RELATIVE_TIME_VALUE ); } inline bool Value:: IsRelativeTimeValue( double &secs ) const { secs = relTimeValueSecs; return( valueType == RELATIVE_TIME_VALUE ); } inline bool Value:: IsRelativeTimeValue( time_t &secs ) const { secs = (int) relTimeValueSecs; return( valueType == RELATIVE_TIME_VALUE ); } inline bool Value:: IsNumber( ) const { return( valueType==INTEGER_VALUE || valueType==REAL_VALUE ); } END_NAMESPACE // classad #endif//__CLASSAD_VALUE_H__