+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);
+}