/
ScryMUD/mud/
ScryMUD/mud/grrmud/Boards/
ScryMUD/mud/grrmud/Help/
ScryMUD/mud/grrmud/Pfiles/
ScryMUD/mud/grrmud/PlayerSacks/
ScryMUD/mud/grrmud/PlayerShops/
ScryMUD/mud/grrmud/help_filter/
ScryMUD/mud/hegemon/
ScryMUD/mud/hegemon/data/
ScryMUD/mud/hegemon/data/help/battle/
ScryMUD/mud/hegemon/data/help/client/
ScryMUD/mud/hegemon/data/help/communications/
ScryMUD/mud/hegemon/data/help/skills/
ScryMUD/mud/hegemon/data/help/spells/
ScryMUD/mud/include/
ScryMUD/mud/lib/
ScryMUD/mud/lib/bitfield/
ScryMUD/mud/lib/log/
ScryMUD/mud/lib/string2/
// $Id: LogStream.h,v 1.8.2.3 2000/03/05 04:57:36 justin Exp $
// $Revision: 1.8.2.3 $  $Author: justin $ $Date: 2000/03/05 04:57:36 $

//
//ScryMUD Server Code
//Copyright (C) 1998  Ben Greear
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// To contact the Author, Ben Greear:  greear@cyberhighway.net, (preferred)
//                                     greearb@agcs.com
//

#include <strstream.h>
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#ifndef LOG_STREAM_INCLUDE
#define LOG_STREAM_INCLUDE

#define LOG_STREAM_BUF_SIZE 200000  /* 200 kilobytes storage */


enum LogLevelEnum {
   DIS = 1,   //disasters
   ERROR = 2,   //errors
   WRN = 4,   //warnings
   INF = 8,   //info
   TRC = 16,  //function trace
   DBG = 32,  //debug
   LSEC = 64,  // log security violations
   DB = 128,  // READ or WRITE from the world files
   XMT = 256, // Output from MUD to characters
   INP = 512, // Input from players
   SCRIPT = 1024, //Scripting specific stuff
   PARSE = 2048, //PARSE specific
   DBG2 = 4096,  //More verbose than debug even..
   ALL = ~(0) // all
};//enum

class LogStream;

typedef LogStream& (*__ls_manip)(LogStream&);

class LogStream : public ostrstream {
protected:
   char buf[LOG_STREAM_BUF_SIZE];
   char* filename;
   int log_level;
   int file_action;
public:
   enum actionE {
      APPEND = 0,
      OVERWRITE = 1
   };

   LogStream(const char* fname, int lvl, actionE fileAction)
         : ostrstream(buf, LOG_STREAM_BUF_SIZE),
           log_level(lvl), file_action(fileAction)
      { filename = strdup(fname); }

   LogStream(const char* fname, int lvl)
         : ostrstream(buf, LOG_STREAM_BUF_SIZE),
           log_level(lvl), file_action(OVERWRITE)
      { filename = strdup(fname); }

   ~LogStream() { 
      flushToFile(filename);
      free(filename);
   }

   const char* getFileName() const { return filename; }

   int flushToFile(const char* fname) {
      *((ostrstream*)this) << ends;
      // Allow some outside filtering...
      if (file_action == OVERWRITE) {
         ofstream ofile(fname);
         ofile << str();
         ofile.close();

         char buf[200];
         sprintf(buf, "truncate_log %s", fname);
         system(buf);
      }
      else if (file_action == APPEND) {
         ofstream ofile(fname, ios::app);
         ofile << str();
         ofile.close();
      }

      seekp(0); //Reset the streambuf
      return 0;
   }

   /** The idea is that the << (const char*) method will be called
    * very often.  So, I'm going to over-ride it, and do a check on
    * our buffer usage.  If it's more than 90%, then dump I'm going
    * to flush it and reset myself to the beginning of the buffer.
    */
   LogStream& operator<< (char* msg) {
      return (*this) << (const char*)msg; 
   }

   LogStream& operator<< (const char* msg) {
      *((ostrstream*)this) << msg; 
      if (pcount() > ((float)(LOG_STREAM_BUF_SIZE) * 0.95)) {
         flushToFile(filename);
      }//if
      return *this;
   }//operator overload      

   LogStream& operator<< (const void* ptr) { 
      *((ostrstream*)this) << ptr;
      return *this;
   }

   LogStream& operator<< (int i) { 
      *((ostrstream*)this) << i;
      return *this;
   }

   int ofLevel(LogLevelEnum i) { return ((int)(i) & log_level); }

   int truncate() {
      return 1;
/*
      char buf[200];
      close();

      sprintf(buf, "truncate_log %s", filename);
      system(buf);

      open(filename, ios::app); //open and append
      return 1;
*/
   }//int

   int getLevel() { return log_level; }
   void setLevel(int i) { log_level = i; }

   void log(int lvl, const char* msg);

   void dbg(const char* msg) {
      log(DBG, msg);
   }

   void log(const char* msg) {
      log(DBG, msg);
   }

   LogStream& operator<<(__ls_manip func) { return (*func)(*this); }

};//LogStream


inline LogStream& endl(LogStream& lstr) {
   return lstr << (const char*)("\n");
}

inline LogStream& nl(LogStream& lstr) {
   return lstr << (const char*)("\n");
}

inline LogStream& flush(LogStream& lstr) {
   lstr.flush();
   return lstr;
}

inline void LogStream::log(int lvl, const char* msg) {
   if ((int)(lvl) & log_level) {
      (*this) << msg;
      (*this) << nl;
      flush();
   }
}//log

#endif