// @(#)root/base:$Id$
// Author: Rene Brun   11/11/99

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMessageHandler                                                      //
//                                                                      //
// Handle messages that might be generated by the system.               //
// By default a handler only keeps track of the different messages      //
// generated for a specific class. By deriving from this class and      //
// overriding Notify() one can implement custom message handling.       //
// In Notify() one has access to the message id and the object          //
// generating the message. One can install more than one message        //
// handler per class. A message handler can be removed or again         //
// added when needed.                                                   //
// All Root "Warnings"  are logged as message 1001                      //
// All Root "Errors"    are logged as message 1002                      //
// All Root "SysErrors" are logged as message 1003                      //
// All Root "Fatals"    are logged as message 1004                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TMessageHandler.h"
#include "TClass.h"
#include "TROOT.h"
#include "TVirtualMutex.h"

ClassImp(TMessageHandler)

//______________________________________________________________________________
TMessageHandler::TMessageHandler(const TClass *cl, Bool_t derived)
{
   // Create a new message handler for class cl and add it to the list
   // of message handlers.

   fClass   = cl;
   fMessObj = 0;
   fMessId  = 0;
   fSize    = 0;
   fCnts    = 0;
   fMessIds = 0;
   fDerived = derived;

   if (fClass)
      SetName(fClass->GetName());
   else
      SetName("DefaultMessageHandler");

   Add();
}

//______________________________________________________________________________
TMessageHandler::TMessageHandler(const char *cl, Bool_t derived)
{
   // Create a new message handler for class named cl and add it to the list
   // of message handlers.

   fClass   = TClass::GetClass(cl);
   fMessObj = 0;
   fMessId  = 0;
   fSize    = 0;
   fCnts    = 0;
   fMessIds = 0;
   fDerived = derived;

   SetName(cl);

   SetName(fClass->GetName());
   Add();
}

//______________________________________________________________________________
TMessageHandler:: ~TMessageHandler()
{
   // Clean up the messagehandler.

   Remove();
   if (fSize <= 0) return;
   delete [] fCnts;
   delete [] fMessIds;
}

//______________________________________________________________________________
void TMessageHandler::Add()
{
   // Add this message handler to the list of messages handlers.

   R__LOCKGUARD2(gROOTMutex);
   gROOT->GetListOfMessageHandlers()->Add(this);
   if (fClass) {
      // don't emit signal when the default message handler is added
      // as this happens in the TROOT ctor and the TQObject stuff is
      // not yet properly initialized on some platforms
      Added();  // emit Added() signal
   }
}

//______________________________________________________________________________
Int_t TMessageHandler::GetMessageCount(Int_t messId) const
{
   // Return counter for message with ID=messid.

   if (fSize <= 0) return 0;
   for (Int_t i = 0; i < fSize; i++) {
      if (fMessIds[i] == messId) return fCnts[i];
   }
   return 0;
}

//______________________________________________________________________________
Int_t TMessageHandler::GetTotalMessageCount() const
{
   // Return total number of messages.

   if (fSize <= 0) return 0;
   Int_t count = 0;
   for (Int_t i = 0; i < fSize; i++) {
      count += fCnts[i];
   }
   return count;
}

//______________________________________________________________________________
void TMessageHandler::HandleMessage(Int_t id, const TObject *obj)
{
   // Store message origin, keep statistics and call Notify().

   // check if message must be managed by this message handler
   if (fClass) {
      if (fDerived) {
         if(!obj->InheritsFrom(fClass)) return;
      } else {
         if (obj->IsA() != fClass) return;
      }
   }

   fMessId  = id;
   fMessObj = obj;

   Notify();

   // increment statistics
   Int_t i;
   // first message
   if (fSize <= 0) {
      fSize    = 1;
      fCnts    = new Int_t[fSize];
      fMessIds = new Int_t[fSize];
   } else {
      // already existing message
      for (i = 0; i < fSize; i++) {
         if (fMessIds[i] == fMessId) {
            fCnts[i]++;
            return;
         }
      }
      // new message
      fSize++;
      Int_t *newCnts    = new Int_t[fSize];
      Int_t *newMessIds = new Int_t[fSize];
      for (i = 0; i < fSize-1; i++) {
         newCnts[i]    = fCnts[i];
         newMessIds[i] = fMessIds[i];
      }
      delete [] fCnts;
      delete [] fMessIds;
      fCnts    = newCnts;
      fMessIds = newMessIds;
   }
   fCnts[fSize-1]    = 1;
   fMessIds[fSize-1] = fMessId;
}

