#ifndef __XIOS_ENUM_REF_IMPL__ #define __XIOS_ENUM_REF_IMPL__ #include "xios_spl.hpp" #include "exception.hpp" #include "buffer_in.hpp" #include "buffer_out.hpp" #include "message.hpp" #include #include namespace xios { using namespace std; template CEnum_ref::CEnum_ref(void) { empty=true ; } template CEnum_ref::CEnum_ref(T_enum& val) { empty=true ; set_ref(val) ; } template CEnum_ref::CEnum_ref(CEnum& type) { empty=true ; set_ref(type) ; } template CEnum_ref::CEnum_ref(const CEnum_ref& type) { empty=true ; set_ref(type) ; } template void CEnum_ref::set_ref(T_enum& val) { ptrValue=&val ; empty=false ; } template void CEnum_ref::set_ref(CEnum& type) { ptrValue=&type.get() ; empty=false ; } template void CEnum_ref::set_ref(const CEnum_ref& type) { ptrValue=type.ptrValue ; empty=type.empty ; } template void CEnum_ref::set(const T_enum& val) const { checkEmpty() ; *ptrValue=val ; } template void CEnum_ref::set(const CEnum& type) const { checkEmpty() ; *ptrValue=type.get() ; } template void CEnum_ref::set(const CEnum_ref& type) const { checkEmpty() ; *ptrValue=type.get() ; } template typename T::t_enum & CEnum_ref::get(void) const { checkEmpty() ; return *ptrValue ; } template const CEnum_ref& CEnum_ref::operator = (T_enum& val) const { set(val) ; return *this ; } template const CEnum_ref& CEnum_ref::operator = (CEnum& type) const { set(type) ; return *this ; } template const CEnum_ref& CEnum_ref::operator = (const CEnum_ref& type) const { set(type) ; return *this ; } template CEnum_ref::operator T_enum&() const { checkEmpty() ; return *ptrValue ; } template CEnum_ref* CEnum_ref::_clone(void) const { checkEmpty() ; return new CEnum_ref(*this) ; } template void CEnum_ref::_fromString(const string& str) const { istringstream iss(str); checkEmpty() ; iss>>*ptrValue ; } template void CEnum_ref::_fromString(const string& str) { checkEmpty() ; string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ; bool found=false ; for(int i=0;i0) strList<<", " ; strList< void CEnum_ref::_fromString(const string& str)", << tmpStr << " cannot be converted in a valid enumeration, possibilities are: " << strList.str()); } template string CEnum_ref::_toString(void) const { if (empty) return string("empty"); return string((T::getStr())[(int)(*ptrValue)]) ; } template bool CEnum_ref::_toBuffer(CBufferOut& buffer) const { checkEmpty() ; if (sizeof(*ptrValue)==sizeof(short int)) return buffer.put((short int) *ptrValue) ; else if (sizeof(*ptrValue)==sizeof(int)) return buffer.put((int) *ptrValue) ; else if (sizeof(*ptrValue)==sizeof(long int)) return buffer.put((long int) *ptrValue) ; else ERROR("template bool CEnum_ref::_toBuffer(CBufferOut& buffer) const", << "incompatibility between enumeration and standard integer type."); return false ; } template bool CEnum_ref::_fromBuffer(CBufferIn& buffer) { checkEmpty() ; bool ret ; if (sizeof(*ptrValue)==sizeof(short int)) { short int val ; ret=buffer.get(val) ; if (ret) *ptrValue = (T_enum) val ; } else if (sizeof(*ptrValue)==sizeof(int)) { int val ; ret=buffer.get(val) ; if (ret) *ptrValue = (T_enum) val ; } else if (sizeof(*ptrValue)==sizeof(long int)) { long int val ; ret=buffer.get(val) ; if (ret) *ptrValue = (T_enum) val ; } else ERROR("template bool CEnum_ref::_fromBuffer(CBufferIn& buffer)", << "incompatibility between enumeration and standard integer type."); return ret ; } template bool CEnum_ref::_fromBuffer(CBufferIn& buffer) const { checkEmpty() ; bool ret ; if (sizeof(*ptrValue)==sizeof(short int)) { short int val ; ret=buffer.get(val) ; if (ret) *ptrValue = (T_enum) val ; } else if (sizeof(*ptrValue)==sizeof(int)) { int val ; ret=buffer.get(val) ; if (ret) *ptrValue = (T_enum) val ; } else if (sizeof(*ptrValue)==sizeof(long int)) { long int val ; ret=buffer.get(val) ; if (ret) *ptrValue = (T_enum) val ; } else ERROR("template bool CEnum_ref::_fromBuffer(CBufferIn& buffer)", << "incompatibility between enumeration and standard integer type"); } template size_t CEnum_ref::_size(void) const { return sizeof(T_enum) ; } template bool CEnum_ref::_isEmpty(void) const { return empty ; } template void CEnum_ref::_reset(void) { empty=true ; } template void CEnum_ref::checkEmpty(void) const { if (empty) ERROR("template void CEnum_ref::checkEmpty(void)", << "Enum reference is not initialized.") ; } template bool operator== (const CEnum_ref& lhs, const typename T::t_enum& rhs) { if (lhs.isEmpty()) return false; return (lhs.get() == rhs); } template bool operator== (const typename T::t_enum& lhs, const CEnum_ref& rhs) { return rhs == lhs; } template bool operator== (const CEnum_ref& lhs, const CEnum_ref& rhs) { if ((lhs.isEmpty() && !rhs.isEmpty()) || (!lhs.isEmpty() && rhs.isEmpty())) return false; if (lhs.isEmpty() && rhs.isEmpty()) return true; return (lhs.get() == rhs.get()); } template CBufferOut& operator<<(CBufferOut& buffer, const CEnum_ref& type) { if (!type.toBuffer(buffer)) ERROR("template CBufferOut& operator<<(CBufferOut& buffer, const CEnum_ref& type)", << "Not enough free space in buffer to queue the enum."); return buffer ; } template CBufferOut& operator<<(CBufferOut& buffer, typename T::t_enum& type) { if (!CEnum_ref(type).toBuffer(buffer)) ERROR("template CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum& type)", << "Not enough free space in buffer to queue the enum."); return buffer ; } template CBufferIn& operator>>(CBufferIn& buffer, typename T::t_enum& type) { if (!CEnum_ref(type).fromBuffer(buffer)) ERROR("template CBufferIn& operator>>(CBufferIn& buffer, typename T::t_enum& type)", << "Not enough data in buffer to unqueue the enum."); return buffer ; } template CBufferIn& operator>>(CBufferIn& buffer, const CEnum_ref& type) { if (!type.fromBuffer(buffer)) ERROR("template CBufferIn& operator>>(CBufferIn& buffer, const CEnum_ref& type) ", << "Not enough data in buffer to unqueue the enum."); return buffer ; return buffer ; } /* template CMessage& operator<<(CMessage& msg, const CEnum_ref& type) { msg.push(*type.clone()) ; return msg ; } */ template CMessage& operator<<(CMessage& msg, typename T::t_enum & type) { msg.push(*CEnum_ref(type).clone()) ; return msg ; } } #endif