// @(#)root/netx:$Name: $:$Id: TXMessage.cxx,v 1.4 2004/12/16 19:23:18 rdm Exp $
// Author: Alvise Dorigo, Fabrizio Furano
/*************************************************************************
* Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// TXMessage //
// //
// Class to handle messages to/from xrootd. //
// //
//////////////////////////////////////////////////////////////////////////
#include "TXMessage.h"
#include "TXPhyConnection.h"
#include "TXProtocol.h"
#include "TError.h"
#include "TXDebug.h"
ClassImp(TXMessage);
//__________________________________________________________________________
TXMessage::TXMessage(struct ServerResponseHeader header)
{
// Constructor
fStatusCode = kXMSC_ok;
memcpy((void *)&fHdr, (const void*)&header, sizeof(ServerResponseHeader));
fData = 0;
fMarshalled = false;
if (!CreateData()) {
Error("TXMessage",
"Error allocating %d bytes for this TXMessage", fHdr.dlen);
fAllocated = false;
} else
fAllocated = true;
}
//__________________________________________________________________________
TXMessage::TXMessage()
{
// Default constructor
memset(&fHdr, 0, sizeof(fHdr));
fStatusCode = kXMSC_ok;
fData = 0;
fMarshalled = false;
fAllocated = false;
}
//__________________________________________________________________________
TXMessage::~TXMessage()
{
// Destructor
if (fData)
free(fData);
}
//__________________________________________________________________________
void *TXMessage::DonateData()
{
// Unlink the owned data in order to pass them elsewhere
void *res = fData;
fData = 0;
fAllocated = false;
return (res);
}
//__________________________________________________________________________
Bool_t TXMessage::CreateData()
{
// Allocate data
if (!fAllocated) {
if (fHdr.dlen) {
fData = malloc(fHdr.dlen+1);
if (!fData) {
Error("TXMessage::CreateData","Fatal ERROR *** malloc failed."
" Probable system resources exhausted.");
gSystem->Abort();
}
char *tmpPtr = (char *)fData;
memset((void*)(tmpPtr+fHdr.dlen), 0, 1);
}
if (!fData)
return kFALSE;
else
return kTRUE;
} else
return kTRUE;
}
//__________________________________________________________________________
void TXMessage::Marshall()
{
// Marshall, i.e. put in network byte order
if (!fMarshalled) {
ROOT::ServerResponseHeader2NetFmt(&fHdr);
fMarshalled = kTRUE;
}
}
//__________________________________________________________________________
void TXMessage::Unmarshall()
{
// Unmarshall, i.e. from network byte to normal order
if (fMarshalled) {
ROOT::clientUnmarshall(&fHdr);
fMarshalled = kFALSE;
}
}
//__________________________________________________________________________
Int_t TXMessage::ReadRaw(TXPhyConnection *phy, ESendRecvOptions opt)
{
// Given a physical connection, we completely build the content
// of the message, reading it from the socket of a phyconn
Int_t bytesread;
int readLen = sizeof(ServerResponseHeader);
if (DebugLevel() >= kDUMPDEBUG)
Info("TXMessage::ReadRaw", "Reading header (%d bytes) from socket.",
readLen);
bytesread = phy->ReadRaw((void *)&fHdr, readLen, opt);
if (bytesread < readLen) {
if (bytesread == TXSOCK_ERR_TIMEOUT)
SetStatusCode(kXMSC_timeout);
else {
if (!(phy->ReaderThreadKilled())) {
Error("TXMessage::ReadRaw", "Error reading %d bytes", readLen);
SetStatusCode(kXMSC_readerr);
} else
// It is like a timeout
SetStatusCode(kXMSC_timeout);
}
memset(&fHdr, 0, sizeof(fHdr));
return 1;
}
// the data arrive marshalled from the server (i.e. network byte order)
SetMarshalled(kTRUE);
Unmarshall();
if (fHdr.dlen) {
if (DebugLevel() >= kDUMPDEBUG)
Info("TXMessage::ReadRaw", "Reading data (%d bytes) from socket.",
fHdr.dlen);
CreateData();
if (phy->ReadRaw(fData, fHdr.dlen, opt) < fHdr.dlen) {
if (!(phy->ReaderThreadKilled())) {
Error("TXMessage::ReadRaw", "Error reading %d bytes.", fHdr.dlen);
SetStatusCode(kXMSC_readerr);
} else
// It is like a timeout
SetStatusCode(kXMSC_timeout);
}
}
return 1;
}
//___________________________________________________________________________
void TXMessage::Int2CharStreamid(kXR_char *charstreamid, Short_t intstreamid)
{
// Converts a streamid given as an integer to its representation
// suitable for the streamid inside the messages (i.e. ascii)
memcpy(charstreamid, &intstreamid, sizeof(intstreamid));
}
//___________________________________________________________________________
Short_t TXMessage::CharStreamid2Int(kXR_char *charstreamid)
{
// Converts a streamid given as an integer to its representation
// suitable for the streamid inside the messages (i.e. ascii)
Int_t res = *((Short_t *)charstreamid);
return res;
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.