// //
///////////////////////////////////////////////////////////////////////////////
+#include <cstdlib>
#include <strings.h>
#include <Riostream.h>
#include <TError.h>
#include <TNamed.h>
#include <TSystem.h>
#include <TEnv.h>
+#include <TArrayC.h>
+#include <Varargs.h> // platform independent definition of va_copy
#include "AliLog.h"
ClassImp(AliLog)
-
+// implementation of a singleton here
AliLog* AliLog::fgInstance = NULL;
Bool_t AliLog::fgDebugEnabled = kTRUE;
+/**
+ * get root logger singleton instance
+ */
+AliLog *AliLog::GetRootLogger()
+{
+ if (fgInstance == NULL)
+ {
+ // creating singleton
+ fgInstance = new AliLog;
+ }
-//_____________________________________________________________________________
+ return fgInstance;
+}
+
+/**
+ * delete the root logger singleton instance
+ */
+void AliLog::DeleteRootLogger()
+{
+ if (fgInstance != NULL)
+ {
+ delete fgInstance;
+ fgInstance = NULL;
+ }
+}
+
+/**
+ * default private constructor
+ */
AliLog::AliLog() :
TObject(),
fGlobalLogLevel(kInfo),
{
// default constructor: set default values
- for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+ for (Int_t iType = kFatal; iType < kMaxType; iType++)
+ {
fOutputTypes[iType] = 0;
fFileNames[iType] = "";
fOutputFiles[iType] = NULL;
fOutputStreams[iType] = NULL;
+ fCallBacks[iType]=NULL;
fPrintType[iType] = kTRUE;
fPrintModule[iType] = kFALSE;
fPrintLocation[iType] = (iType == kDebug);
}
+ // TO BE REVIEWED
// replace the previous instance by this one
if (fgInstance) delete fgInstance;
fgInstance = this;
ReadEnvSettings();
}
-//_____________________________________________________________________________
+/**
+ * private destructor
+ */
AliLog::~AliLog()
{
// destructor: clean up and reset instance pointer
if (fRepetitions > 0) PrintRepetitions();
- for (Int_t i = 0; i < fModuleDebugLevels.GetEntriesFast(); i++) {
+ for (Int_t i = 0; i < fModuleDebugLevels.GetEntriesFast(); i++)
+ {
if (fModuleDebugLevels[i]) fModuleDebugLevels[i]->Delete();
}
+
fClassDebugLevels.Delete();
- for (Int_t i = 0; i < fClassDebugLevels.GetEntriesFast(); i++) {
+
+ for (Int_t i = 0; i < fClassDebugLevels.GetEntriesFast(); i++)
+ {
if (fClassDebugLevels[i]) fClassDebugLevels[i]->Delete();
}
+
fClassDebugLevels.Delete();
- for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+ for (Int_t iType = kFatal; iType < kMaxType; iType++)
+ {
CloseFile(iType);
}
+
fflush(stderr);
fflush(stdout);
fgInstance = NULL;
}
+// NOT IMPLEMENTED!?
//_____________________________________________________________________________
AliLog::AliLog(const AliLog& log) :
- TObject(log)
+ TObject(log),
+ fGlobalLogLevel(log.fGlobalLogLevel),
+ fModuleDebugLevels(log.fModuleDebugLevels),
+ fClassDebugLevels(log.fClassDebugLevels),
+ fPrintRepetitions(log.fPrintRepetitions),
+ fRepetitions(log.fRepetitions),
+ fLastType(log.fLastType),
+ fLastMessage(log.fLastMessage),
+ fLastModule(log.fLastModule),
+ fLastClassName(log.fLastClassName),
+ fLastFunction(log.fLastFunction),
+ fLastFile(log.fLastFile),
+ fLastLine(log.fLastLine)
{
// copy constructor
Fatal("AliLog", "copy constructor not implemented");
}
+// NOT IMPLEMENTED!?
//_____________________________________________________________________________
AliLog& AliLog::operator = (const AliLog& /*log*/)
{
}
+/**
+ * gSystem see TSystem.h
+ * gEnv see TEnv.h
+ *
+ * LOG_NO_DEBUG: fgDebugEnabled <- false
+ * AliRoot.AliLog.EnableDebug
+ * AliRoot.AliLog.GlobalLogLevel
+ */
//_____________________________________________________________________________
void AliLog::ReadEnvSettings()
{
// load settings from the root configuration file (.rootrc)
// and from environment variables
- static const char* typeNames[kMaxType] =
- {"kFatal", "kError", "kWarning", "kInfo", "kDebug"};
+ static const char* typeNames[kMaxType] = {"kFatal", "kError", "kWarning", "kInfo", "kDebug"};
// debug en- or disabling
- if (gSystem->Getenv("LOG_NO_DEBUG")) {
+ if (gSystem->Getenv("LOG_NO_DEBUG"))
+ {
fgDebugEnabled = kFALSE;
- } else if (gEnv->Defined("AliRoot.AliLog.EnableDebug")) {
- fgDebugEnabled = gEnv->GetValue("AliRoot.AliLog.EnableDebug",
- fgDebugEnabled);
+ }
+ else if (gEnv->Defined("AliRoot.AliLog.EnableDebug"))
+ {
+ fgDebugEnabled = gEnv->GetValue("AliRoot.AliLog.EnableDebug", fgDebugEnabled);
AliInfo(Form("debug %sabled", ((fgDebugEnabled) ? "en" : "dis")));
}
// global log level
- if (gEnv->Defined("AliRoot.AliLog.GlobalLogLevel")) {
+ if (gEnv->Defined("AliRoot.AliLog.GlobalLogLevel"))
+ {
const char* type = gEnv->GetValue("AliRoot.AliLog.GlobalLogLevel", "");
- for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+
+ for (Int_t iType = kFatal; iType < kMaxType; iType++)
+ {
if (strcmp(type, typeNames[iType]) == 0) fGlobalLogLevel = iType;
}
+
AliDebug(3, Form("global log level set to %d", fGlobalLogLevel));
}
// global debug level
- if (gEnv->Defined("AliRoot.AliLog.GlobalDebugLevel")) {
- Int_t level = gEnv->GetValue("AliRoot.AliLog.GlobalDebugLevel",
- Int_t(fGlobalLogLevel - kDebugOffset));
+ if (gEnv->Defined("AliRoot.AliLog.GlobalDebugLevel"))
+ {
+ Int_t level = gEnv->GetValue("AliRoot.AliLog.GlobalDebugLevel", Int_t(fGlobalLogLevel - kDebugOffset));
if (level < -kDebugOffset) level = kDebugOffset;
fGlobalLogLevel = kDebugOffset + level;
- AliDebug(3, Form("global debug level set to %d",
- fGlobalLogLevel - kDebugOffset));
+ AliDebug(3, Form("global debug level set to %d", fGlobalLogLevel - kDebugOffset));
}
// module debug level
- if (gEnv->Defined("AliRoot.AliLog.ModuleDebugLevel")) {
+ if (gEnv->Defined("AliRoot.AliLog.ModuleDebugLevel"))
+ {
TString levels = gEnv->GetValue("AliRoot.AliLog.ModuleDebugLevel", "");
char* p = const_cast<char*>(levels.Data());
- while (const char* module = strtok(p, " ")) {
+
+ while (const char* module = strtok(p, " "))
+ {
p = NULL;
- char* pos = index(module, ':');
+ char* pos = const_cast<char*>(index(module, ':'));
if (!pos) continue;
*(pos++) = '\0';
Int_t level = atoi(pos);
}
// class debug level
- if (gEnv->Defined("AliRoot.AliLog.ClassDebugLevel")) {
+ if (gEnv->Defined("AliRoot.AliLog.ClassDebugLevel"))
+ {
TString levels = gEnv->GetValue("AliRoot.AliLog.ClassDebugLevel", "");
char* p = const_cast<char*>(levels.Data());
- while (const char* className = strtok(p, " ")) {
+
+ while (const char* className = strtok(p, " "))
+ {
p = NULL;
- char* pos = index(className, ':');
+ char* pos = const_cast<char*>(index(className, ':'));
if (!pos) continue;
*(pos++) = '\0';
Int_t level = atoi(pos);
SetClassDebugLevel(className, level);
- AliDebug(3, Form("debug level for class %s set to %d",
- className, level));
+ AliDebug(3, Form("debug level for class %s set to %d", className, level));
}
}
// general output stream
- if (gEnv->Defined("AliRoot.AliLog.Output")) {
+ if (gEnv->Defined("AliRoot.AliLog.Output"))
+ {
TString stream = gEnv->GetValue("AliRoot.AliLog.Output", "Standard");
- if (stream.CompareTo("standard", TString::kIgnoreCase) == 0) {
+
+ if (stream.CompareTo("standard", TString::kIgnoreCase) == 0)
+ {
SetStandardOutput();
AliDebug(3, "output stream set to standard output for all types");
- } else if (stream.CompareTo("error", TString::kIgnoreCase) == 0) {
+ }
+ else if (stream.CompareTo("error", TString::kIgnoreCase) == 0)
+ {
SetErrorOutput();
AliDebug(3, "output stream set to error output for all types");
- } else if (!stream.IsNull()) {
+ }
+ else if (!stream.IsNull())
+ {
SetFileOutput(stream);
- AliDebug(3, Form("output stream set to file %s for all types",
- stream.Data()));
+ AliDebug(3, Form("output stream set to file %s for all types", stream.Data()));
}
}
// individual output streams
- for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+ for (Int_t iType = kFatal; iType < kMaxType; iType++)
+ {
TString name("AliRoot.AliLog.Output.");
name += &typeNames[iType][1];
- if (gEnv->Defined(name)) {
+
+ if (gEnv->Defined(name))
+ {
TString stream = gEnv->GetValue(name, "Standard");
- if (stream.CompareTo("standard", TString::kIgnoreCase) == 0) {
- SetStandardOutput(EType(iType));
- AliDebug(3, Form("output stream set to standard output for type %s",
- typeNames[iType]));
- } else if (stream.CompareTo("error", TString::kIgnoreCase) == 0) {
- SetErrorOutput(EType(iType));
- AliDebug(3, Form("output stream set to error output for type %s",
- typeNames[iType]));
- } else if (!stream.IsNull()) {
- SetFileOutput(EType(iType), stream);
- AliDebug(3, Form("output stream set to file %s for type %s",
- stream.Data(), typeNames[iType]));
+
+ if (stream.CompareTo("standard", TString::kIgnoreCase) == 0)
+ {
+ SetStandardOutput(EType_t(iType));
+ AliDebug(3, Form("output stream set to standard output for type %s", typeNames[iType]));
+ }
+ else if (stream.CompareTo("error", TString::kIgnoreCase) == 0)
+ {
+ SetErrorOutput(EType_t(iType));
+ AliDebug(3, Form("output stream set to error output for type %s", typeNames[iType]));
+ }
+ else if (!stream.IsNull())
+ {
+ SetFileOutput(EType_t(iType), stream);
+ AliDebug(3, Form("output stream set to file %s for type %s", stream.Data(), typeNames[iType]));
}
}
}
// handling of root error messages
- if (gEnv->Defined("AliRoot.AliLog.HandleRootMessages")) {
+ if (gEnv->Defined("AliRoot.AliLog.HandleRootMessages"))
+ {
Bool_t on = gEnv->GetValue("AliRoot.AliLog.HandleRootMessages", kTRUE);
SetHandleRootMessages(on);
- AliDebug(3, Form("handling of root messages %sabled",
- ((on) ? "en" : "dis")));
+ AliDebug(3, Form("handling of root messages %sabled", ((on) ? "en" : "dis")));
}
// printout settings
- static const char* settingNames[4] =
- {"Type", "Module", "Scope", "Location"};
- Bool_t* settings[] =
- {fPrintType, fPrintModule, fPrintScope, fPrintLocation};
- for (Int_t iSetting = 0; iSetting < 4; iSetting++) {
+ static const char* settingNames[4] = {"Type", "Module", "Scope", "Location"};
+ Bool_t* settings[] = {fPrintType, fPrintModule, fPrintScope, fPrintLocation};
+
+ for (Int_t iSetting = 0; iSetting < 4; iSetting++)
+ {
TString name("AliRoot.AliLog.Print");
name += settingNames[iSetting];
- if (gEnv->Defined(name)) {
+
+ if (gEnv->Defined(name))
+ {
Bool_t on = gEnv->GetValue(name, settings[iSetting][0]);
- for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+
+ for (Int_t iType = kFatal; iType < kMaxType; iType++)
+ {
settings[iSetting][iType] = on;
}
- AliDebug(3, Form("printing of %s %sabled for all types",
- settingNames[iSetting], ((on) ? "en" : "dis")));
+ AliDebug(3, Form("printing of %s %sabled for all types", settingNames[iSetting], ((on) ? "en" : "dis")));
}
- for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+ for (Int_t iType = kFatal; iType < kMaxType; iType++)
+ {
TString nameType = name + "." + &typeNames[iType][1];
- if (gEnv->Defined(nameType)) {
+
+ if (gEnv->Defined(nameType))
+ {
Bool_t on = gEnv->GetValue(nameType, settings[iSetting][iType]);
settings[iSetting][iType] = on;
- AliDebug(3, Form("printing of %s %sabled for type %s",
- settingNames[iSetting], ((on) ? "en" : "dis"),
- typeNames[iType]));
+ AliDebug(3, Form("printing of %s %sabled for type %s", settingNames[iSetting], ((on) ? "en" : "dis"), typeNames[iType]));
}
}
}
// repetition of messages
- if (gEnv->Defined("AliRoot.AliLog.PrintRepetitions")) {
+ if (gEnv->Defined("AliRoot.AliLog.PrintRepetitions"))
+ {
Bool_t on = gEnv->GetValue("AliRoot.AliLog.PrintRepetitions", kTRUE);
fPrintRepetitions = on;
- AliDebug(3, Form("printing of message repetitions %sabled",
- ((on) ? "en" : "dis")));
+ AliDebug(3, Form("printing of message repetitions %sabled", ((on) ? "en" : "dis")));
}
}
{
// new error handler for messages from root
- switch (level) {
+ switch (level)
+ {
case ::kFatal : level = kFatal; break;
case ::kSysError :
DefaultErrorHandler(level, abort, location, message);
}
+// DEPRECATED: USE A CONFIGURATION FILE INSTEAD
//_____________________________________________________________________________
void AliLog::EnableDebug(Bool_t enabled)
{
}
//_____________________________________________________________________________
-void AliLog::SetGlobalLogLevel(EType type)
+void AliLog::SetGlobalLogLevel(EType_t type)
{
// set the global debug level
+ // TO BE DELETED
if (!fgInstance) new AliLog;
fgInstance->fGlobalLogLevel = type;
}
}
//_____________________________________________________________________________
-void AliLog::SetStandardOutput(EType type)
+void AliLog::SetStandardOutput(EType_t type)
{
// write log messages of the given type to the standard output (stdout)
}
//_____________________________________________________________________________
-void AliLog::SetErrorOutput(EType type)
+void AliLog::SetErrorOutput(EType_t type)
{
// write log messages of the given type to the error output (stderr)
}
//_____________________________________________________________________________
-void AliLog::SetFileOutput(EType type, const char* fileName)
+void AliLog::SetFileOutput(EType_t type, const char* fileName)
{
// write log messages of the given type to the given file
}
if (closeFile) {
fclose(fOutputFiles[type]);
- fOutputStreams[type]->close();
+ ofstream* stream=reinterpret_cast<ofstream*>(fOutputStreams[type]);
+ stream->close();
delete fOutputStreams[type];
}
}
else if (fOutputTypes[type] == 2) {
if (!fOutputFiles[type]) {
FILE* file = NULL;
- ofstream* stream = NULL;
+ ostream* stream = NULL;
if (!fFileNames[type].IsNull()) {
for (Int_t iType = kFatal; iType < kMaxType; iType++) {
if ((iType != type) &&
}
//_____________________________________________________________________________
-void AliLog::SetPrintType(EType type, Bool_t on)
+void AliLog::SetPrintType(EType_t type, Bool_t on)
{
// switch on or off the printing of the message type for the given message type
}
//_____________________________________________________________________________
-void AliLog::SetPrintModule(EType type, Bool_t on)
+void AliLog::SetPrintModule(EType_t type, Bool_t on)
{
// switch on or off the printing of the module for the given message type
}
//_____________________________________________________________________________
-void AliLog::SetPrintScope(EType type, Bool_t on)
+void AliLog::SetPrintScope(EType_t type, Bool_t on)
{
// switch on or off the printing of the scope/class name
// for the given message type
}
//_____________________________________________________________________________
-void AliLog::SetPrintLocation(EType type, Bool_t on)
+void AliLog::SetPrintLocation(EType_t type, Bool_t on)
{
// switch on or off the printing of the file name and line number
// for the given message type
//_____________________________________________________________________________
-void AliLog::Write(const char* name, Int_t option)
+void AliLog::WriteToFile(const char* name, Int_t option)
{
// write the log object with the given name and option to the current file
// get the logging level for the given module and class
if (!fgInstance) new AliLog;
- TObject* obj = fgInstance->fClassDebugLevels.FindObject(className);
- if (obj) return obj->GetUniqueID();
- obj = fgInstance->fModuleDebugLevels.FindObject(module);
- if (obj) return obj->GetUniqueID();
+ if (className) {
+ TObject* obj = fgInstance->fClassDebugLevels.FindObject(className);
+ if (obj) return obj->GetUniqueID();
+ }
+ if (module) {
+ TObject* obj = fgInstance->fModuleDebugLevels.FindObject(module);
+ if (obj) return obj->GetUniqueID();
+ }
return fgInstance->fGlobalLogLevel;
}
{"Fatal", "Error", "Warning", "Info", "Debug"};
if (fPrintType[type]) {
- fprintf(stream, "%s in ", typeNames[type]);
+ PrintString(type, stream, "%c-", typeNames[type][0]);
}
- fprintf(stream, "<");
if (fPrintModule[type] && module) {
- fprintf(stream, "%s/", module);
+ PrintString(type, stream, "%s/", module);
}
if (fPrintScope[type] && className) {
- fprintf(stream, "%s::", className);
+ PrintString(type, stream, "%s::", className);
}
if (message) {
- fprintf(stream, "%s>: %s", function, message);
+ PrintString(type, stream, "%s: %s", function, message);
} else {
- fprintf(stream, "%s>", function);
+ PrintString(type, stream, "%s", function);
}
if (fPrintLocation[type] && file) {
- fprintf(stream, " (%s:%.0d)", file, line);
+ PrintString(type, stream, " (%s:%.0d)", file, line);
}
if (message) {
- fprintf(stream, "\n");
+ PrintString(type, stream, "\n");
} else {
- fprintf(stream, ": ");
+ PrintString(type, stream, ": ");
}
+ if (fCallBacks[type]) (*(fCallBacks[type]))((EType_t)type, NULL);
}
//_____________________________________________________________________________
{
// print number of repetitions
- fprintf(GetOutputStream(fLastType), " <message repeated %d time%s>\n",
+ PrintString(fLastType, GetOutputStream(fLastType), " <message repeated %d time%s>\n",
fRepetitions, (fRepetitions > 1) ? "s" : "");
+ if (fCallBacks[fLastType]) (*(fCallBacks[fLastType]))((EType_t)fLastType, NULL);
}
//_____________________________________________________________________________
//_____________________________________________________________________________
-Int_t AliLog::RedirectStdoutTo(EType type, UInt_t level, const char* module,
+Int_t AliLog::RedirectStdoutTo(EType_t type, UInt_t level, const char* module,
const char* className, const char* function,
const char* file, Int_t line, Bool_t print)
{
}
//_____________________________________________________________________________
-Int_t AliLog::RedirectStderrTo(EType type, UInt_t level, const char* module,
+Int_t AliLog::RedirectStderrTo(EType_t type, UInt_t level, const char* module,
const char* className, const char* function,
const char* file, Int_t line, Bool_t print)
{
}
//_____________________________________________________________________________
-Int_t AliLog::RedirectTo(FILE* stream, EType type, UInt_t level,
+Int_t AliLog::RedirectTo(FILE* stream, EType_t type, UInt_t level,
const char* module, const char* className,
const char* function, const char* file, Int_t line,
Bool_t print)
if (stream != stderr) dup2(fileno(stderr), fileno(stream));
} else if (fOutputTypes[type] == 2) { // file
freopen(fFileNames[type], "a", stream);
+ } else if (fOutputTypes[type] == 3) { // external C++ stream
+ // redirection is not possible for external C++ streams
}
// print information
//_____________________________________________________________________________
-ostream& AliLog::Stream(EType type, UInt_t level,
+ostream& AliLog::Stream(EType_t type, UInt_t level,
const char* module, const char* className,
const char* function, const char* file, Int_t line)
{
}
//_____________________________________________________________________________
-ostream& AliLog::GetStream(EType type, UInt_t level,
+ostream& AliLog::GetStream(EType_t type, UInt_t level,
const char* module, const char* className,
const char* function, const char* file, Int_t line)
{
return cerr;
} else if (fOutputTypes[type] == 2) {
return *fOutputStreams[type];
+ } else if (fOutputTypes[type] == 3) {
+ return *fOutputStreams[type];
}
return nullStream;
}
+void AliLog::SetStreamOutput(ostream* stream)
+{
+ // set an external stream as target for log messages of all types
+ // the external stream is completely handled by the caller, the
+ // AliLog class just writes to it
+
+ for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+ SetStreamOutput((AliLog::EType_t)iType, stream);
+ }
+}
+
+void AliLog::SetStreamOutput(EType_t type, ostream* stream)
+{
+ // set an external stream as target for log messages of the given type
+ // the external stream is completely handled by the caller, the
+ // AliLog class just writes to it
+
+ if ((type < kFatal) || (type >= kMaxType)) return;
+ if (!fgInstance) new AliLog;
+ if (fgInstance->fOutputTypes[type] == 2) {
+ fgInstance->CloseFile(type);
+ }
+ fgInstance->fOutputTypes[type] = 3;
+ fgInstance->fFileNames[type] = "";
+ fgInstance->fOutputFiles[type] = NULL;
+ fgInstance->fOutputStreams[type] = stream;
+}
+
+void AliLog::SetLogNotification(AliLogNotification pCallBack)
+{
+ // set a notification callback function for log messages of all types
+
+ for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+ SetLogNotification((AliLog::EType_t)iType, pCallBack);
+ }
+}
+
+void AliLog::SetLogNotification(EType_t type, AliLogNotification pCallBack)
+{
+ // set a notifications call back function for log messages of all types
+ // the callback fuction is invoced whenever an output was written
+ // Note: does not work for c++ streamer classes, the external stream
+ // has to handle this diectly (e.g. custom implementation of endl)
+
+ if ((type < kFatal) || (type >= kMaxType)) return;
+ if (!fgInstance) new AliLog;
+ fgInstance->fCallBacks[type]=pCallBack;
+}
+
+void AliLog::PrintString(Int_t type, FILE* stream, const char* format, ...)
+{
+ // this is the general method to print a log message using variadac args
+ // to the FILE* like (C - like) streams, e.g. stdout, stderr, or files
+ // opened by fopen.
+ // Only in case of an external c++ ostream type output, the message is
+ // written to that stream and the notifictaion callback is called.
+ // The message is printed by a normal vfprintf function otherwise
+
+ if (format==NULL) return;
+
+ va_list ap;
+ va_start(ap, format);
+ if (fOutputTypes[type] != 3) {
+ if (stream!=NULL) {
+ vfprintf(stream, format, ap);
+ }
+ } else {
+ // build the string and write everthing to the corresponding ostream
+ TString fmt(format);
+ TArrayC tgt(fmt.Length()*10); // just take a number
+#ifdef R__VA_COPY
+ va_list bap;
+ R__VA_COPY(bap, ap);
+#else
+#warning definition of R__VA_COPY has disappeared
+#endif //R__VA_COPY
+
+ Int_t iResult=0;
+ while (1) {
+ iResult=vsnprintf(tgt.GetArray(), tgt.GetSize(), format, ap);
+ if (iResult==-1) {
+ iResult=tgt.GetSize()*2;
+ } else if (iResult<tgt.GetSize()) {
+ break;
+ }
+#ifdef R__VA_COPY
+ if (iResult<10000) {
+ tgt.Set(iResult+1);
+ va_end(ap);
+ R__VA_COPY(ap, bap);
+ } else
+#endif //R__VA_COPY
+ {
+ tgt[tgt.GetSize()-1]=0;
+ break;
+ }
+ }
+#ifdef R__VA_COPY
+ va_end(bap);
+#endif //R__VA_COPY
+
+ if (fOutputStreams[type]) {
+ *(fOutputStreams[type]) << tgt.GetArray();
+ }
+ }
+ va_end(ap);
+}