//______________________________________________________________________________
Bool_t TMessageHandler::Notify()
{
   // This method must be overridden to handle object notifcation.

   if (fClass) return kFALSE;
   // case of default handler
   // encode class number in message id
   if (!fMessObj) return kFALSE;
   Int_t uid = Int_t(fMessObj->IsA()->GetUniqueID());
   fMessId += 10000*uid;
   fMessId = -fMessId;
   Notified();  // emit Notified() signal
   return kFALSE;
}

//______________________________________________________________________________
void TMessageHandler::Print(Option_t *) const
{
   // Print statistics for this message handler.

   printf("\n ****** Message Handler: %s has a total of %d messages\n",GetName(),GetTotalMessageCount());
   if (fSize <= 0) return;
   Int_t id, uid;
   const TClass *cl;
   TIter next(gROOT->GetListOfClasses());
   for (Int_t i = 0; i < fSize; i++) {
      id = fMessIds[i];
      cl = fClass;
      if (id < 0) {
         id = -id;
         uid = id/10000;
         id = id%10000;
         next.Reset();
         while ((cl = (TClass*)next())) {
            if (cl->GetUniqueID() == UInt_t(uid)) break;
         }
      }
      if (!cl) cl = gROOT->IsA();
      if (id == 1001) {
         printf("  Class: %-20s WARNINGs       has %d counts\n",cl->GetName(),fCnts[i]);
         continue;
      }
      if (id == 1002) {
         printf("  Class: %-20s ERRORs         has %d counts\n",cl->GetName(),fCnts[i]);
         continue;
      }
      printf("  Class: %-20s MessID = %5d has %d counts\n",cl->GetName(),id,fCnts[i]);
   }
}

