#ifndef __XIOS_ENUM_IMPL__ #define __XIOS_ENUM_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::CEnum(void) { empty=true ; } template CEnum::CEnum(const T_enum& val) { empty=true ; set(val) ; } template CEnum::CEnum(const CEnum& type) { empty=true ; set(type) ; } template CEnum::CEnum(const CEnum_ref& type) { empty=true ; set(type) ; } template void CEnum::set(const T_enum& val) { if (empty) { ptrValue = new T_enum(val) ; empty=false ; } else *ptrValue = val ; } template void CEnum::set(const CEnum& type) { if (type.isEmpty()) reset() ; else { if (empty) { ptrValue = new T_enum(*type.ptrValue) ; empty=false ; } else *ptrValue = *type.ptrValue ; } } template void CEnum::set(const CEnum_ref& type) { if (type.isEmpty()) reset() ; else { if (empty) { ptrValue = new T_enum(*type.ptrValue) ; empty=false ; } else *ptrValue = *type.ptrValue ; } } template typename T::t_enum & CEnum::get(void) { checkEmpty(); return *ptrValue ; } template const typename T::t_enum& CEnum::get(void) const { checkEmpty(); return *ptrValue ; } template CEnum& CEnum::operator = (const T_enum& val) { set(val) ; return *this ; } template CEnum& CEnum::operator = (const CEnum& type) { set(type) ; return *this ; } template CEnum& CEnum::operator = (const CEnum_ref& type) { set(type) ; return *this ; } template CEnum::operator T_enum&() { checkEmpty(); return *ptrValue ; } template CEnum* CEnum::_clone(void) const { checkEmpty(); return new CEnum(*this) ; } template void CEnum::_fromString(const string& str) { string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ; bool found=false ; for(int i=0;i0) strList<<", " ; strList< void CEnum::_fromString(const string& str)", << tmpStr << " cannot be converted in a valid enumeration, possibilities are: " << strList.str()); } template size_t CEnum::_size(void) const { return sizeof(T_enum) ; } template bool CEnum::_isEmpty(void) const { return empty ; } template string CEnum::_toString(void) const { if (empty) return string("empty") ; return string((T::getStr())[(int)(*ptrValue)]) ; } template bool CEnum::_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::_toBuffer(CBufferOut& buffer) const", << "incompatibility between enumeration and standard integer type."); return false ; } template bool CEnum::_fromBuffer(CBufferIn& buffer) { bool ret ; allocate() ; 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::_fromBuffer(CBufferIn& buffer)", << "incompatibility between enumeration and standard integer type."); return ret ; } template void CEnum::allocate(void) { if (empty) { ptrValue = new T_enum ; empty=false ; } } template void CEnum::_reset(void) { if (!empty) { delete ptrValue ; empty=true ; } } template void CEnum::checkEmpty(void) const { if (empty) ERROR("template void CEnum::checkEmpty(void) const", << "Enum is not initialized."); } template CBufferOut& operator<<(CBufferOut& buffer, const CEnum& type) { if (!type.toBuffer(buffer)) ERROR("template CBufferOut& operator<<(CBufferOut& buffer, const CEnum& type)", << "Not enough free space in buffer to queue the enum."); return buffer ; } template CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type) { if (!CEnum(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, CEnum& type) { if (!type.fromBuffer(buffer)) ERROR("template CBufferIn& operator>>(CBufferIn& buffer, CEnum& type)", << "Not enough data in buffer to unqueue the enum."); return buffer ; } /* template CMessage& operator<<(CMessage& msg, const CEnum& type) { msg.push(*type.clone()) ; return msg ; } */ template CMessage& operator<<(CMessage& msg, const typename T::t_enum & type) { msg.push(*CEnum(type).clone()) ; return msg ; } } #endif