diff options
Diffstat (limited to 'rnprotocol/rnprotocol.cc')
-rw-r--r-- | rnprotocol/rnprotocol.cc | 819 |
1 files changed, 819 insertions, 0 deletions
diff --git a/rnprotocol/rnprotocol.cc b/rnprotocol/rnprotocol.cc new file mode 100644 index 0000000..ce0deec --- /dev/null +++ b/rnprotocol/rnprotocol.cc @@ -0,0 +1,819 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +*/ +/**************************************************************************** + * + * + * COMMENTS: + * + ****************************************************************************/ + +#include <rnprotocol.hh> +#include <assert.h> + +using namespace rnp; +using namespace std; + +#include "raslib/rminit.hh" +#include "debug.hh" + + +const RnpQuark Rnp::rnpProtocolId = 25112001; + + +const char* Rnp::endiannessNames[2]= + { + "big endian", "little endian" + }; + +const char* Rnp::fragmentTypeNames[Rnp::fgt_HowMany]= + { + "(fgt_none)", "Command", "OkAnswer", "ErrorAnswer" + }; + +const char* Rnp::dataTypeNames[Rnp::dtt_HowMany] = + { + "(dtt_none)", "Asciiz", "Int32","Float","Double","Opaque","NullPtr" + }; + +const char* Rnp::errorTypeNames[Rnp::ert_HowMany] = + { + "(ert_unknown)", "StlException", "OtherException" + }; + +const char* Rnp::errorParamNames[Rnp::erp_HowMany] = + { + "(erp_none)", "StlWhatValue" + }; + +const char* Rnp::undefValue = "(undef)"; + +const char* Rnp::getFragmentTypeName(RnpQuark fType) throw() + { + if(0<= fType && fType < fgt_HowMany) return fragmentTypeNames[fType]; + return undefValue; + } + +const char* Rnp::getDataTypeName(RnpQuark dType) throw() + { + if(0<= dType && dType < dtt_HowMany) return dataTypeNames[dType]; + return undefValue; + } + +const char* Rnp::getErrorTypeName(RnpQuark eType) throw() + { + if(0<= eType && eType < ert_HowMany) return errorTypeNames[eType]; + return undefValue; + } + +const char* Rnp::getErrorParamName(RnpQuark eName) throw() + { + if(0<= eName && eName < erp_HowMany) return errorParamNames[eName]; + return undefValue; + } + +const char* Rnp::getEndiannessName(Rnp::Endianness endianness) throw() + { + return endiannessNames[endianness]; + } + +Rnp::Endianness Rnp::detectHostEndianness() throw() + { + unsigned int uInteger = 1; + + char* ptr = (char*)&uInteger; + + return *ptr==1 ? littleEndian : bigEndian; + } + +RnpQuark Rnp::swapBytes(RnpQuark orig) throw() + { + RnpQuark result = orig; + + char *buf = (char*)&result; + + char tmp = buf[0]; + buf[0] = buf[3]; + buf[3] = tmp; + + tmp = buf[1]; + buf[1] = buf[2]; + buf[2] = tmp; + + return result; + } + +//############## RNP Header ################################# + +bool RnpHeader::isRnpMessage() const throw() + { + Rnp::Endianness hostEndianness = Rnp::detectHostEndianness(); + + RnpQuark cProtocolId = hostEndianness == Rnp::littleEndian ? protocolId : Rnp::swapBytes(protocolId); + + return cProtocolId == Rnp::rnpProtocolId ? true:false; + } + +Rnp::Endianness RnpHeader::getEndianness() const throw() + { + return (Rnp::Endianness)messageEndianness; + } + +RnpQuark RnpHeader::getTotalLength() const throw() + { + Rnp::Endianness endianness = (Rnp::Endianness)messageEndianness; + return endianness == Rnp::detectHostEndianness() ? totalMessageLength : Rnp::swapBytes(totalMessageLength); + } + +bool RnpHeader::changeEndianness(Rnp::Endianness newEndianness) throw() + { + Rnp::Endianness endianness = (Rnp::Endianness)messageEndianness; + + if(newEndianness == endianness) return false; // no change necessary + + messageEndianness = newEndianness; + + totalMessageLength = Rnp::swapBytes(totalMessageLength); + nrFragments = Rnp::swapBytes(nrFragments); + serverType = Rnp::swapBytes(serverType); + authInfoStart = Rnp::swapBytes(authInfoStart); + authInfoLength = Rnp::swapBytes(authInfoLength); + comprInfoStart = Rnp::swapBytes(comprInfoStart); + comprInfoLength = Rnp::swapBytes(comprInfoLength); + dataStart = Rnp::swapBytes(dataStart); + dataLength = Rnp::swapBytes(dataLength); + + return true; + } + +RnpFragmentHeader* RnpHeader::getFirstFragment() const throw() + { + return (RnpFragmentHeader*)((char*)this + dataStart); + } + +//############ RNP Fragment ################################## + +RnpFragmentHeader* RnpFragmentHeader::getNextFragment() const throw() + { + char *ptr = (char*)this; + + return (RnpFragmentHeader*)(ptr + totalLength); + } + +RnpParameter* RnpFragmentHeader::getFirstParameter() const throw() + { + return (RnpParameter*)(this+1); + } + +void RnpFragmentHeader::changeEndianness() throw() + { + // there is no info about the initial endianness so be carefull + fragmType = Rnp::swapBytes(fragmType); + command = Rnp::swapBytes(command); + nrParams = Rnp::swapBytes(nrParams); + totalLength = Rnp::swapBytes(totalLength); + } + +//############ RNP Parameter ################################## +RnpParameter* RnpParameter::getNextParameter() const throw() + { + char *ptr = (char*)this; + return (RnpParameter*)(ptr + totalLength); + } + +void* RnpParameter::getData() const throw() + { + return (void*)(this+1); + } + +RnpQuark RnpParameter::getDataLength() const throw() + { + return dataLength; + } + +RnpQuark RnpParameter::computeTotalAlignedLength() throw() + { + totalLength = (sizeof(RnpParameter) + dataLength + 3) & 0xFFFFFFFC; + return totalLength; + } + +RnpQuark RnpParameter::getPaddLength() const throw() + { + return totalLength - (sizeof(RnpParameter) + dataLength); + } + +void RnpParameter::changeToHostEndianness() throw() + { + // there is no info about the initial endianness so be carefull + paramType = Rnp::swapBytes(paramType); + dataType = Rnp::swapBytes(dataType); + dataLength = Rnp::swapBytes(dataLength); + totalLength = Rnp::swapBytes(totalLength); + + RnpQuark *valPtr = (RnpQuark*)getData(); + switch(dataType) + { + case Rnp::dtt_Int32: + case Rnp::dtt_Float32: *valPtr = Rnp::swapBytes(*valPtr); + break; + + case Rnp::dtt_Double64: RnpQuark temp = Rnp::swapBytes(*valPtr); + *valPtr = Rnp::swapBytes(*(valPtr +1)); + *(valPtr+1) = temp; + break; + } + } + +void RnpParameter::changeToPartnerEndianness() throw() + { + // there is no info about the initial endianness so be careful + + RnpQuark *valPtr = (RnpQuark*)getData(); + switch(dataType) + { + case Rnp::dtt_Int32: + case Rnp::dtt_Float32: *valPtr = Rnp::swapBytes(*valPtr); + break; + + case Rnp::dtt_Double64: RnpQuark temp = Rnp::swapBytes(*valPtr); + *valPtr = Rnp::swapBytes(*(valPtr +1)); + *(valPtr+1) = temp; + break; + } + paramType = Rnp::swapBytes(paramType); + dataType = Rnp::swapBytes(dataType); + dataLength = Rnp::swapBytes(dataLength); + totalLength = Rnp::swapBytes(totalLength); + } + +//########################################################### + +RnpProtocolEncoder::RnpProtocolEncoder() throw() + { + commBuffer = NULL; + + rnpHeader = NULL; + currFragment = NULL; + currParameter = NULL; + allocated = false; + carrierHeaderSize = 0; + finalEndianness = Rnp::detectHostEndianness(); + } + +RnpProtocolEncoder::~RnpProtocolEncoder() throw() + { + if(commBuffer != NULL && allocated == true) delete commBuffer; + // the other pointers are not pointing to allocated memory!! + } + +void RnpProtocolEncoder::setBuffer(akg::CommBuffer* buffer) throw() + { + if(commBuffer != NULL && allocated == true) delete commBuffer; + + commBuffer = buffer; + allocated = false; + } + +bool RnpProtocolEncoder::allocateBuffer(int maxMessageLength) throw() + { + if(commBuffer != NULL && allocated ==true) delete commBuffer; + + commBuffer = new akg::CommBuffer(maxMessageLength); + allocated = true; + return true; + } + +bool RnpProtocolEncoder::adjustBufferSize(int differenceSize) throw() + { + ENTER( "RnpProtocolEncoder::adjustBufferSize( differenceSize=" << differenceSize << " )" ); + + if (commBuffer == 0) + { + TALK( "RnpProtocolEncoder::adjustBufferSize(): warning: null commBuffer, assert would fire." ); + return false; + } + assert(commBuffer != 0); + + if (differenceSize <= 0) + { + TALK( "RnpProtocolEncoder::adjustBufferSize(): warning: nonpositive differenceSize, assert would fire." ); + return false; + } + assert(differenceSize > 0); + + // we need to adjust the pointers to the new location + char *orig = (char*)(commBuffer->getData()); + char *head = (char*)rnpHeader; + char *frag = (char*)currFragment; + char *para = (char*)currParameter; + + if(commBuffer->resize(commBuffer->getDataSize() + differenceSize + RNP_DEFAULTBUFFERSIZE) == true) + { + char *final = (char*)(commBuffer->getData()); + rnpHeader = (RnpHeader*)(final + (head - orig)); + currFragment = (RnpFragmentHeader*)(final + (frag - orig)); + currParameter= (RnpParameter*)(final + (para - orig)); + LEAVE( "RnpProtocolEncoder::adjustBufferSize() -> true" ); + return true; + } + + LEAVE( "RnpProtocolEncoder::adjustBufferSize() -> false" ); + return false; + } + +int RnpProtocolEncoder::getBufferSize() throw() + { + if (commBuffer == 0) + { + TALK( "RnpProtocolEncoder::getBufferSize(): warning: null commBuffer, assert will fire." ); + } + assert(commBuffer != 0); + + return commBuffer->getBufferSize(); + } + +void RnpProtocolEncoder::startMessage(RnpQuark serverType, int nCarrierHeaderSize) throw() + { + if (commBuffer == 0) + { + TALK( "RnpProtocolEncoder::startMessage(): warning: null commBuffer, assert will fire." ); + } + assert(commBuffer != NULL); + + carrierHeaderSize = nCarrierHeaderSize; + + commBuffer->clearToRead(); + + commBuffer->reserve(sizeof(RnpHeader) + carrierHeaderSize); + + rnpHeader = (RnpHeader*)((char*)commBuffer->getData() + carrierHeaderSize); + + Rnp::Endianness hostEndianness = Rnp::detectHostEndianness(); + + // the protocolID is always 25112001 little endian!! + rnpHeader->protocolId = hostEndianness == Rnp::littleEndian ? Rnp::rnpProtocolId : Rnp::swapBytes(Rnp::rnpProtocolId); + + rnpHeader->messageEndianness = hostEndianness; + rnpHeader->desiredEndianness = hostEndianness; + rnpHeader->majorVersion = 1; + rnpHeader->minorVersion = 0; + rnpHeader->totalMessageLength = sizeof(RnpHeader); + rnpHeader->nrFragments = 0; + rnpHeader->serverType = serverType; + rnpHeader->authInfoStart = 0; + rnpHeader->authInfoLength = 0; + rnpHeader->comprInfoStart = 0; + rnpHeader->comprInfoLength = 0; + rnpHeader->dataStart = sizeof(RnpHeader); + rnpHeader->dataLength = 0; + + currFragment = (RnpFragmentHeader*)(rnpHeader+1); + + } + +int RnpProtocolEncoder::getCarrierHeaderSize() throw() + { + return carrierHeaderSize; + } + +void RnpProtocolEncoder::setDesiredEndianness(Rnp::Endianness desiredEndianness) throw() + { + rnpHeader->desiredEndianness = desiredEndianness; + } +void RnpProtocolEncoder::setFinalEndianness(Rnp::Endianness endianness) throw() + { + finalEndianness = endianness; + } + +void RnpProtocolEncoder::startFragment(Rnp::FragmentType fType,RnpQuark command) throw() + { + commBuffer->reserve(sizeof(RnpFragmentHeader)); + + currFragment->fragmType = fType; + currFragment->command = command; + currFragment->nrParams = 0; + currFragment->totalLength = sizeof(RnpFragmentHeader); + + currParameter = currFragment->getFirstParameter(); + rnpHeader->nrFragments++; + + } + +void RnpProtocolEncoder::addStringParameter(RnpQuark parameterType,const char* str) throw() + { + if(str != 0) addParameter(parameterType, Rnp::dtt_Asciiz, str, strlen(str)+1); + else addParameter(parameterType, Rnp::dtt_NullPtr, str, 0); + } + +void RnpProtocolEncoder::addInt32Parameter(RnpQuark parameterType, int par) throw() + { + addParameter(parameterType, Rnp::dtt_Int32, &par, sizeof(par)); + } + +void RnpProtocolEncoder::addFloat32Parameter(RnpQuark parameterType, float par) throw() + { + addParameter(parameterType, Rnp::dtt_Float32, &par, sizeof(par)); + } +void RnpProtocolEncoder::addDouble64Parameter(RnpQuark parameterType, double par) throw() + { + addParameter(parameterType, Rnp::dtt_Double64, &par, sizeof(par)); + } + +void RnpProtocolEncoder::addOpaqueParameter(RnpQuark parameterType, const void *buf, int size) throw() + { + if(buf != 0) addParameter(parameterType, Rnp::dtt_Opaque, buf, size); + else addParameter(parameterType, Rnp::dtt_NullPtr, buf, 0); + } + +void RnpProtocolEncoder::addParameter(RnpQuark parameterType, Rnp::DataType dtt, const void *data, int length) throw() + { + commBuffer->reserve(sizeof(RnpParameter)); + + currParameter->paramType = parameterType; + currParameter->dataType = dtt; + currParameter->dataLength = length; + currParameter->totalLength = currParameter->computeTotalAlignedLength(); + + int paddlen = currParameter->getPaddLength(); + + if(data != 0 ) commBuffer->read(data,length); + if(paddlen) commBuffer->reserve(paddlen); + + currFragment->nrParams++; + currFragment->totalLength += currParameter->totalLength; + currParameter = currParameter->getNextParameter(); + } + +void RnpProtocolEncoder::endFragment() throw() + { + rnpHeader->totalMessageLength += currFragment->totalLength; + rnpHeader->dataLength += currFragment->totalLength; + currFragment = currFragment->getNextFragment(); + } + +akg::CommBuffer* RnpProtocolEncoder::endMessage() throw() + { + changeToPartnerEndianness(finalEndianness); + return commBuffer; + } + +bool RnpProtocolEncoder::changeToPartnerEndianness(Rnp::Endianness newEndianness) throw() + { + if(newEndianness == rnpHeader->getEndianness()) return false; + // so newEndianness is the same as the message endiannes, no change necessary + + // don't forget that the endianness is now the host endianness so, + // after changed, the data can't be used correctly any more!! + + RnpFragmentHeader* lCurrFragment = rnpHeader->getFirstFragment(); + + for(int fragment=0; fragment < rnpHeader->nrFragments; fragment++) + { + + RnpParameter* lCurrParameter = lCurrFragment->getFirstParameter(); + for(int parameter = 0; parameter < lCurrFragment->nrParams; parameter++) + { + RnpParameter* nextParameter = lCurrParameter->getNextParameter(); + lCurrParameter->changeToPartnerEndianness(); + lCurrParameter = nextParameter; + } + + RnpFragmentHeader* nextFragment = lCurrFragment->getNextFragment(); + lCurrFragment->changeEndianness(); + lCurrFragment = nextFragment; + } + + rnpHeader->changeEndianness(newEndianness); + + return true; + } + +//###### DECODER ####################### + +RnpProtocolDecoder::RnpProtocolDecoder() throw() + { + // this memory doesn't belong to us, so do not deallocate!! + commBuffer = NULL; + rnpHeader = NULL; + currFragment = NULL; + currParameter = NULL; + } + +bool RnpProtocolDecoder::decode(akg::CommBuffer *buffer) throw() + { + // Later, throw something intelligible! + commBuffer = buffer; + + rnpHeader = (RnpHeader*)commBuffer->getData(); + + if(rnpHeader->isRnpMessage() == false) return false; + + originalEndianness = rnpHeader->getEndianness(); + + if(originalEndianness == Rnp::detectHostEndianness()) + { + // -- test validity of message -- + if(testIntegrity() == false) return false; + } + else + { // -- endianess of message -- + changeToHostEndianness(); + } + return true; + } + +bool RnpProtocolDecoder::testIntegrity() const throw() + { + // could be done better... + ENTER( "RnpProtocolDecoder::testIntegrity()" ); + + if(rnpHeader->isRnpMessage() == false) + { + RMInit::logOut << "Communication error: received invalid RNP header." << endl; + return false; + } + + bool ok = true; + char *endOfMessage = (char*)rnpHeader + rnpHeader->getTotalLength(); + char *endOfHeader = (char*)rnpHeader + sizeof(RnpHeader); + int maxLength = commBuffer->getDataSize() - sizeof(RnpHeader); + // max of every length + + RnpFragmentHeader* lCurrFragment = (RnpFragmentHeader*)getFirstFragment(); + for(int fragment=0; fragment < countFragments(); fragment++) + { + if( endOfHeader <= (char*)lCurrFragment && (char*)lCurrFragment < endOfMessage) + ; + else + { + ok = false; + RMInit::logOut << "Communication error: RNP message corrupt: short header." << endl; + break; + } + + if(lCurrFragment->totalLength > maxLength) + { + ok = false; + RMInit::logOut << "Communication error: RNP message corrupt: actual length (" << lCurrFragment->totalLength << ") larger than foreseen (" << maxLength << ")." << endl; + break; + } + + char *startOfParameters = (char*)lCurrFragment + sizeof(RnpFragmentHeader); + char *endOfParameters = (char*)lCurrFragment + lCurrFragment->totalLength; + + RnpParameter* lCurrParameter = (RnpParameter*)getFirstParameter(); + for(int parameter = 0; parameter < countParameters(); parameter++) + { + if( startOfParameters <= (char*)lCurrParameter && (char*)lCurrParameter < endOfParameters) + ; + else + { + ok = false; + RMInit::logOut << "Communication error: RNP message corrupt: current parameter location outside parameter area." << endl; + break; + } + + if(lCurrParameter->totalLength > lCurrFragment->totalLength) + { + ok = false; + RMInit::logOut << "Communication error: RNP message corrupt: current parameter length (" << lCurrParameter->totalLength << ") larger than total fragment size (" << lCurrFragment->totalLength << ")." << endl; + break; + } + + lCurrParameter = (RnpParameter*)getNextParameter(); + } + + if( (char*)lCurrParameter != endOfParameters) + { + ok = false; +// the counting seems to differ from the protocol specs; +// to avoid log flooding we disable it for the moment being -- PB 2005-aug-28 +#ifdef RMANDEBUG + RMInit::logOut << "Communication warning: puzzled by message: parameter count too small, found extra parameter(s). (this message can be ignored)" << endl; +#endif + } + + if(ok == false) + break; + + // we found a valid fragment, proceed to next one + lCurrFragment = (RnpFragmentHeader*)getNextFragment(); + } + + LEAVE( "RnpProtocolDecoder::testIntegrity() -> " << ok ); + return ok; + } + +bool RnpProtocolDecoder::changeToHostEndianness() throw() + { + if(rnpHeader->changeEndianness(Rnp::detectHostEndianness()) == false ) return false; + // so host endianness is the same as the message endiannes, no change necessary + + currFragment = (RnpFragmentHeader*)getFirstFragment(); + + for(int fragment=0; fragment < countFragments(); fragment++) + { + currFragment->changeEndianness(); + + currParameter = (RnpParameter*)getFirstParameter(); + for(int parameter = 0; parameter < countParameters(); parameter++) + { + currParameter->changeToHostEndianness(); + + currParameter = (RnpParameter*)getNextParameter(); + } + + currFragment = (RnpFragmentHeader*)getNextFragment(); + } + return true; + } + +RnpQuark RnpProtocolDecoder::getDestinationServerType() const throw() + { + return rnpHeader->serverType; + } + +Rnp::Endianness RnpProtocolDecoder::getDesiredEndianness() const throw() + { + return (Rnp::Endianness)rnpHeader->desiredEndianness; + } + +Rnp::Endianness RnpProtocolDecoder::getOriginalEndianness() const throw() + { + return originalEndianness; + } + +int RnpProtocolDecoder::getMessageLength() const throw() + { + return rnpHeader->totalMessageLength; + } + +int RnpProtocolDecoder::getMessageVersion() const throw() + { + return 1000*rnpHeader->majorVersion + rnpHeader->minorVersion; + } + +RnpQuark RnpProtocolDecoder::countFragments() const throw() + { + return rnpHeader->nrFragments; + } + +const RnpFragmentHeader* RnpProtocolDecoder::getFirstFragment() const throw() + { + currFragmentIdx = 0; + + return currFragment = (currFragmentIdx < rnpHeader->nrFragments ? rnpHeader->getFirstFragment() : 0); + } + +const RnpFragmentHeader* RnpProtocolDecoder::getNextFragment() const throw() + { + currFragmentIdx++; + + return currFragment = (currFragmentIdx < rnpHeader->nrFragments ? currFragment->getNextFragment() : 0); + } + +RnpQuark RnpProtocolDecoder::getFragmentType() const throw() + { + return currFragment->fragmType; + } + +const char* RnpProtocolDecoder::getFragmentTypeName() const throw() + { + return Rnp::getFragmentTypeName(currFragment->fragmType); + } +RnpQuark RnpProtocolDecoder::getCommand() const throw() + { + return currFragment->command; + } + +int RnpProtocolDecoder::countParameters() const throw() + { + return currFragment->nrParams; + } + +RnpQuark RnpProtocolDecoder::getFragmentLength() const throw() + { + return currFragment->totalLength; + } + +const RnpParameter* RnpProtocolDecoder::getFirstParameter() const throw() + { + currParameterIdx = 0; + + return currParameter = ( currParameterIdx < currFragment->nrParams ? currFragment->getFirstParameter() : 0); + } + +const RnpParameter* RnpProtocolDecoder::getNextParameter() const throw() + { + currParameterIdx++; + + return currParameter = ( currParameterIdx < currFragment->nrParams ? currParameter->getNextParameter() : 0); + } + +RnpQuark RnpProtocolDecoder::getParameterType() const throw() + { + return currParameter->paramType; + } + +RnpQuark RnpProtocolDecoder::getDataType() const throw() + { + return currParameter->dataType; + } + +const void* RnpProtocolDecoder::getData() const throw() + { + return currParameter->getData(); + } + +const char* RnpProtocolDecoder::getDataAsString() const throw() + { + if ( !( currParameter->dataType == Rnp::dtt_Asciiz || currParameter->dataType == Rnp::dtt_NullPtr) ) + { + TALK( "RnpProtocolEncoder::getDataAsString(): warning: assert will fire." ); + } + assert(currParameter->dataType == Rnp::dtt_Asciiz || currParameter->dataType == Rnp::dtt_NullPtr); + + return currParameter->dataType == Rnp::dtt_Asciiz ? (const char*)currParameter->getData() : (const char*)0; + } + +int RnpProtocolDecoder::getDataAsInteger() const throw() + { + if ( !( currParameter->dataType == Rnp::dtt_Int32 ) ) + { + TALK( "RnpProtocolEncoder::getDataAsInteger(): warning: assert will fire." ); + } + assert(currParameter->dataType == Rnp::dtt_Int32); + + return *(int*)currParameter->getData(); + } + +float RnpProtocolDecoder::getDataAsFloat() const throw() + { + if ( !( currParameter->dataType == Rnp::dtt_Float32 ) ) + { + TALK( "RnpProtocolEncoder::getDataAsFloat(): warning: assert will fire." ); + } + assert(currParameter->dataType == Rnp::dtt_Float32); + + return *(float*)currParameter->getData(); + } + +double RnpProtocolDecoder::getDataAsDouble() const throw() + { + if ( !( currParameter->dataType == Rnp::dtt_Double64 ) ) + { + TALK( "RnpProtocolEncoder::getDataAsDouble(): warning: assert will fire." ); + } + assert(currParameter->dataType == Rnp::dtt_Double64); + + return *(double*)currParameter->getData(); + } + +const void* RnpProtocolDecoder::getDataAsOpaque() const throw() + { + if ( !( currParameter->dataType == Rnp::dtt_Opaque || currParameter->dataType == Rnp::dtt_NullPtr) ) + { + TALK( "RnpProtocolEncoder::getDataAsOpaque(): warning: assert will fire." ); + } + assert(currParameter->dataType == Rnp::dtt_Opaque || currParameter->dataType == Rnp::dtt_NullPtr); + + return currParameter->dataType == Rnp::dtt_Opaque ? (const void*)currParameter->getData() : (const void*)0; + } + +int RnpProtocolDecoder::getDataLength() const throw() + { + return currParameter->getDataLength(); + } + +void RnpProtocolDecoder::printRnpHeader(RnpHeader *lRnpHeader) const throw() + { + cout<<"RnpHeader ID="<<lRnpHeader->protocolId<<endl; + cout<<" total fragments="<<lRnpHeader->nrFragments<<endl; + cout<<" sizeof header="<<sizeof(RnpHeader)<<endl; + cout<<endl; + } + +bool RnpProtocolDecoder::isRnpMessage() const throw() + { + return rnpHeader->isRnpMessage(); + } + |