//______________________________________________________________________________
void TMessageHandler::Remove()
{
   // Remove this message handler from the list of messages handlers.

   R__LOCKGUARD2(gROOTMutex);
   gROOT->GetListOfMessageHandlers()->Remove(this);
   Removed();  // emit Removed() signal
}
 TMessageHandler.cxx:1
 TMessageHandler.cxx:2
 TMessageHandler.cxx:3
 TMessageHandler.cxx:4
 TMessageHandler.cxx:5
 TMessageHandler.cxx:6
 TMessageHandler.cxx:7
 TMessageHandler.cxx:8
 TMessageHandler.cxx:9
 TMessageHandler.cxx:10
 TMessageHandler.cxx:11
 TMessageHandler.cxx:12
 TMessageHandler.cxx:13
 TMessageHandler.cxx:14
 TMessageHandler.cxx:15
 TMessageHandler.cxx:16
 TMessageHandler.cxx:17
 TMessageHandler.cxx:18
 TMessageHandler.cxx:19
 TMessageHandler.cxx:20
 TMessageHandler.cxx:21
 TMessageHandler.cxx:22
 TMessageHandler.cxx:23
 TMessageHandler.cxx:24
 TMessageHandler.cxx:25
 TMessageHandler.cxx:26
 TMessageHandler.cxx:27
 TMessageHandler.cxx:28
 TMessageHandler.cxx:29
 TMessageHandler.cxx:30
 TMessageHandler.cxx:31
 TMessageHandler.cxx:32
 TMessageHandler.cxx:33
 TMessageHandler.cxx:34
 TMessageHandler.cxx:35
 TMessageHandler.cxx:36
 TMessageHandler.cxx:37
 TMessageHandler.cxx:38
 TMessageHandler.cxx:39
 TMessageHandler.cxx:40
 TMessageHandler.cxx:41
 TMessageHandler.cxx:42
 TMessageHandler.cxx:43
 TMessageHandler.cxx:44
 TMessageHandler.cxx:45
 TMessageHandler.cxx:46
 TMessageHandler.cxx:47
 TMessageHandler.cxx:48
 TMessageHandler.cxx:49
 TMessageHandler.cxx:50
 TMessageHandler.cxx:51
 TMessageHandler.cxx:52
 TMessageHandler.cxx:53
 TMessageHandler.cxx:54
 TMessageHandler.cxx:55
 TMessageHandler.cxx:56
 TMessageHandler.cxx:57
 TMessageHandler.cxx:58
 TMessageHandler.cxx:59
 TMessageHandler.cxx:60
 TMessageHandler.cxx:61
 TMessageHandler.cxx:62
 TMessageHandler.cxx:63
 TMessageHandler.cxx:64
 TMessageHandler.cxx:65
 TMessageHandler.cxx:66
 TMessageHandler.cxx:67
 TMessageHandler.cxx:68
 TMessageHandler.cxx:69
 TMessageHandler.cxx:70
 TMessageHandler.cxx:71
 TMessageHandler.cxx:72
 TMessageHandler.cxx:73
 TMessageHandler.cxx:74
 TMessageHandler.cxx:75
 TMessageHandler.cxx:76
 TMessageHandler.cxx:77
 TMessageHandler.cxx:78
 TMessageHandler.cxx:79
 TMessageHandler.cxx:80
 TMessageHandler.cxx:81
 TMessageHandler.cxx:82
 TMessageHandler.cxx:83
 TMessageHandler.cxx:84
 TMessageHandler.cxx:85
 TMessageHandler.cxx:86
 TMessageHandler.cxx:87
 TMessageHandler.cxx:88
 TMessageHandler.cxx:89
 TMessageHandler.cxx:90
 TMessageHandler.cxx:91
 TMessageHandler.cxx:92
 TMessageHandler.cxx:93
 TMessageHandler.cxx:94
 TMessageHandler.cxx:95
 TMessageHandler.cxx:96
 TMessageHandler.cxx:97
 TMessageHandler.cxx:98
 TMessageHandler.cxx:99
 TMessageHandler.cxx:100
 TMessageHandler.cxx:101
 TMessageHandler.cxx:102
 TMessageHandler.cxx:103
 TMessageHandler.cxx:104
 TMessageHandler.cxx:105
 TMessageHandler.cxx:106
 TMessageHandler.cxx:107
 TMessageHandler.cxx:108
 TMessageHandler.cxx:109
 TMessageHandler.cxx:110
 TMessageHandler.cxx:111
 TMessageHandler.cxx:112
 TMessageHandler.cxx:113
 TMessageHandler.cxx:114
 TMessageHandler.cxx:115
 TMessageHandler.cxx:116
 TMessageHandler.cxx:117
 TMessageHandler.cxx:118
 TMessageHandler.cxx:119
 TMessageHandler.cxx:120
 TMessageHandler.cxx:121
 TMessageHandler.cxx:122
 TMessageHandler.cxx:123
 TMessageHandler.cxx:124
 TMessageHandler.cxx:125
 TMessageHandler.cxx:126
 TMessageHandler.cxx:127
 TMessageHandler.cxx:128
 TMessageHandler.cxx:129
 TMessageHandler.cxx:130
 TMessageHandler.cxx:131
 TMessageHandler.cxx:132
 TMessageHandler.cxx:133
 TMessageHandler.cxx:134
 TMessageHandler.cxx:135
 TMessageHandler.cxx:136
 TMessageHandler.cxx:137
 TMessageHandler.cxx:138
 TMessageHandler.cxx:139
 TMessageHandler.cxx:140
 TMessageHandler.cxx:141
 TMessageHandler.cxx:142
 TMessageHandler.cxx:143
 TMessageHandler.cxx:144
 TMessageHandler.cxx:145
 TMessageHandler.cxx:146
 TMessageHandler.cxx:147
 TMessageHandler.cxx:148
 TMessageHandler.cxx:149
 TMessageHandler.cxx:150
 TMessageHandler.cxx:151
 TMessageHandler.cxx:152
 TMessageHandler.cxx:153
 TMessageHandler.cxx:154
 TMessageHandler.cxx:155
 TMessageHandler.cxx:156
 TMessageHandler.cxx:157
 TMessageHandler.cxx:158
 TMessageHandler.cxx:159
 TMessageHandler.cxx:160
 TMessageHandler.cxx:161
 TMessageHandler.cxx:162
 TMessageHandler.cxx:163
 TMessageHandler.cxx:164
 TMessageHandler.cxx:165
 TMessageHandler.cxx:166
 TMessageHandler.cxx:167
 TMessageHandler.cxx:168
 TMessageHandler.cxx:169
 TMessageHandler.cxx:170
 TMessageHandler.cxx:171
 TMessageHandler.cxx:172
 TMessageHandler.cxx:173
 TMessageHandler.cxx:174
 TMessageHandler.cxx:175
 TMessageHandler.cxx:176
 TMessageHandler.cxx:177
 TMessageHandler.cxx:178
 TMessageHandler.cxx:179
 TMessageHandler.cxx:180
 TMessageHandler.cxx:181
 TMessageHandler.cxx:182
 TMessageHandler.cxx:183
 TMessageHandler.cxx:184
 TMessageHandler.cxx:185
 TMessageHandler.cxx:186
 TMessageHandler.cxx:187
 TMessageHandler.cxx:188
 TMessageHandler.cxx:189
 TMessageHandler.cxx:190
 TMessageHandler.cxx:191
 TMessageHandler.cxx:192
 TMessageHandler.cxx:193
 TMessageHandler.cxx:194
 TMessageHandler.cxx:195
 TMessageHandler.cxx:196
 TMessageHandler.cxx:197
 TMessageHandler.cxx:198
 TMessageHandler.cxx:199
 TMessageHandler.cxx:200
 TMessageHandler.cxx:201
 TMessageHandler.cxx:202
 TMessageHandler.cxx:203
 TMessageHandler.cxx:204
 TMessageHandler.cxx:205
 TMessageHandler.cxx:206
 TMessageHandler.cxx:207
 TMessageHandler.cxx:208
 TMessageHandler.cxx:209
 TMessageHandler.cxx:210
 TMessageHandler.cxx:211
 TMessageHandler.cxx:212
 TMessageHandler.cxx:213
 TMessageHandler.cxx:214
 TMessageHandler.cxx:215
 TMessageHandler.cxx:216
 TMessageHandler.cxx:217
 TMessageHandler.cxx:218
 TMessageHandler.cxx:219
 TMessageHandler.cxx:220
 TMessageHandler.cxx:221
 TMessageHandler.cxx:222
 TMessageHandler.cxx:223
 TMessageHandler.cxx:224
 TMessageHandler.cxx:225
 TMessageHandler.cxx:226
 TMessageHandler.cxx:227
 TMessageHandler.cxx:228
 TMessageHandler.cxx:229
 TMessageHandler.cxx:230
 TMessageHandler.cxx:231
 TMessageHandler.cxx:232
 TMessageHandler.cxx:233
 TMessageHandler.cxx:234
 TMessageHandler.cxx:235
 TMessageHandler.cxx:236
 TMessageHandler.cxx:237
 TMessageHandler.cxx:238
 TMessageHandler.cxx:239
 TMessageHandler.cxx:240
 TMessageHandler.cxx:241
 TMessageHandler.cxx:242