//****************************************************************************** // RCF - Remote Call Framework // Copyright (c) 2005 - 2007. All rights reserved. // Consult your license for conditions of use. // Developed by Jarl Lindrud. // Contact: jlindrud@hotmail.com . //****************************************************************************** #ifndef INCLUDE_SF_ENCODING_HPP #define INCLUDE_SF_ENCODING_HPP #include #include #include #include namespace SF { class Text; class BinaryNative; class BinaryPortable; static char chSeparator = ':'; //************************************************************************** // countElements() template inline UInt32 countTypedElements( BinaryNative *, T *, DataPtr &data) { RCF_ASSERT(data.length() % sizeof(T) == 0); return data.length() / sizeof(T); } template inline UInt32 countTypedElements( BinaryPortable *, T *, DataPtr &data) { RCF_ASSERT(data.length() % sizeof(T) == 0); return data.length() / sizeof(T); } template inline UInt32 countTypedElements( Text *, T *, DataPtr &data) { // Count number of internally occurring separators in the data, and then add 1 UInt32 count = 0; for (UInt32 i=1; i inline UInt32 countElements( E *, DataPtr &data, const std::type_info &objType) { SF_FOR_EACH_FUNDAMENTAL_TYPE( SF_TRY_COUNT_ELEMENTS ); RCF_ASSERT(0)(objType); return 0; } #undef SF_TRY_COUNT_ELEMENTS //************************************************************************** // encodeTypedElements()/decodeTypedElements() // TODO: precision issues when encoding/decoding floating point values? template inline void encodeTypedElements( Text *, T *, DataPtr &data, T *t, int nCount) { std::ostringstream ostr; ostr << t[0]; for (int i=1; i(s.c_str()), static_cast(s.length())); } template inline void decodeTypedElements( Text *, T *, DataPtr &data, T *t, int nCount) { if (data.length() == 0) { RCF_THROW(RCF::Exception(RCF::SfError_DataFormat)); } std::string strData(reinterpret_cast(data.get()), data.length()); std::istringstream istr(strData); istr >> t[0]; for (int i=1; i> t[i]; } } inline void encodeTypedElements( Text *, char *, DataPtr &data, char *t, int nCount) { data.assign(reinterpret_cast(t), nCount); } inline void decodeTypedElements( Text *, char *, DataPtr &data, char *t, int nCount) { memcpy(t, data.get(), nCount); } inline void encodeTypedElements( Text *, unsigned char *, DataPtr &data, unsigned char *t, int nCount) { data.assign(reinterpret_cast(t), nCount); } inline void decodeTypedElements( Text *, unsigned char *, DataPtr &data, unsigned char *t, int nCount) { memcpy(t, data.get(), nCount); } inline void encodeTypedElements( Text *, wchar_t *, DataPtr &data, wchar_t *t, int nCount) { data.assign(reinterpret_cast(t), nCount*sizeof(wchar_t)); } inline void decodeTypedElements( Text *, wchar_t *, DataPtr &data, wchar_t *t, int nCount) { memcpy(t, data.get(), nCount*sizeof(wchar_t)); } template inline void encodeTypedElements( BinaryNative *, T *, DataPtr &data, T *t, int nCount) { data.assign(reinterpret_cast(t), sizeof(T)*nCount ); } template inline void decodeTypedElements( BinaryNative *, T *, DataPtr &data, T *t, int nCount) { RCF_ASSERT( data.length() == sizeof(T)*nCount); memcpy(t, data.get(), sizeof(T)*nCount); } template inline void encodeTypedElements( BinaryPortable *, T *, DataPtr &data, T *t, int nCount) { UInt32 nBufferSize = sizeof(T) * nCount; UInt32 nAlloc = data.allocate(nBufferSize); RCF_ASSERT(nAlloc == nBufferSize); T *buffer = reinterpret_cast(data.get()); memcpy(buffer, t, nBufferSize); RCF::machineToNetworkOrder(buffer, sizeof(T), nCount); } template inline void decodeTypedElements( BinaryPortable *, T *, DataPtr &data, T *t, int nCount) { if (data.length() != sizeof(T)*nCount) { RCF_THROW(RCF::Exception(RCF::SfError_DataFormat))(data.length())(nCount)(typeid(T).name()); } T *buffer = reinterpret_cast(data.get()); RCF::networkToMachineOrder(buffer, sizeof(T), nCount); memcpy(t, buffer, nCount*sizeof(T)); } //************************************************************************** // encodeElements()/decodeElements() #define SF_TRY_ENCODE_ELEMENTS(type) \ if (objType == typeid(type)) \ { \ encodeTypedElements( \ (Encoding *) 0, \ (type *) 0, \ data, \ static_cast(pvObject), \ nCount); \ return; \ } template inline void encodeElements( Encoding *, DataPtr &data, void *pvObject, const std::type_info &objType, int nCount) { SF_FOR_EACH_FUNDAMENTAL_TYPE( SF_TRY_ENCODE_ELEMENTS ); RCF_ASSERT(0)(objType); } #undef SF_TRY_ENCODE_ELEMENTS #define SF_TRY_DECODE_ELEMENTS(type) \ if (objType == typeid(type)) \ { \ decodeTypedElements( \ (Encoding *) 0, \ (type *) 0, \ data, \ static_cast(pvObject), \ nCount); \ return; \ } template inline void decodeElements( Encoding *, DataPtr &data, void *pvObject, const std::type_info &objType, int nCount) { SF_FOR_EACH_FUNDAMENTAL_TYPE( SF_TRY_DECODE_ELEMENTS ); RCF_ASSERT(0)(objType); } #undef SF_TRY_DECODE_ELEMENTS } // namespace SF #endif // !INCLUDE_SF_ENCODING_HPP