///////////////////////////////////////////////////////////////////////////////
// MQ4CPP - Message queuing for C++
// Copyright (C) 2004-2007 Riccardo Pompeo (Italy)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#define SILENT
#include "MemoryChannel.h"
#include "Trace.h"
#include "GeneralHashFunctions.h"
#include "Logger.h"
static char* MEMORY_OVERFLOW="MemoryChannel Exception: displacement overflows memory buffer";
static char* TRANSFER_IN_PROGRESS="MemoryChannel Exception: memory transfer still in progress";
MemoryChannelClient::MemoryChannelClient(const char* theName, const char* theHost,int thePort, const char* theTarget)
:Client(theName, theHost, thePort, theTarget)
{
TRACE("MemoryChannelClient::MemoryChannelClient - start")
itsState=MC_STOP;
itsBuffer=NULL;
itsSize=0;
itsMap=NULL;
itsBlocks=0;
itsTxBuffer=NULL;
itsTxSize=0;
itsTxMap=NULL;
itsTxBlocks=0;
itsLastTx=0;
itsTxCnt=0;
itsSessionToken=0;
itsBlocksToTx=0;
itsBlocksTransmitted=0;
TRACE("MemoryChannelClient::MemoryChannelClient - end")
}
MemoryChannelClient::~MemoryChannelClient()
{
TRACE("MemoryChannelClient::~MemoryChannelClient - start")
if(itsBuffer!=NULL) delete [] itsBuffer;
if(itsMap!=NULL) delete [] itsMap;
if(itsTxBuffer!=NULL) delete [] itsTxBuffer;
if(itsTxMap!=NULL) delete [] itsTxMap;
TRACE("MemoryChannelClient::~MemoryChannelClient - end")
}
void MemoryChannelClient::setSize(unsigned long theSize)
{
TRACE("MemoryChannelClient::setSize - start")
if(theSize!=0 && theSize!=itsSize)
{
TRACE("Resizing working buffer")
if(itsBuffer!=NULL) delete [] itsBuffer;
if(itsMap!=NULL) delete [] itsMap;
TRACE("Allocating new buffer. Size=" << theSize)
itsSize=theSize;
itsBlocks=theSize/MC_BLOCKSIZE;
itsBlocks+=(theSize%MC_BLOCKSIZE>0) ? 1 : 0;
TRACE("Blocks=" << itsBlocks)
itsBuffer=new char[itsBlocks*MC_BLOCKSIZE];
itsMap=new MemoryBlockState[itsBlocks];
TRACE("Initializing memory")
memset(itsBuffer,0,itsSize);
memset(itsMap,0,itsBlocks);
}
TRACE("MemoryChannelClient::setSize - end")
}
void MemoryChannelClient::set(char* theBuffer,unsigned long theSize)
{
TRACE("MemoryChannelClient::set - start")
if(itsBuffer!=NULL) delete [] itsBuffer;
if(itsMap!=NULL) delete [] itsMap;
itsBuffer=theBuffer;
itsSize=theSize;
itsBlocks=theSize/MC_BLOCKSIZE;
itsBlocks+=(theSize%MC_BLOCKSIZE>0) ? 1 : 0;
TRACE("Blocks=" << itsBlocks)
itsMap=new MemoryBlockState[itsBlocks];
memset(itsMap,0,itsBlocks);
TRACE("MemoryChannelClient::set - end")
}
void MemoryChannelClient::commit(bool theDeltaTransfer)
{
TRACE("MemoryChannelClient::commit - start")
if(done())
{
if(itsTxBlocks!=itsBlocks)
{
TRACE("Resizing transmition map")
delete [] itsTxMap;
itsTxBlocks=itsBlocks;
itsTxMap=new MemoryBlockState[itsTxBlocks];
}
if(itsTxSize!=itsSize)
{
TRACE("Resizing transmition buffer")
delete [] itsTxBuffer;
itsTxSize=itsSize;
itsTxBuffer=new char[itsBlocks*MC_BLOCKSIZE];
}
TRACE("Copying buffer and map")
memcpy(itsTxBuffer,itsBuffer,itsTxSize);
if(theDeltaTransfer && itsMap!=NULL)
memcpy(itsTxMap,itsMap,itsTxBlocks*sizeof(MemoryBlockState));
else
for(unsigned int cnt=0; cnt < itsTxBlocks; cnt++)
itsTxMap[cnt]=MC_CHANGED;
memset(itsMap,0,itsBlocks);
sendHeader();
}
else
{
TRACE("Commit failed because MemoryChannelClient is still transfering previous buffer")
throw MemoryChannelException(TRANSFER_IN_PROGRESS);
}
TRACE("MemoryChannelClient::commit - end")
}
void MemoryChannelClient::rollback()
{
TRACE("MemoryChannelClient::rollback - start")
if(itsSize!=itsTxSize)
{
TRACE("Resizing transmition buffer")
delete [] itsBuffer;
itsSize=itsTxSize;
itsBuffer=new char[itsSize];
}
if(itsBlocks!=itsTxBlocks)
{
TRACE("Resizing transmition map")
delete [] itsMap;
itsBlocks=itsTxBlocks;
itsMap=new MemoryBlockState[itsBlocks];
}
TRACE("Copying buffer and map")
if(itsSize!=0)
memcpy(itsBuffer,itsTxBuffer,itsSize);
if(itsBlocks!=0)
memcpy(itsMap,itsTxMap,itsBlocks);
TRACE("MemoryChannelClient::rollback - end")
}
bool MemoryChannelClient::searchFirstBlock()
{
TRACE("MemoryChannelClient::searchFirstBlock - start")
itsBlocksTransmitted=0;
itsBlocksToTx=0;
itsTxCnt=0;
bool found=false;
for(unsigned long cnt=0;cnt < itsTxBlocks;cnt++)
{
if(itsTxMap[cnt]==MC_CHANGED)
{
if(!found)
{
TRACE("Found block to tx at=" << cnt)
itsTxCnt=cnt;
itsTxMap[cnt]=MC_TRANSFERING;
found=true;
}
itsBlocksToTx++;
}
}
TRACE("Blocks to tx found=" << itsBlocksToTx)
TRACE("MemoryChannelClient::searchFirstBlock - end")
return found;
}
bool MemoryChannelClient::searchNextBlock()
{
TRACE("MemoryChannelClient::searchNextBlock - start")
bool found=false;
itsTxMap[itsTxCnt]=MC_TRANSFERED;
for(unsigned long cnt=itsTxCnt+1;cnt < itsTxBlocks;cnt++)
{
if(itsTxMap[cnt]==MC_CHANGED)
{
TRACE("Found block to tx at=" << cnt)
itsTxCnt=cnt;
itsTxMap[cnt]=MC_TRANSFERING;
found=true;
break;
}
}
TRACE("MemoryChannelClient::searchNextBlock - end")
return found;
}
char* MemoryChannelClient::blockAt(unsigned long theBlock)
{
if(theBlock>itsTxBlocks)
throw MemoryChannelException(MEMORY_OVERFLOW);
return (itsTxBuffer+theBlock*MC_BLOCKSIZE);
}
void MemoryChannelClient::sendHeader()
{
TRACE("MemoryChannelClient::sendHeader - start")
if(searchFirstBlock())
{
itsState=MC_SENDING_HEADER;
itsTxStructure.free();
if(itsBlocksToTx == 1)
itsState=MC_WAIT_LAST_ACK;
StringProperty* aBlockTypeProperty=new StringProperty("BT");
aBlockTypeProperty->set("HDR");
itsTxStructure.add(aBlockTypeProperty);
LongIntProperty* aTotBlocksProperty=new LongIntProperty("TB");
aTotBlocksProperty->set(itsBlocksToTx);
itsTxStructure.add(aTotBlocksProperty);
TRACE("Blocks to tx=" << itsBlocksToTx)
LongIntProperty* aBlockIndexProperty=new LongIntProperty("BI");
aBlockIndexProperty->set(itsTxCnt);
itsTxStructure.add(aBlockIndexProperty);
TRACE("Block index=" << itsTxCnt)
LongIntProperty* aBufferSizeProperty=new LongIntProperty("BS");
aBufferSizeProperty->set(itsTxSize);
itsTxStructure.add(aBufferSizeProperty);
TRACE("Buffer size=" << itsTxSize)
StringProperty* aBufferProperty=new StringProperty("BF");
aBufferProperty->set(blockAt(itsTxCnt),MC_BLOCKSIZE);
itsTxStructure.add(aBufferProperty);
string aString;
encodeProperties(itsTxStructure,aString);
sendMessage(aString);
itsLastTx=Timer::time();
itsBlocksTransmitted++;
}
TRACE("MemoryChannelClient::sendHeader - end")
}
void MemoryChannelClient::sendBlock()
{
TRACE("MemoryChannelClient::sendBlock - start")
itsState=MC_SENDING_BLOCKS;
itsTxStructure.free();
if(searchNextBlock())
{
if(itsBlocksTransmitted+1>=itsBlocksToTx)
itsState=MC_WAIT_LAST_ACK;
LongIntProperty* aTokenProperty=new LongIntProperty("TK");
aTokenProperty->set(itsSessionToken);
itsTxStructure.add(aTokenProperty);
TRACE("Session token=" << itsSessionToken)
StringProperty* aBlockTypeProperty=new StringProperty("BT");
aBlockTypeProperty->set("BLK");
itsTxStructure.add(aBlockTypeProperty);
LongIntProperty* aBlockIndexProperty=new LongIntProperty("BI");
aBlockIndexProperty->set(itsTxCnt);
itsTxStructure.add(aBlockIndexProperty);
TRACE("Block index=" << itsTxCnt)
StringProperty* aBufferProperty=new StringProperty("BF");
aBufferProperty->set(blockAt(itsTxCnt),MC_BLOCKSIZE);
itsTxStructure.add(aBufferProperty);
string aString;
encodeProperties(itsTxStructure,aString);
sendMessage(aString);
itsLastTx=Timer::time();
itsBlocksTransmitted++;
}
else
{
TRACE("No more blocks to tx")
throw MemoryChannelException("MemoryChannelClient::sendBlock: no more blocks to tx");
}
TRACE("MemoryChannelClient::sendBlock - end")
}
void MemoryChannelClient::success(string theBuffer)
{
TRACE("MemoryChannelClient::success - start")
decodeProperties(theBuffer,itsResponse);
MemoryChannelResult result=MC_VOID;
Property* aProperty=itsResponse.get("RS");
if(aProperty!=NULL && aProperty->is(PROPERTY_SHORTINT))
{
result=(MemoryChannelResult)((ShortIntProperty*)aProperty)->get();
TRACE("Result=" << result)
}
aProperty=itsResponse.get("TK");
if(aProperty!=NULL && aProperty->is(PROPERTY_LONGINT))
{
itsSessionToken=((LongIntProperty*)aProperty)->get();
TRACE("Session token=" << itsSessionToken)
}
switch(result)
{
case MC_NOT_ALLOWED:
TRACE("Memory transfer exception")
itsState=MC_FAILED;
onCompletion();
break;
case MC_SESSION_STARTED:
case MC_SESSION_FINISHED:
case MC_SESSION_CONTINUE:
switch(itsState)
{
case MC_WAIT_LAST_ACK:
TRACE("Last acknoledge")
itsState=MC_STOP;
onCompletion();
break;
case MC_SENDING_HEADER:
case MC_SENDING_BLOCKS:
TRACE("Send new block")
sendBlock();
break;
}
break;
default:
TRACE("Return value not allowed")
itsState=MC_FAILED;
onCompletion();
}
TRACE("MemoryChannelClient::success - end")
}
void MemoryChannelClient::fail(string theError)
{
TRACE("MemoryChannelClient::fail - start")
itsState=MC_FAILED;
onCompletion();
WARNING(theError.c_str())
TRACE("MemoryChannelClient::fail - end")
}
void MemoryChannelClient::onWakeup(Wakeup* theMessage)
{
TRACE("MemoryChannelClient::onWakeup - start")
if(itsState!=MC_STOP && itsState!=MC_FAILED && Timer::time()-itsLastTx > MC_TIMEOUT)
{
WARNING("Timeout during transmition")
itsState=MC_FAILED;
onCompletion();
}
Client::onWakeup(theMessage);
TRACE("MemoryChannelClient::onWakeup - end")
}
void MemoryChannelClient::markBlocks(unsigned long theDisplacement,unsigned long theSize)
{
TRACE("MemoryChannelClient::markBlocks - start")
unsigned long start=theDisplacement/MC_BLOCKSIZE;
unsigned long end=(theDisplacement+theSize-1)/MC_BLOCKSIZE;
TRACE("Displ=" << theDisplacement << " Size=" << theSize << " Start=" << start << " End=" << end)
for(unsigned long cnt=start; cnt <= end; cnt++)
itsMap[cnt]=MC_CHANGED;
TRACE("MemoryChannelClient::markBlocks - end")
}
void MemoryChannelClient::set(unsigned long theDisplacement,long long theValue)
{
TRACE("MemoryChannelClient::set - start")
if(theDisplacement+sizeof(theValue)<=itsSize)
{
*(long long*)(itsBuffer+theDisplacement)=theValue;
markBlocks(theDisplacement,sizeof(theValue));
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelClient::set - end")
}
void MemoryChannelClient::set(unsigned long theDisplacement,long theValue)
{
TRACE("MemoryChannelClient::set - start")
if(theDisplacement+sizeof(theValue)<=itsSize)
{
*(long*)(itsBuffer+theDisplacement)=theValue;
markBlocks(theDisplacement,sizeof(theValue));
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelClient::set - end")
}
void MemoryChannelClient::set(unsigned long theDisplacement,short theValue)
{
TRACE("MemoryChannelClient::set - start")
if(theDisplacement+sizeof(theValue)<=itsSize)
{
*(short*)(itsBuffer+theDisplacement)=theValue;
markBlocks(theDisplacement,sizeof(theValue));
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelClient::set - end")
}
void MemoryChannelClient::set(unsigned long theDisplacement,char theValue)
{
TRACE("MemoryChannelClient::set - start")
if(theDisplacement+sizeof(theValue)<=itsSize)
{
*(itsBuffer+theDisplacement)=theValue;
markBlocks(theDisplacement,sizeof(theValue));
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelClient::set - end")
}
void MemoryChannelClient::set(unsigned long theDisplacement,char* theSourcePtr,unsigned long theSize)
{
TRACE("MemoryChannelClient::set - start")
if(theDisplacement+theSize<=itsSize)
{
memcpy(itsBuffer+theDisplacement,theSourcePtr,theSize);
markBlocks(theDisplacement,theSize);
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelClient::set - end")
}
void MemoryChannelClient::set(unsigned long theDisplacement,unsigned long theSize,char theValue)
{
TRACE("MemoryChannelClient::set - start")
if(theDisplacement+theSize<=itsSize)
{
memset(itsBuffer+theDisplacement,theValue,theSize);
markBlocks(theDisplacement,theSize);
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelClient::set - end")
}
MemoryChannelServer::MemoryChannelServer(const char* theName)
:Server(theName)
{
TRACE("MemoryChannelServer::MemoryChannelServer - start")
itsBuffer=NULL;
itsSize=0;
itsSession.blocksReceived=0;
itsSession.blocksToRx=0;
itsSession.size=0;
itsSession.token=0;
itsSession.time=0;
itsSession.buffer=NULL;
itsSession.blocks=0;
itsSession.lastblock=0;
TRACE("MemoryChannelServer::MemoryChannelServer - end")
}
MemoryChannelServer::~MemoryChannelServer()
{
TRACE("MemoryChannelServer::~MemoryChannelServer - start")
if(itsBuffer!=NULL)
delete [] itsBuffer;
if(itsSession.buffer!=NULL)
delete [] itsSession.buffer;
TRACE("MemoryChannelServer::~MemoryChannelServer - end")
}
void MemoryChannelServer::copyBuffer()
{
TRACE("MemoryChannelServer::copyBuffer - start")
if(itsBuffer==NULL)
{
TRACE("Allocate buffer")
itsSize=itsSession.size;
itsBuffer=new char[itsSize];
memcpy(itsBuffer,itsSession.buffer,itsSize);
}
else if(itsBuffer!=NULL && itsSize!=itsSession.size)
{
TRACE("Resize buffer")
delete [] itsBuffer;
itsSize=itsSession.size;
itsBuffer=new char[itsSize];
memcpy(itsBuffer,itsSession.buffer,itsSize);
}
else
{
TRACE("Copy only")
memcpy(itsBuffer,itsSession.buffer,itsSize);
}
TRACE("MemoryChannelServer::copyBuffer - start")
}
string MemoryChannelServer::service(string theBuffer)
{
TRACE("MemoryChannelServer::service - start")
string ret;
ListProperty aResponse;
decodeProperties(theBuffer,itsRxStructure);
Property* aProperty=itsRxStructure.get("BT");
if(aProperty!=NULL && aProperty->is(PROPERTY_STRING))
{
string btype=((StringProperty*)aProperty)->get();
TRACE("Block type=" << btype)
if(btype.compare("HDR")==0)
{
receiveHeader(aResponse);
}
else if(btype.compare("BLK")==0)
{
receiveBlock(aResponse);
}
else
{
setResponse(aResponse,MC_NOT_ALLOWED);
}
}
encodeProperties(aResponse,ret);
TRACE("MemoryChannelServer::service - end")
return ret;
}
void MemoryChannelServer::setResponse(ListProperty& theResponse,MemoryChannelResult theCode,unsigned long theToken)
{
TRACE("MemoryChannelServer::setResponse - start")
TRACE("Result=" << theCode)
TRACE("Token=" << theToken)
ShortIntProperty* aResultProperty=new ShortIntProperty("RS");
aResultProperty->set(theCode);
theResponse.add(aResultProperty);
if(theToken!=0L)
{
LongIntProperty* aTokenProperty=new LongIntProperty("TK");
aTokenProperty->set(theToken);
theResponse.add(aTokenProperty);
}
TRACE("MemoryChannelServer::setResponse - end")
}
void MemoryChannelServer::receiveHeader(ListProperty& theResponse)
{
TRACE("MemoryChannelServer::receiveHeader - start")
Property* aProperty;
itsSession.blocksToRx=0;
itsSession.size=0;
itsSession.time=Timer::time();
itsSession.token=RSHash(getName())+Timer::time();
itsSession.blocksReceived=1;
itsSession.lastblock=0;
aProperty=itsRxStructure.get("TB");
if(aProperty!=NULL && aProperty->is(PROPERTY_LONGINT))
{
itsSession.blocksToRx=((LongIntProperty*)aProperty)->get();
TRACE("Blocks to rx=" << itsSession.blocksToRx)
}
aProperty=itsRxStructure.get("BS");
if(aProperty!=NULL && aProperty->is(PROPERTY_LONGINT))
{
itsSession.size=((LongIntProperty*)aProperty)->get();
unsigned long blocks=itsSession.size/MC_BLOCKSIZE;
blocks+=(itsSession.size%MC_BLOCKSIZE>0) ? 1 : 0;
if(itsSession.buffer==NULL && itsSession.size>0)
{
TRACE("Allocate buffer")
itsSession.blocks=blocks;
itsSession.buffer=new char[itsSession.blocks*MC_BLOCKSIZE];
memset(itsSession.buffer,0,itsSession.blocks*MC_BLOCKSIZE);
}
else if(itsSession.buffer!=NULL && blocks!=itsSession.blocks && itsSession.size>0)
{
TRACE("Resize buffer")
delete [] itsSession.buffer;
itsSession.blocks=blocks;
itsSession.buffer=new char[itsSession.blocks*MC_BLOCKSIZE];
memset(itsSession.buffer,0,itsSession.blocks*MC_BLOCKSIZE);
}
TRACE("Buffer size=" << itsSession.size)
TRACE("Blocks=" << itsSession.blocks)
}
unsigned long bindex=0;
aProperty=itsRxStructure.get("BI");
if(aProperty!=NULL && aProperty->is(PROPERTY_LONGINT))
{
bindex=((LongIntProperty*)aProperty)->get();
TRACE("Block index=" << bindex)
}
aProperty=itsRxStructure.get("BF");
if(aProperty!=NULL && aProperty->is(PROPERTY_STRING) && itsSession.size>0 && itsSession.blocksToRx>0)
{
string buffer=((StringProperty*)aProperty)->get();
TRACE("Buffer size=" << buffer.size())
if(buffer.size()==MC_BLOCKSIZE && bindex<itsSession.blocks)
{
memcpy(itsSession.buffer+bindex*MC_BLOCKSIZE,buffer.data(),MC_BLOCKSIZE);
if(itsSession.blocksToRx==1)
{
setResponse(theResponse,MC_SESSION_FINISHED,itsSession.token);
copyBuffer();
itsSession.blocks=0;
itsSession.token=0;
itsSession.lastblock=0;
onCompletion();
TRACE("Session finished")
}
else
{
itsSession.lastblock=bindex;
setResponse(theResponse,MC_SESSION_STARTED,itsSession.token);
TRACE("Session started. Token=" << itsSession.token)
}
}
else
{
setResponse(theResponse,MC_NOT_ALLOWED);
TRACE("Wrong parameters from peer")
}
}
else
{
setResponse(theResponse,MC_NOT_ALLOWED);
TRACE("Wrong parameters from peer")
}
TRACE("MemoryChannelServer::receiveHeader - end")
}
void MemoryChannelServer::receiveBlock(ListProperty& theResponse)
{
TRACE("MemoryChannelServer::receiveBlock - start")
Property* aProperty=itsRxStructure.get("TK");
if(aProperty!=NULL && aProperty->is(PROPERTY_LONGINT))
{
unsigned long token=((LongIntProperty*)aProperty)->get();
TRACE("Session token=" << token)
if(itsSession.token==token)
{
TRACE("Session found")
unsigned long bindex=0;
aProperty=itsRxStructure.get("BI");
if(aProperty!=NULL && aProperty->is(PROPERTY_LONGINT))
{
bindex=((LongIntProperty*)aProperty)->get();
TRACE("Block index=" << bindex)
}
aProperty=itsRxStructure.get("BF");
if(aProperty!=NULL && aProperty->is(PROPERTY_STRING))
{
string buffer=((StringProperty*)aProperty)->get();
TRACE("Buffer size=" << buffer.size())
if(buffer.size()==MC_BLOCKSIZE && bindex<itsSession.blocks)
{
memcpy(itsSession.buffer+bindex*MC_BLOCKSIZE,buffer.data(),MC_BLOCKSIZE);
if(bindex!=itsSession.lastblock)
itsSession.blocksReceived++;
if(itsSession.blocksReceived>=itsSession.blocksToRx)
{
setResponse(theResponse,MC_SESSION_FINISHED,itsSession.token);
copyBuffer();
itsSession.blocks=0;
itsSession.token=0;
itsSession.lastblock=0;
onCompletion();
TRACE("Session finished")
}
else
{
itsSession.lastblock=bindex;
setResponse(theResponse,MC_SESSION_CONTINUE,itsSession.token);
TRACE("Session continue. Token=" << itsSession.token)
}
}
else
{
setResponse(theResponse,MC_NOT_ALLOWED);
TRACE("Wrong parameters from peer")
}
}
else
{
setResponse(theResponse,MC_NOT_ALLOWED);
TRACE("Wrong parameters from peer")
}
}
else
{
TRACE("Session not found")
setResponse(theResponse,MC_NOT_ALLOWED);
}
}
else
{
TRACE("Wrong parameters from peer")
setResponse(theResponse,MC_NOT_ALLOWED);
}
TRACE("MemoryChannelServer::receiveBlock - end")
}
void MemoryChannelServer::onWakeup(Wakeup* theMessage)
{
TRACE("MemoryChannelServer::onWakeup - start")
if(itsSession.token!=0 && Timer::time()-itsSession.time>MC_TIMEOUT)
{
TRACE("Session timeout. Token=" << itsSession.token << " dTime=" << (theMessage->getTime()-itsSession.time))
WARNING("Session dropped for timeout")
itsSession.blocksReceived=0;
itsSession.blocksToRx=0;
itsSession.size=0;
itsSession.token=0;
itsSession.time=0;
itsSession.lastblock=0;
}
TRACE("MemoryChannelServer::onWakeup - end")
}
long long MemoryChannelServer::get64(unsigned long theDisplacement)
{
TRACE("MemoryChannelServer::get64 - start")
long long res=0;
if(theDisplacement+sizeof(res)<=itsSize)
{
res=*(long long*)(itsBuffer+theDisplacement);
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelServer::get64 - end")
return res;
}
long MemoryChannelServer::get32(unsigned long theDisplacement)
{
TRACE("MemoryChannelServer::get32 - start")
long res=0;
if(theDisplacement+sizeof(res)<=itsSize)
{
res=*(long*)(itsBuffer+theDisplacement);
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelServer::get32 - end")
return res;
}
short MemoryChannelServer::get16(unsigned long theDisplacement)
{
TRACE("MemoryChannelServer::get16 - start")
short res=0;
if(theDisplacement+sizeof(res)<=itsSize)
{
res=*(short*)(itsBuffer+theDisplacement);
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelServer::get16 - end")
return res;
}
char MemoryChannelServer::get8(unsigned long theDisplacement)
{
TRACE("MemoryChannelServer::get8 - start")
char res=0;
if(theDisplacement+sizeof(res)<=itsSize)
{
res=*(itsBuffer+theDisplacement);
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelServer::get8 - end")
return res;
}
void MemoryChannelServer::get(unsigned long theDisplacement,char* theDestPtr,unsigned long theSize)
{
TRACE("MemoryChannelServer::get - start")
if(theDisplacement+theSize<=itsSize)
{
memcpy(theDestPtr,itsBuffer+theDisplacement,theSize);
}
else
{
throw MemoryChannelException(MEMORY_OVERFLOW);
}
TRACE("MemoryChannelServer::get - end")
}
syntax highlighted by Code2HTML, v. 0.9.1