//////////////////////////////////////////////////////////////////////////
#include "AliHLTMessage.h"
+#include "TVirtualStreamerInfo.h"
#include "Bytes.h"
#include "TFile.h"
+#include "TProcessID.h"
#include "TClass.h"
extern "C" void R__zip (Int_t cxlevel, Int_t *nin, char *bufin, Int_t *lout, char *bufout, Int_t *nout);
extern "C" void R__unzip(Int_t *nin, UChar_t *bufin, Int_t *lout, char *bufout, Int_t *nout);
const Int_t kMAXBUF = 0xffffff;
+Bool_t AliHLTMessage::fgEvolution = kFALSE;
+
ClassImp(AliHLTMessage)
//______________________________________________________________________________
fBufCompCur(0),
fCompPos(0)
, fBufUncompressed(0)
+ , fBitsPIDs(0)
+ , fInfos(NULL)
+ , fEvolution(kFALSE)
{
// Create a AliHLTMessage object for storing objects. The "what" integer
// describes the type of message. Predifined ROOT system message types
*this << what;
+ SetBit(kCannotHandleMemberWiseStreaming);
}
const Int_t AliHLTMessage::fgkMinimumSize=30;
fBufCompCur(0),
fCompPos(0)
, fBufUncompressed(0)
+ , fBitsPIDs(0)
+ , fInfos(NULL)
+ , fEvolution(kFALSE)
{
// Create a AliHLTMessage object for reading objects. The objects will be
// read from buf. Use the What() method to get the message type.
Reset();
}
+//______________________________________________________________________________
+void AliHLTMessage::EnableSchemaEvolutionForAll(Bool_t enable)
+{
+ // Static function enabling or disabling the automatic schema evolution.
+ // By default schema evolution support is off.
+
+ fgEvolution = enable;
+}
+
+//______________________________________________________________________________
+Bool_t AliHLTMessage::UsesSchemaEvolutionForAll()
+{
+ // Static function returning status of global schema evolution.
+
+ return fgEvolution;
+}
+
+//______________________________________________________________________________
+void AliHLTMessage::ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t /* force */)
+{
+ // Force writing the TStreamerInfo to the message.
+
+ if (fgEvolution || fEvolution) {
+ if (!fInfos) fInfos = new TList();
+ fInfos->Add(info);
+ }
+}
+
//______________________________________________________________________________
void AliHLTMessage::Forward()
{
if (IsReading()) {
SetWriteMode();
SetBufferOffset(fBufSize);
+ SetBit(kCannotHandleMemberWiseStreaming);
if (fBufComp) {
fCompPos = fBufCur;
}
}
+//______________________________________________________________________________
+void AliHLTMessage::IncrementLevel(TVirtualStreamerInfo *info)
+{
+ // Increment level.
+
+ TBufferFile::IncrementLevel(info);
+
+ if (fgEvolution || fEvolution) {
+ if (!fInfos) fInfos = new TList();
+ fInfos->Add(info);
+ }
+}
+
//______________________________________________________________________________
void AliHLTMessage::Reset()
{
return 0;
}
+//______________________________________________________________________________
+void AliHLTMessage::WriteObject(const TObject *obj)
+{
+ // Write object to message buffer.
+ // When support for schema evolution is enabled the list of TStreamerInfo
+ // used to stream this object is kept in fInfos. This information is used
+ // by TSocket::Send that sends this list through the socket. This list is in
+ // turn used by TSocket::Recv to store the TStreamerInfo objects in the
+ // relevant TClass in case the TClass does not know yet about a particular
+ // class version. This feature is implemented to support clients and servers
+ // with either different ROOT versions or different user classes versions.
+
+ if (fgEvolution || fEvolution) {
+ if (fInfos)
+ fInfos->Clear();
+ else
+ fInfos = new TList();
+ }
+
+ fBitsPIDs.ResetAllBits();
+ WriteObjectAny(obj, TObject::Class());
+}
+
+//______________________________________________________________________________
+UShort_t AliHLTMessage::WriteProcessID(TProcessID *pid)
+{
+ // Check if the ProcessID pid is already in the message.
+ // If not, then:
+ // - mark bit 0 of fBitsPIDs to indicate that a ProcessID has been found
+ // - mark bit uid+1 where uid id the uid of the ProcessID
+
+ if (fBitsPIDs.TestBitNumber(0)) return 0;
+ if (!pid)
+ pid = TProcessID::GetPID();
+ if (!pid) return 0;
+ fBitsPIDs.SetBitNumber(0);
+ UInt_t uid = pid->GetUniqueID();
+ fBitsPIDs.SetBitNumber(uid+1);
+ return 1;
+}
+
AliHLTMessage* AliHLTMessage::Stream(TObject* pSrc, Int_t compression, unsigned verbosity)
{
/// Helper function to stream an object into an AliHLTMessage
// modifications, original revision:
// root/net: v5-14-00 $: TMessage.h,v 1.9 2005/12/09 15:12:19 rdm
// Author: Fons Rademakers 19/12/96
+//
+// 2009-09-01 updating to revision
+// @(#)root/net:$Id$
+// Streaming problems have been encountered, especially when streaming
+// TObjArrays. As long as there was just one member, the streaming was
+// fine. With several members, internal variables of the objects have
+// been interchanged/mixed. This bug only effected the serialization
+// part, not the restoration of the object.
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
#ifndef ROOT_MessageTypes
#include "MessageTypes.h"
#endif
+#ifndef ROOT_TBits
+#include "TBits.h"
+#endif
#include "AliHLTLogging.h"
/**
void SetLength() const;
+ void ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t force);
void Forward();
- TClass *GetClass() const { return fClass; }
+ TClass *GetClass() const { return fClass;}
+ void IncrementLevel(TVirtualStreamerInfo* info);
void Reset();
void Reset(UInt_t what) { SetWhat(what); Reset(); }
UInt_t What() const { return fWhat; }
void SetWhat(UInt_t what);
+ void EnableSchemaEvolution(Bool_t enable = kTRUE) { fEvolution = enable; }
+ Bool_t UsesSchemaEvolution() const { return fEvolution; }
void SetCompressionLevel(Int_t level = 1);
Int_t GetCompressionLevel() const { return fCompress; }
Int_t Compress();
Int_t Uncompress();
char *CompBuffer() const { return fBufComp; }
Int_t CompLength() const { return (Int_t)(fBufCompCur - fBufComp); }
+ void WriteObject(const TObject *obj);
+ UShort_t WriteProcessID(TProcessID *pid);
+
+ static void EnableSchemaEvolutionForAll(Bool_t enable = kTRUE);
+ static Bool_t UsesSchemaEvolutionForAll();
/**
* Helper function to stream an object into an AliHLTMessage
char *fBufCompCur; //!Current position in compressed buffer
char *fCompPos; //!Position of fBufCur when message was compressed
char *fBufUncompressed; //!Uncompressed buffer
+ TBits fBitsPIDs; //Array of bits to mark the TProcessIDs uids written to the message
+ TList *fInfos; //Array of TStreamerInfo used in WriteObject
+ Bool_t fEvolution; //True if support for schema evolution required
+
+ static Bool_t fgEvolution; //True if global support for schema evolution required
// AliHLTMessage objects cannot be copied or assigned
AliHLTMessage(const AliHLTMessage &); // not implemented
/** a default buffer describing an empty message */
static UInt_t fgkDefaultBuffer[2]; //!transient
- ClassDef(AliHLTMessage,1) // Message buffer class
+ ClassDef(AliHLTMessage,2) // Message buffer class
};
#endif // ALIHLTMESSAGE_H