<commit_before>// @(#)root/base:$Id$
// Author: Fons Rademakers   29/07/95

/*************************************************************************
 * 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.             *
 *************************************************************************/

/**
Error handling routines.

This file defines a number of global error handling routines:
Warning(), Error(), SysError() and Fatal(). They all take a
location string (where the error happened) and a printf style format
string plus vararg's. In the end these functions call an
errorhandler function. By default DefaultErrorHandler() is used.
*/

#ifdef WIN32
#include <windows.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include "snprintf.h"
#include "Varargs.h"
#include "Riostream.h"
#include "TError.h"
#include "TSystem.h"
#include "TString.h"
#include "TEnv.h"
#include "TVirtualMutex.h"
#include "ThreadLocalStorage.h"

// Mutex for error and error format protection
// (exported to be used for similar cases in other classes)

TVirtualMutex *gErrorMutex = 0;

Int_t  gErrorIgnoreLevel     = kUnset;
Int_t  gErrorAbortLevel      = kSysError+1;
Bool_t gPrintViaErrorHandler = kFALSE;

const char *kAssertMsg = "%s violated at line %d of `%s'";
const char *kCheckMsg  = "%s not true at line %d of `%s'";

// Integrate with crash reporter.
#ifdef __APPLE__
extern "C" {
static const char *__crashreporter_info__ = 0;
asm(".desc ___crashreporter_info__, 0x10");
}
#endif

static ErrorHandlerFunc_t gErrorHandler = DefaultErrorHandler;

////////////////////////////////////////////////////////////////////////////////
/// Print debugging message to stderr and, on Windows, to the system debugger.

static void DebugPrint(const char *fmt, ...)
{
   TTHREAD_TLS(Int_t) buf_size = 2048;
   TTHREAD_TLS(char*) buf = 0;

   va_list ap;
   va_start(ap, fmt);

again:
   if (!buf)
      buf = new char[buf_size];

   Int_t n = vsnprintf(buf, buf_size, fmt, ap);
   // old vsnprintf's return -1 if string is truncated new ones return
   // total number of characters that would have been written
   if (n == -1 || n >= buf_size) {
      if (n == -1)
         buf_size *= 2;
      else
         buf_size = n+1;
      delete [] buf;
      buf = 0;
      va_end(ap);
      va_start(ap, fmt);
      goto again;
   }
   va_end(ap);

   // Serialize the actual printing.
   R__LOCKGUARD2(gErrorMutex);

   const char *toprint = buf; // Work around for older platform where we use TThreadTLSWrapper
   fprintf(stderr, "%s", toprint);

#ifdef WIN32
   ::OutputDebugString(buf);
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// Set an errorhandler function. Returns the old handler.

ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
{
   ErrorHandlerFunc_t oldhandler = gErrorHandler;
   gErrorHandler = newhandler;
   return oldhandler;
}

////////////////////////////////////////////////////////////////////////////////
/// Returns the current error handler function.

ErrorHandlerFunc_t GetErrorHandler()
{
   return gErrorHandler;
}

////////////////////////////////////////////////////////////////////////////////
/// The default error handler function. It prints the message on stderr and
/// if abort is set it aborts the application.

void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
{
   if (gErrorIgnoreLevel == kUnset) {
      R__LOCKGUARD2(gErrorMutex);

      gErrorIgnoreLevel = 0;
      if (gEnv) {
         TString slevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
         if (!slevel.CompareTo("Print", TString::kIgnoreCase))
            gErrorIgnoreLevel = kPrint;
         else if (!slevel.CompareTo("Info", TString::kIgnoreCase))
            gErrorIgnoreLevel = kInfo;
         else if (!slevel.CompareTo("Warning", TString::kIgnoreCase))
            gErrorIgnoreLevel = kWarning;
         else if (!slevel.CompareTo("Error", TString::kIgnoreCase))
            gErrorIgnoreLevel = kError;
         else if (!slevel.CompareTo("Break", TString::kIgnoreCase))
            gErrorIgnoreLevel = kBreak;
         else if (!slevel.CompareTo("SysError", TString::kIgnoreCase))
            gErrorIgnoreLevel = kSysError;
         else if (!slevel.CompareTo("Fatal", TString::kIgnoreCase))
            gErrorIgnoreLevel = kFatal;
      }
   }

   if (level < gErrorIgnoreLevel)
      return;

   const char *type = 0;

   if (level >= kInfo)
      type = "Info";
   if (level >= kWarning)
      type = "Warning";
   if (level >= kError)
      type = "Error";
   if (level >= kBreak)
      type = "\n *** Break ***";
   if (level >= kSysError)
      type = "SysError";
   if (level >= kFatal)
      type = "Fatal";

   TString smsg;
   if (level >= kPrint && level < kInfo)
      smsg.Form("%s", msg);
   else if (level >= kBreak && level < kSysError)
      smsg.Form("%s %s", type, msg);
   else if (!location || !location[0])
      smsg.Form("%s: %s", type, msg);
   else
      smsg.Form("%s in <%s>: %s", type, location, msg);

   DebugPrint("%s\n", smsg.Data());

   fflush(stderr);
   if (abort_bool) {

#ifdef __APPLE__
      if (__crashreporter_info__)
         delete [] __crashreporter_info__;
      __crashreporter_info__ = StrDup(smsg);
#endif

      DebugPrint("aborting\n");
      fflush(stderr);
      if (gSystem) {
         gSystem->StackTrace();
         gSystem->Abort();
      } else
         abort();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// General error handler function. It calls the user set error handler.

void ErrorHandler(Int_t level, const char *location, const char *fmt, va_list ap)
{
   TTHREAD_TLS(Int_t) buf_size(256);
   TTHREAD_TLS(char*) buf_storage(0);

   char small_buf[256];
   char *buf = buf_storage ? buf_storage : small_buf;

   int vc = 0;
   va_list sap;
   R__VA_COPY(sap, ap);

again:
   if (!buf) {
      buf_storage = buf = new char[buf_size];
   }

   if (!fmt)
      fmt = "no error message provided";

   Int_t n = vsnprintf(buf, buf_size, fmt, ap);
   // old vsnprintf's return -1 if string is truncated new ones return
   // total number of characters that would have been written
   if (n == -1 || n >= buf_size) {
      if (n == -1)
         buf_size *= 2;
      else
         buf_size = n+1;
      if (buf != &(small_buf[0])) delete [] buf;
      buf = 0;
      va_end(ap);
      R__VA_COPY(ap, sap);
      vc = 1;
      goto again;
   }
   va_end(sap);
   if (vc)
      va_end(ap);

   char *bp;
   if (level >= kSysError && level < kFatal) {
      const char *toprint = buf; // Work around for older platform where we use TThreadTLSWrapper
      bp = Form("%s (%s)", toprint, gSystem->GetError());
   } else
      bp = buf;

   if (level != kFatal)
      gErrorHandler(level, level >= gErrorAbortLevel, location, bp);
   else
      gErrorHandler(level, kTRUE, location, bp);
}

////////////////////////////////////////////////////////////////////////////////
/// This function can be used in abstract base classes in case one does
/// not want to make the class a "real" (in C++ sense) ABC. If this
/// function is called it will warn the user that the function should
/// have been overridden.

void AbstractMethod(const char *method)
{
   Warning(method, "this method must be overridden!");
}

////////////////////////////////////////////////////////////////////////////////
/// This function can be used in classes that should override a certain
/// function, but in the inherited class the function makes no sense.

void MayNotUse(const char *method)
{
   Warning(method, "may not use this method");
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function to declare a function obsolete. Specify as of which version
/// the method is obsolete and as from which version it will be removed.

void Obsolete(const char *function, const char *asOfVers, const char *removedFromVers)
{
   TString mess;
   mess.Form("obsolete as of %s and will be removed from %s", asOfVers, removedFromVers);
   Warning(function, "%s", mess.Data());
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in case an error occurred.

void Error(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kError, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in case a system (OS or GUI) related error occurred.

void SysError(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap, va_(fmt));
   ErrorHandler(kSysError, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in case an error occurred.

void Break(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kBreak, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function for informational messages.

void Info(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kInfo, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in warning situations.

void Warning(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kWarning, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in case of a fatal error. It will abort the program.

void Fatal(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kFatal, location, va_(fmt), ap);
   va_end(ap);
}
<commit_msg>Claim to Coverity that Fatal() aborts, allways.<commit_after>// @(#)root/base:$Id$
// Author: Fons Rademakers   29/07/95

/*************************************************************************
 * 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.             *
 *************************************************************************/

/**
Error handling routines.

This file defines a number of global error handling routines:
Warning(), Error(), SysError() and Fatal(). They all take a
location string (where the error happened) and a printf style format
string plus vararg's. In the end these functions call an
errorhandler function. By default DefaultErrorHandler() is used.
*/

#ifdef WIN32
#include <windows.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include "snprintf.h"
#include "Varargs.h"
#include "Riostream.h"
#include "TError.h"
#include "TSystem.h"
#include "TString.h"
#include "TEnv.h"
#include "TVirtualMutex.h"
#include "ThreadLocalStorage.h"

// Mutex for error and error format protection
// (exported to be used for similar cases in other classes)

TVirtualMutex *gErrorMutex = 0;

Int_t  gErrorIgnoreLevel     = kUnset;
Int_t  gErrorAbortLevel      = kSysError+1;
Bool_t gPrintViaErrorHandler = kFALSE;

const char *kAssertMsg = "%s violated at line %d of `%s'";
const char *kCheckMsg  = "%s not true at line %d of `%s'";

// Integrate with crash reporter.
#ifdef __APPLE__
extern "C" {
static const char *__crashreporter_info__ = 0;
asm(".desc ___crashreporter_info__, 0x10");
}
#endif

static ErrorHandlerFunc_t gErrorHandler = DefaultErrorHandler;

////////////////////////////////////////////////////////////////////////////////
/// Print debugging message to stderr and, on Windows, to the system debugger.

static void DebugPrint(const char *fmt, ...)
{
   TTHREAD_TLS(Int_t) buf_size = 2048;
   TTHREAD_TLS(char*) buf = 0;

   va_list ap;
   va_start(ap, fmt);

again:
   if (!buf)
      buf = new char[buf_size];

   Int_t n = vsnprintf(buf, buf_size, fmt, ap);
   // old vsnprintf's return -1 if string is truncated new ones return
   // total number of characters that would have been written
   if (n == -1 || n >= buf_size) {
      if (n == -1)
         buf_size *= 2;
      else
         buf_size = n+1;
      delete [] buf;
      buf = 0;
      va_end(ap);
      va_start(ap, fmt);
      goto again;
   }
   va_end(ap);

   // Serialize the actual printing.
   R__LOCKGUARD2(gErrorMutex);

   const char *toprint = buf; // Work around for older platform where we use TThreadTLSWrapper
   fprintf(stderr, "%s", toprint);

#ifdef WIN32
   ::OutputDebugString(buf);
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// Set an errorhandler function. Returns the old handler.

ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
{
   ErrorHandlerFunc_t oldhandler = gErrorHandler;
   gErrorHandler = newhandler;
   return oldhandler;
}

////////////////////////////////////////////////////////////////////////////////
/// Returns the current error handler function.

ErrorHandlerFunc_t GetErrorHandler()
{
   return gErrorHandler;
}

////////////////////////////////////////////////////////////////////////////////
/// The default error handler function. It prints the message on stderr and
/// if abort is set it aborts the application.

void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
{
   if (gErrorIgnoreLevel == kUnset) {
      R__LOCKGUARD2(gErrorMutex);

      gErrorIgnoreLevel = 0;
      if (gEnv) {
         TString slevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
         if (!slevel.CompareTo("Print", TString::kIgnoreCase))
            gErrorIgnoreLevel = kPrint;
         else if (!slevel.CompareTo("Info", TString::kIgnoreCase))
            gErrorIgnoreLevel = kInfo;
         else if (!slevel.CompareTo("Warning", TString::kIgnoreCase))
            gErrorIgnoreLevel = kWarning;
         else if (!slevel.CompareTo("Error", TString::kIgnoreCase))
            gErrorIgnoreLevel = kError;
         else if (!slevel.CompareTo("Break", TString::kIgnoreCase))
            gErrorIgnoreLevel = kBreak;
         else if (!slevel.CompareTo("SysError", TString::kIgnoreCase))
            gErrorIgnoreLevel = kSysError;
         else if (!slevel.CompareTo("Fatal", TString::kIgnoreCase))
            gErrorIgnoreLevel = kFatal;
      }
   }

   if (level < gErrorIgnoreLevel)
      return;

   const char *type = 0;

   if (level >= kInfo)
      type = "Info";
   if (level >= kWarning)
      type = "Warning";
   if (level >= kError)
      type = "Error";
   if (level >= kBreak)
      type = "\n *** Break ***";
   if (level >= kSysError)
      type = "SysError";
   if (level >= kFatal)
      type = "Fatal";

   TString smsg;
   if (level >= kPrint && level < kInfo)
      smsg.Form("%s", msg);
   else if (level >= kBreak && level < kSysError)
      smsg.Form("%s %s", type, msg);
   else if (!location || !location[0])
      smsg.Form("%s: %s", type, msg);
   else
      smsg.Form("%s in <%s>: %s", type, location, msg);

   DebugPrint("%s\n", smsg.Data());

   fflush(stderr);
   if (abort_bool) {

#ifdef __APPLE__
      if (__crashreporter_info__)
         delete [] __crashreporter_info__;
      __crashreporter_info__ = StrDup(smsg);
#endif

      DebugPrint("aborting\n");
      fflush(stderr);
      if (gSystem) {
         gSystem->StackTrace();
         gSystem->Abort();
      } else
         abort();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// General error handler function. It calls the user set error handler.

void ErrorHandler(Int_t level, const char *location, const char *fmt, va_list ap)
{
   TTHREAD_TLS(Int_t) buf_size(256);
   TTHREAD_TLS(char*) buf_storage(0);

   char small_buf[256];
   char *buf = buf_storage ? buf_storage : small_buf;

   int vc = 0;
   va_list sap;
   R__VA_COPY(sap, ap);

again:
   if (!buf) {
      buf_storage = buf = new char[buf_size];
   }

   if (!fmt)
      fmt = "no error message provided";

   Int_t n = vsnprintf(buf, buf_size, fmt, ap);
   // old vsnprintf's return -1 if string is truncated new ones return
   // total number of characters that would have been written
   if (n == -1 || n >= buf_size) {
      if (n == -1)
         buf_size *= 2;
      else
         buf_size = n+1;
      if (buf != &(small_buf[0])) delete [] buf;
      buf = 0;
      va_end(ap);
      R__VA_COPY(ap, sap);
      vc = 1;
      goto again;
   }
   va_end(sap);
   if (vc)
      va_end(ap);

   char *bp;
   if (level >= kSysError && level < kFatal) {
      const char *toprint = buf; // Work around for older platform where we use TThreadTLSWrapper
      bp = Form("%s (%s)", toprint, gSystem->GetError());
   } else
      bp = buf;

   if (level != kFatal)
      gErrorHandler(level, level >= gErrorAbortLevel, location, bp);
   else
      gErrorHandler(level, kTRUE, location, bp);
}

////////////////////////////////////////////////////////////////////////////////
/// This function can be used in abstract base classes in case one does
/// not want to make the class a "real" (in C++ sense) ABC. If this
/// function is called it will warn the user that the function should
/// have been overridden.

void AbstractMethod(const char *method)
{
   Warning(method, "this method must be overridden!");
}

////////////////////////////////////////////////////////////////////////////////
/// This function can be used in classes that should override a certain
/// function, but in the inherited class the function makes no sense.

void MayNotUse(const char *method)
{
   Warning(method, "may not use this method");
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function to declare a function obsolete. Specify as of which version
/// the method is obsolete and as from which version it will be removed.

void Obsolete(const char *function, const char *asOfVers, const char *removedFromVers)
{
   TString mess;
   mess.Form("obsolete as of %s and will be removed from %s", asOfVers, removedFromVers);
   Warning(function, "%s", mess.Data());
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in case an error occurred.

void Error(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kError, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in case a system (OS or GUI) related error occurred.

void SysError(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap, va_(fmt));
   ErrorHandler(kSysError, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in case an error occurred.

void Break(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kBreak, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function for informational messages.

void Info(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kInfo, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in warning situations.

void Warning(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kWarning, location, va_(fmt), ap);
   va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////
/// Use this function in case of a fatal error. It will abort the program.

// Fatal() *might* not abort the program (if gAbortLevel > kFatal) - but for all
// reasonable settings it *will* abort. So let's be reasonable wrt Coverity:
// coverity[+kill]
void Fatal(const char *location, const char *va_(fmt), ...)
{
   va_list ap;
   va_start(ap,va_(fmt));
   ErrorHandler(kFatal, location, va_(fmt), ap);
   va_end(ap);
}
<|endoftext|>


<commit_before>// @(#)root/base:$Id$
// Author: Fons Rademakers   28/11/96

/*************************************************************************
 * 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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TTimer                                                               //
//                                                                      //
// Handles synchronous and a-synchronous timer events.                  //
// 1. synchronous timer is registered into TSystem and is processed     //
//    within the standard ROOT event-loop.                              //
// 2. asynchronous timer is passed to the operating system which sends  //
//    an external signal to ROOT and thus interrupts its event-loop.    //
//                                                                      //
// You can use this class in one of the following ways:                 //
//    - Sub-class TTimer and override the Notify() method.              //
//    - Re-implement the TObject::HandleTimer() method in your class    //
//      and pass a pointer to this object to timer, see the SetObject() //
//      method.                                                         //
//    - Pass an interpreter command to timer, see SetCommand() method.  //
//    - Create a TTimer, connect its Timeout() signal to the            //
//      appropriate methods. Then when the time is up it will emit a    //
//      Timeout() signal and call connected slots.                      //
//                                                                      //
//  Minimum timeout interval is defined in TSystem::ESysConstants as    //
//  kItimerResolution (currently 10 ms).                                //
//                                                                      //
//  Signal/slots example:                                               //
//       TTimer *timer = new TTimer();                                  //
//       timer->Connect("Timeout()", "myObjectClassName",               //
//                      myObject, "TimerDone()");                       //
//       timer->Start(2000, kTRUE);   // 2 seconds single-shot          //
//                                                                      //
//  To emit the Timeout signal repeadetly with minimum timeout:         //
//       timer->Start(0, kFALSE);                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TTimer.h"
#include "TSystem.h"
#include "TROOT.h"

ClassImp(TTimer)

class TSingleShotCleaner : public TTimer {
private:
   TList  *fGarbage;
public:
   TSingleShotCleaner() : TTimer(10, kTRUE) { fGarbage = new TList(); }
   virtual ~TSingleShotCleaner() { fGarbage->Delete(); delete fGarbage; }
   void TurnOn() {
      TObject *obj = (TObject*) gTQSender;
      fGarbage->Add(obj);
      Reset();
      if (gSystem)
         gSystem->AddTimer(this);
   }
   Bool_t Notify() {
      fGarbage->Delete();
      Reset();
      if (gSystem)
         gSystem->RemoveTimer(this);
      return kTRUE;
   }
};

//______________________________________________________________________________
TTimer::TTimer(Long_t ms, Bool_t mode) : fTime(ms)
{
   // Create timer that times out in ms milliseconds. If milliSec is 0
   // then the timeout will be the minimum timeout (see TSystem::ESysConstants,
   // i.e. 10 ms). If mode == kTRUE then the timer is synchronous else
   // a-synchronous. The default is synchronous. Add a timer to the system
   // eventloop by calling TurnOn(). Set command to be executed from Notify()
   // or set the object whose HandleTimer() method will be called via Notify(),
   // derive from TTimer and override Notify() or connect slots to the
   // signals Timeout(), TurnOn() and TurnOff().

   fObject      = 0;
   fCommand     = "";
   fSync        = mode;
   fIntSyscalls = kFALSE;
   Reset();
}

//______________________________________________________________________________
TTimer::TTimer(TObject *obj, Long_t ms, Bool_t mode) : fTime(ms)
{
   // Create timer that times out in ms milliseconds. If mode == kTRUE then
   // the timer is synchronous else a-synchronous. The default is synchronous.
   // Add a timer to the system eventloop by calling TurnOn().
   // The object's HandleTimer() will be called by Notify().

   fObject      = obj;
   fCommand     = "";
   fSync        = mode;
   fIntSyscalls = kFALSE;
   Reset();
}

//______________________________________________________________________________
TTimer::TTimer(const char *command, Long_t ms, Bool_t mode) : fTime(ms)
{
   // Create timer that times out in ms milliseconds. If mode == kTRUE then
   // the timer is synchronous else a-synchronous. The default is synchronous.
   // Add a timer to the system eventloop by calling TurnOn().
   // The interpreter will execute command from Notify().

   fObject      = 0;
   fCommand     = command;
   fSync        = mode;
   fIntSyscalls = kFALSE;
   Reset();
}

//______________________________________________________________________________
Bool_t TTimer::CheckTimer(const TTime &now)
{
   // Check if timer timed out.

   if (fAbsTime <= now) {
      fTimeout = kTRUE;
      Notify();
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TTimer::Notify()
{
   // Notify when timer times out. The timer is always reset. To stop
   // the timer call TurnOff().

   Timeout();       // emit Timeout() signal
   if (fObject) fObject->HandleTimer(this);
   if (fCommand && fCommand.Length() > 0)
      gROOT->ProcessLine(fCommand);

   Reset();
   return kTRUE;
}

//______________________________________________________________________________
void TTimer::Reset()
{
   // Reset the timer.

   // make sure gSystem exists
   ROOT::GetROOT();

   fTimeout = kFALSE;
   fAbsTime = fTime;
   if (gSystem) {
      fAbsTime += gSystem->Now();
      if (!fSync) gSystem->ResetTimer(this);
   }
}

//______________________________________________________________________________
void TTimer::SetCommand(const char *command)
{
   // Set the interpreter command to be executed at time out. Removes the
   // object to be notified (if it was set).

   fObject  = 0;
   fCommand = command;
}

//______________________________________________________________________________
void TTimer::SetObject(TObject *object)
{
   // Set the object to be notified  at time out. Removes the command to
   // be executed (if it was set).

   fObject  = object;
   fCommand = "";
}

//______________________________________________________________________________
void TTimer::SetInterruptSyscalls(Bool_t set)
{
   // When the argument is true the a-synchronous timer (SIGALRM) signal
   // handler is set so that interrupted syscalls will not be restarted
   // by the kernel. This is typically used in case one wants to put a
   // timeout on an I/O operation. By default interrupted syscalls will
   // be restarted.

   fIntSyscalls = set;
}

//___________________________________________________________________
void TTimer::Start(Long_t milliSec, Bool_t singleShot)
{
   // Starts the timer with a milliSec timeout. If milliSec is 0
   // then the timeout will be the minimum timeout (see TSystem::ESysConstants,
   // i.e. 10 ms), if milliSec is -1 then the time interval as previously
   // specified (in ctor or SetTime()) will be used.
   // If singleShot is kTRUE, the timer will be activated only once,
   // otherwise it will continue until it is stopped.
   // See also TurnOn(), Stop(), TurnOff().

   if (milliSec >= 0)
      SetTime(milliSec);
   Reset();
   TurnOn();
   if (singleShot)
      Connect(this, "Timeout()", "TTimer", this, "TurnOff()");
   else
      Disconnect(this, "Timeout()", this, "TurnOff()");
}

//______________________________________________________________________________
void TTimer::TurnOff()
{
   // Remove timer from system timer list. This requires that a timer
   // has been placed in the system timer list (using TurnOn()).
   // If a TTimer subclass is placed on another list, override TurnOff() to
   // remove the timer from the correct list.

   if (gSystem)
      if (gSystem->RemoveTimer(this))
         Emit("TurnOff()");
}

//______________________________________________________________________________
void TTimer::TurnOn()
{
   // Add the timer to the system timer list. If a TTimer subclass has to be
   // placed on another list, override TurnOn() to add the timer to the correct
   // list.

   // might have been set in a previous Start()
   Disconnect(this, "Timeout()", this, "TurnOff()");

   if (gSystem) {
      gSystem->AddTimer(this);
      Emit("TurnOn()");
   }
}

//______________________________________________________________________________
void TTimer::SingleShot(Int_t milliSec, const char *receiver_class,
                        void *receiver, const char *method)
{
   // This static function calls a slot after a given time interval.
   // Created internal timer will be deleted after that.

   TTimer *singleShotTimer = new TTimer(milliSec);
   TQObject::Connect(singleShotTimer, "Timeout()",
                     receiver_class, receiver, method);

   static TSingleShotCleaner singleShotCleaner;  // single shot timer cleaner

   // gSingleShotCleaner will delete singleShotTimer a
   // short period after Timeout() signal is emitted
   TQObject::Connect(singleShotTimer, "Timeout()",
                     "TTimer", &singleShotCleaner, "TurnOn()");

   singleShotTimer->Start(milliSec, kTRUE);
}
<commit_msg>add extra comment to call Reset() also in derived Notify().<commit_after>// @(#)root/base:$Id$
// Author: Fons Rademakers   28/11/96

/*************************************************************************
 * 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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TTimer                                                               //
//                                                                      //
// Handles synchronous and a-synchronous timer events.                  //
// 1. synchronous timer is registered into TSystem and is processed     //
//    within the standard ROOT event-loop.                              //
// 2. asynchronous timer is passed to the operating system which sends  //
//    an external signal to ROOT and thus interrupts its event-loop.    //
//                                                                      //
// You can use this class in one of the following ways:                 //
//    - Sub-class TTimer and override the Notify() method.              //
//    - Re-implement the TObject::HandleTimer() method in your class    //
//      and pass a pointer to this object to timer, see the SetObject() //
//      method.                                                         //
//    - Pass an interpreter command to timer, see SetCommand() method.  //
//    - Create a TTimer, connect its Timeout() signal to the            //
//      appropriate methods. Then when the time is up it will emit a    //
//      Timeout() signal and call connected slots.                      //
//                                                                      //
//  Minimum timeout interval is defined in TSystem::ESysConstants as    //
//  kItimerResolution (currently 10 ms).                                //
//                                                                      //
//  Signal/slots example:                                               //
//       TTimer *timer = new TTimer();                                  //
//       timer->Connect("Timeout()", "myObjectClassName",               //
//                      myObject, "TimerDone()");                       //
//       timer->Start(2000, kTRUE);   // 2 seconds single-shot          //
//                                                                      //
//  To emit the Timeout signal repeadetly with minimum timeout:         //
//       timer->Start(0, kFALSE);                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TTimer.h"
#include "TSystem.h"
#include "TROOT.h"

ClassImp(TTimer)

class TSingleShotCleaner : public TTimer {
private:
   TList  *fGarbage;
public:
   TSingleShotCleaner() : TTimer(10, kTRUE) { fGarbage = new TList(); }
   virtual ~TSingleShotCleaner() { fGarbage->Delete(); delete fGarbage; }
   void TurnOn() {
      TObject *obj = (TObject*) gTQSender;
      fGarbage->Add(obj);
      Reset();
      if (gSystem)
         gSystem->AddTimer(this);
   }
   Bool_t Notify() {
      fGarbage->Delete();
      Reset();
      if (gSystem)
         gSystem->RemoveTimer(this);
      return kTRUE;
   }
};

//______________________________________________________________________________
TTimer::TTimer(Long_t ms, Bool_t mode) : fTime(ms)
{
   // Create timer that times out in ms milliseconds. If milliSec is 0
   // then the timeout will be the minimum timeout (see TSystem::ESysConstants,
   // i.e. 10 ms). If mode == kTRUE then the timer is synchronous else
   // a-synchronous. The default is synchronous. Add a timer to the system
   // eventloop by calling TurnOn(). Set command to be executed from Notify()
   // or set the object whose HandleTimer() method will be called via Notify(),
   // derive from TTimer and override Notify() or connect slots to the
   // signals Timeout(), TurnOn() and TurnOff().

   fObject      = 0;
   fCommand     = "";
   fSync        = mode;
   fIntSyscalls = kFALSE;
   Reset();
}

//______________________________________________________________________________
TTimer::TTimer(TObject *obj, Long_t ms, Bool_t mode) : fTime(ms)
{
   // Create timer that times out in ms milliseconds. If mode == kTRUE then
   // the timer is synchronous else a-synchronous. The default is synchronous.
   // Add a timer to the system eventloop by calling TurnOn().
   // The object's HandleTimer() will be called by Notify().

   fObject      = obj;
   fCommand     = "";
   fSync        = mode;
   fIntSyscalls = kFALSE;
   Reset();
}

//______________________________________________________________________________
TTimer::TTimer(const char *command, Long_t ms, Bool_t mode) : fTime(ms)
{
   // Create timer that times out in ms milliseconds. If mode == kTRUE then
   // the timer is synchronous else a-synchronous. The default is synchronous.
   // Add a timer to the system eventloop by calling TurnOn().
   // The interpreter will execute command from Notify().

   fObject      = 0;
   fCommand     = command;
   fSync        = mode;
   fIntSyscalls = kFALSE;
   Reset();
}

//______________________________________________________________________________
Bool_t TTimer::CheckTimer(const TTime &now)
{
   // Check if timer timed out.

   if (fAbsTime <= now) {
      fTimeout = kTRUE;
      Notify();
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TTimer::Notify()
{
   // Notify when timer times out. The timer is always reset. To stop
   // the timer call TurnOff(). Make sure to call Reset() also in derived
   // Notify() so timers will keep working repeatedly.

   Timeout();       // emit Timeout() signal
   if (fObject) fObject->HandleTimer(this);
   if (fCommand && fCommand.Length() > 0)
      gROOT->ProcessLine(fCommand);

   Reset();
   return kTRUE;
}

//______________________________________________________________________________
void TTimer::Reset()
{
   // Reset the timer.

   // make sure gSystem exists
   ROOT::GetROOT();

   fTimeout = kFALSE;
   fAbsTime = fTime;
   if (gSystem) {
      fAbsTime += gSystem->Now();
      if (!fSync) gSystem->ResetTimer(this);
   }
}

//______________________________________________________________________________
void TTimer::SetCommand(const char *command)
{
   // Set the interpreter command to be executed at time out. Removes the
   // object to be notified (if it was set).

   fObject  = 0;
   fCommand = command;
}

//______________________________________________________________________________
void TTimer::SetObject(TObject *object)
{
   // Set the object to be notified  at time out. Removes the command to
   // be executed (if it was set).

   fObject  = object;
   fCommand = "";
}

//______________________________________________________________________________
void TTimer::SetInterruptSyscalls(Bool_t set)
{
   // When the argument is true the a-synchronous timer (SIGALRM) signal
   // handler is set so that interrupted syscalls will not be restarted
   // by the kernel. This is typically used in case one wants to put a
   // timeout on an I/O operation. By default interrupted syscalls will
   // be restarted.

   fIntSyscalls = set;
}

//___________________________________________________________________
void TTimer::Start(Long_t milliSec, Bool_t singleShot)
{
   // Starts the timer with a milliSec timeout. If milliSec is 0
   // then the timeout will be the minimum timeout (see TSystem::ESysConstants,
   // i.e. 10 ms), if milliSec is -1 then the time interval as previously
   // specified (in ctor or SetTime()) will be used.
   // If singleShot is kTRUE, the timer will be activated only once,
   // otherwise it will continue until it is stopped.
   // See also TurnOn(), Stop(), TurnOff().

   if (milliSec >= 0)
      SetTime(milliSec);
   Reset();
   TurnOn();
   if (singleShot)
      Connect(this, "Timeout()", "TTimer", this, "TurnOff()");
   else
      Disconnect(this, "Timeout()", this, "TurnOff()");
}

//______________________________________________________________________________
void TTimer::TurnOff()
{
   // Remove timer from system timer list. This requires that a timer
   // has been placed in the system timer list (using TurnOn()).
   // If a TTimer subclass is placed on another list, override TurnOff() to
   // remove the timer from the correct list.

   if (gSystem)
      if (gSystem->RemoveTimer(this))
         Emit("TurnOff()");
}

//______________________________________________________________________________
void TTimer::TurnOn()
{
   // Add the timer to the system timer list. If a TTimer subclass has to be
   // placed on another list, override TurnOn() to add the timer to the correct
   // list.

   // might have been set in a previous Start()
   Disconnect(this, "Timeout()", this, "TurnOff()");

   if (gSystem) {
      gSystem->AddTimer(this);
      Emit("TurnOn()");
   }
}

//______________________________________________________________________________
void TTimer::SingleShot(Int_t milliSec, const char *receiver_class,
                        void *receiver, const char *method)
{
   // This static function calls a slot after a given time interval.
   // Created internal timer will be deleted after that.

   TTimer *singleShotTimer = new TTimer(milliSec);
   TQObject::Connect(singleShotTimer, "Timeout()",
                     receiver_class, receiver, method);

   static TSingleShotCleaner singleShotCleaner;  // single shot timer cleaner

   // gSingleShotCleaner will delete singleShotTimer a
   // short period after Timeout() signal is emitted
   TQObject::Connect(singleShotTimer, "Timeout()",
                     "TTimer", &singleShotCleaner, "TurnOn()");

   singleShotTimer->Start(milliSec, kTRUE);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/smart_ref_impl.hpp>

namespace fc
{
   // explicitly instantiate the smart_ref, gcc fails to instantiate it in some release builds
   //template graphene::chain::fee_schedule& smart_ref<graphene::chain::fee_schedule>::operator=(smart_ref<graphene::chain::fee_schedule>&&);
   //template graphene::chain::fee_schedule& smart_ref<graphene::chain::fee_schedule>::operator=(U&&);
   //template graphene::chain::fee_schedule& smart_ref<graphene::chain::fee_schedule>::operator=(const smart_ref&);
   //template smart_ref<graphene::chain::fee_schedule>::smart_ref();
   //template const graphene::chain::fee_schedule& smart_ref<graphene::chain::fee_schedule>::operator*() const;
}

#define MAX_FEE_STABILIZATION_ITERATION 4

namespace graphene { namespace chain {

   typedef fc::smart_ref<fee_schedule> smart_fee_schedule;

   fee_schedule::fee_schedule()
   {
   }

   fee_schedule fee_schedule::get_default()
   {
      fee_schedule result;
      for( int i = 0; i < fee_parameters().count(); ++i )
      {
         fee_parameters x; x.set_which(i);
         result.parameters.insert(x);
      }
      return result;
   }

   struct fee_schedule_validate_visitor
   {
      typedef void result_type;

      template<typename T>
      void operator()( const T& p )const
      {
         //p.validate();
      }
   };

   void fee_schedule::validate()const
   {
      for( const auto& f : parameters )
         f.visit( fee_schedule_validate_visitor() );
   }

   struct calc_fee_visitor
   {
      typedef uint64_t result_type;

      const fee_parameters& param;
      calc_fee_visitor( const fee_parameters& p ):param(p){}

      template<typename OpType>
      result_type operator()(  const OpType& op )const
      {
         return op.calculate_fee( param.get<typename OpType::fee_parameters_type>() ).value;
      }
   };

   struct set_fee_visitor
   {
      typedef void result_type;
      asset _fee;

      set_fee_visitor( asset f ):_fee(f){}

      template<typename OpType>
      void operator()( OpType& op )const
      {
         op.fee = _fee;
      }
   };

   struct zero_fee_visitor
   {
      typedef void result_type;

      template<typename ParamType>
      result_type operator()(  ParamType& op )const
      {
         memset( (char*)&op, 0, sizeof(op) );
      }
   };

   void fee_schedule::zero_all_fees()
   {
      *this = get_default();
      for( fee_parameters& i : parameters )
         i.visit( zero_fee_visitor() );
      this->scale = 0;
   }

   asset fee_schedule::calculate_fee( const operation& op, const price& core_exchange_rate )const
   {
      //idump( (op)(core_exchange_rate) );
      fee_parameters params; params.set_which(op.which());
      auto itr = parameters.find(params);
      if( itr != parameters.end() ) params = *itr;
      auto base_value = op.visit( calc_fee_visitor( params ) );
      auto scaled = fc::uint128(base_value) * scale;
      scaled /= GRAPHENE_100_PERCENT;
      FC_ASSERT( scaled <= GRAPHENE_MAX_SHARE_SUPPLY );
      //idump( (base_value)(scaled)(core_exchange_rate) );
      auto result = asset( scaled.to_uint64(), asset_id_type(0) ) * core_exchange_rate;
      //FC_ASSERT( result * core_exchange_rate >= asset( scaled.to_uint64()) );

      while( result * core_exchange_rate < asset( scaled.to_uint64()) )
        result.amount++;

      FC_ASSERT( result.amount <= GRAPHENE_MAX_SHARE_SUPPLY );
      return result;
   }

   asset fee_schedule::set_fee( operation& op, const price& core_exchange_rate )const
   {
      auto f = calculate_fee( op, core_exchange_rate );
      auto f_max = f;
      for( int i=0; i<MAX_FEE_STABILIZATION_ITERATION; i++ )
      {
         op.visit( set_fee_visitor( f_max ) );
         auto f2 = calculate_fee( op, core_exchange_rate );
         if( f == f2 )
            break;
         f_max = std::max( f_max, f2 );
         f = f2;
         if( i == 0 )
         {
            // no need for warnings on later iterations
            wlog( "set_fee requires multiple iterations to stabilize with core_exchange_rate ${p} on operation ${op}",
               ("p", core_exchange_rate) ("op", op) );
         }
      }
      return f_max;
   }

   void chain_parameters::validate()const
   {
      current_fees->validate();
      FC_ASSERT( reserve_percent_of_fee <= GRAPHENE_100_PERCENT );
      FC_ASSERT( network_percent_of_fee <= GRAPHENE_100_PERCENT );
      FC_ASSERT( lifetime_referrer_percent_of_fee <= GRAPHENE_100_PERCENT );
      FC_ASSERT( network_percent_of_fee + lifetime_referrer_percent_of_fee <= GRAPHENE_100_PERCENT );

      FC_ASSERT( block_interval >= GRAPHENE_MIN_BLOCK_INTERVAL );
      FC_ASSERT( block_interval <= GRAPHENE_MAX_BLOCK_INTERVAL );
      FC_ASSERT( block_interval > 0 );
      FC_ASSERT( maintenance_interval > block_interval,
                 "Maintenance interval must be longer than block interval" );
      FC_ASSERT( maintenance_interval % block_interval == 0,
                 "Maintenance interval must be a multiple of block interval" );
      FC_ASSERT( maximum_transaction_size >= GRAPHENE_MIN_TRANSACTION_SIZE_LIMIT,
                 "Transaction size limit is too low" );
      FC_ASSERT( maximum_block_size >= GRAPHENE_MIN_BLOCK_SIZE_LIMIT,
                 "Block size limit is too low" );
      FC_ASSERT( maximum_time_until_expiration > block_interval,
                 "Maximum transaction expiration time must be greater than a block interval" );
      FC_ASSERT( maximum_proposal_lifetime - committee_proposal_review_period > block_interval,
                 "Committee proposal review period must be less than the maximum proposal lifetime" );
   }

} } // graphene::chain
<commit_msg>fix linking errors on OS X<commit_after>/*
 * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/smart_ref_impl.hpp>

namespace fc
{
   // explicitly instantiate the smart_ref, gcc fails to instantiate it in some release builds
   //template graphene::chain::fee_schedule& smart_ref<graphene::chain::fee_schedule>::operator=(smart_ref<graphene::chain::fee_schedule>&&);
   //template graphene::chain::fee_schedule& smart_ref<graphene::chain::fee_schedule>::operator=(U&&);
   //template graphene::chain::fee_schedule& smart_ref<graphene::chain::fee_schedule>::operator=(const smart_ref&);
   //template smart_ref<graphene::chain::fee_schedule>::smart_ref();
   //template const graphene::chain::fee_schedule& smart_ref<graphene::chain::fee_schedule>::operator*() const;
}

#define MAX_FEE_STABILIZATION_ITERATION 4

namespace graphene { namespace chain {

   typedef fc::smart_ref<fee_schedule> smart_fee_schedule;

   static smart_fee_schedule tmp;

   fee_schedule::fee_schedule()
   {
   }

   fee_schedule fee_schedule::get_default()
   {
      fee_schedule result;
      for( int i = 0; i < fee_parameters().count(); ++i )
      {
         fee_parameters x; x.set_which(i);
         result.parameters.insert(x);
      }
      return result;
   }

   struct fee_schedule_validate_visitor
   {
      typedef void result_type;

      template<typename T>
      void operator()( const T& p )const
      {
         //p.validate();
      }
   };

   void fee_schedule::validate()const
   {
      for( const auto& f : parameters )
         f.visit( fee_schedule_validate_visitor() );
   }

   struct calc_fee_visitor
   {
      typedef uint64_t result_type;

      const fee_parameters& param;
      calc_fee_visitor( const fee_parameters& p ):param(p){}

      template<typename OpType>
      result_type operator()(  const OpType& op )const
      {
         return op.calculate_fee( param.get<typename OpType::fee_parameters_type>() ).value;
      }
   };

   struct set_fee_visitor
   {
      typedef void result_type;
      asset _fee;

      set_fee_visitor( asset f ):_fee(f){}

      template<typename OpType>
      void operator()( OpType& op )const
      {
         op.fee = _fee;
      }
   };

   struct zero_fee_visitor
   {
      typedef void result_type;

      template<typename ParamType>
      result_type operator()(  ParamType& op )const
      {
         memset( (char*)&op, 0, sizeof(op) );
      }
   };

   void fee_schedule::zero_all_fees()
   {
      *this = get_default();
      for( fee_parameters& i : parameters )
         i.visit( zero_fee_visitor() );
      this->scale = 0;
   }

   asset fee_schedule::calculate_fee( const operation& op, const price& core_exchange_rate )const
   {
      //idump( (op)(core_exchange_rate) );
      fee_parameters params; params.set_which(op.which());
      auto itr = parameters.find(params);
      if( itr != parameters.end() ) params = *itr;
      auto base_value = op.visit( calc_fee_visitor( params ) );
      auto scaled = fc::uint128(base_value) * scale;
      scaled /= GRAPHENE_100_PERCENT;
      FC_ASSERT( scaled <= GRAPHENE_MAX_SHARE_SUPPLY );
      //idump( (base_value)(scaled)(core_exchange_rate) );
      auto result = asset( scaled.to_uint64(), asset_id_type(0) ) * core_exchange_rate;
      //FC_ASSERT( result * core_exchange_rate >= asset( scaled.to_uint64()) );

      while( result * core_exchange_rate < asset( scaled.to_uint64()) )
        result.amount++;

      FC_ASSERT( result.amount <= GRAPHENE_MAX_SHARE_SUPPLY );
      return result;
   }

   asset fee_schedule::set_fee( operation& op, const price& core_exchange_rate )const
   {
      auto f = calculate_fee( op, core_exchange_rate );
      auto f_max = f;
      for( int i=0; i<MAX_FEE_STABILIZATION_ITERATION; i++ )
      {
         op.visit( set_fee_visitor( f_max ) );
         auto f2 = calculate_fee( op, core_exchange_rate );
         if( f == f2 )
            break;
         f_max = std::max( f_max, f2 );
         f = f2;
         if( i == 0 )
         {
            // no need for warnings on later iterations
            wlog( "set_fee requires multiple iterations to stabilize with core_exchange_rate ${p} on operation ${op}",
               ("p", core_exchange_rate) ("op", op) );
         }
      }
      return f_max;
   }

   void chain_parameters::validate()const
   {
      current_fees->validate();
      FC_ASSERT( reserve_percent_of_fee <= GRAPHENE_100_PERCENT );
      FC_ASSERT( network_percent_of_fee <= GRAPHENE_100_PERCENT );
      FC_ASSERT( lifetime_referrer_percent_of_fee <= GRAPHENE_100_PERCENT );
      FC_ASSERT( network_percent_of_fee + lifetime_referrer_percent_of_fee <= GRAPHENE_100_PERCENT );

      FC_ASSERT( block_interval >= GRAPHENE_MIN_BLOCK_INTERVAL );
      FC_ASSERT( block_interval <= GRAPHENE_MAX_BLOCK_INTERVAL );
      FC_ASSERT( block_interval > 0 );
      FC_ASSERT( maintenance_interval > block_interval,
                 "Maintenance interval must be longer than block interval" );
      FC_ASSERT( maintenance_interval % block_interval == 0,
                 "Maintenance interval must be a multiple of block interval" );
      FC_ASSERT( maximum_transaction_size >= GRAPHENE_MIN_TRANSACTION_SIZE_LIMIT,
                 "Transaction size limit is too low" );
      FC_ASSERT( maximum_block_size >= GRAPHENE_MIN_BLOCK_SIZE_LIMIT,
                 "Block size limit is too low" );
      FC_ASSERT( maximum_time_until_expiration > block_interval,
                 "Maximum transaction expiration time must be greater than a block interval" );
      FC_ASSERT( maximum_proposal_lifetime - committee_proposal_review_period > block_interval,
                 "Committee proposal review period must be less than the maximum proposal lifetime" );
   }

} } // graphene::chain
<|endoftext|>


<commit_before>// Copyright (c) 2017, Franz Hollerer. All rights reserved.
// This code is licensed under the MIT License (MIT).
// See LICENSE file for full details.
#include <iostream>
#include <stdint.h>
#include <catch/catch.hpp>
#include <hodea/utils/byteorder.hpp>

using namespace hodea;

TEST_CASE("Byteorder: fetch8()", "[fetch8]")
{
    uint8_t buf[] = {0xaa};
    unsigned v;
    int cnt;

    cnt = fetch8(v, buf);
    REQUIRE(v == 0xaa);
    REQUIRE(cnt == 1);
}

TEST_CASE("Byteorder: fetch16_le()", "[fetch16_le]")
{
    uint8_t buf[] = {0x08, 0x15};
    unsigned v;
    int cnt;

    cnt = fetch16_le(v, buf);
    REQUIRE(v == 0x1508);
    REQUIRE(cnt == 2);
}

TEST_CASE("Byteorder: fetch32_le()", "[fetch32_le]")
{
    uint8_t buf[] = {0x08, 0x15, 0xca, 0xfe};
    unsigned v;
    int cnt;

    cnt = fetch32_le(v, buf);
    REQUIRE(v == 0xfeca1508U);
    REQUIRE(cnt == 4);
}

TEST_CASE("Byteorder: fetch64_le()", "[fetch64_le]")
{
    uint8_t buf[] = {0x08, 0x15, 0xca, 0xfe, 0x41, 0x11, 0xc0, 0x01};
    uint64_t v;
    int cnt;

    cnt = fetch64_le(v, buf);
    REQUIRE(v == 0x01c01141feca1508LLU);
    REQUIRE(cnt == 8);
}

TEST_CASE("Byteorder: fetch16_be()", "[fetch16_be]")
{
    uint8_t buf[] = {0x08, 0x15};
    unsigned v;
    int cnt;

    cnt = fetch16_be(v, buf);
    REQUIRE(v == 0x0815);
    REQUIRE(cnt == 2);
}

TEST_CASE("Byteorder: fetch32_be()", "[fetch32_be]")
{
    uint8_t buf[] = {0x08, 0x15, 0xca, 0xfe};
    unsigned v;
    int cnt;

    cnt = fetch32_be(v, buf);
    REQUIRE(v == 0x0815cafe);
    REQUIRE(cnt == 4);
}

TEST_CASE("Byteorder: fetch64_be()", "[fetch64_be]")
{
    uint8_t buf[] = {0x08, 0x15, 0xca, 0xfe, 0x41, 0x11, 0xc0, 0x01};
    uint64_t v;
    unsigned cnt;

    cnt = fetch64_be(v, buf);
    REQUIRE(v == 0x0815cafe4111c001LLU);
    REQUIRE(cnt == 8);
}

TEST_CASE("Byteorder: store8()", "[store8]")
{
    uint8_t buf[] = {0};
    int cnt;

    cnt = store8(buf, 0x11);
    REQUIRE(buf[0] == 0x11);
    REQUIRE(cnt == 1);
}

TEST_CASE("Byteorder: store16_le()", "[store16_le]")
{
    uint8_t buf[] = {0, 0};
    int cnt;

    cnt = store16_le(buf, 0x4711);
    REQUIRE(buf[0] == 0x11);
    REQUIRE(buf[1] == 0x47);
    REQUIRE(cnt == 2);
}

TEST_CASE("Byteorder: store32_le()", "[store32_le]")
{
    uint8_t buf[] = {0, 0, 0, 0};
    int cnt;

    cnt = store32_le(buf, 0x08154711);
    REQUIRE(buf[0] == 0x11);
    REQUIRE(buf[1] == 0x47);
    REQUIRE(buf[2] == 0x15);
    REQUIRE(buf[3] == 0x08);
    REQUIRE(cnt == 4);
}

TEST_CASE("Byteorder: store64_le()", "[store64_le]")
{
    uint8_t buf[] = {0, 0, 0, 0, 0, 0, 0, 0};
    int cnt;

    cnt = store64_le(buf, 0xc001cafe08154711LLU);
    REQUIRE(buf[0] == 0x11);
    REQUIRE(buf[1] == 0x47);
    REQUIRE(buf[2] == 0x15);
    REQUIRE(buf[3] == 0x08);
    REQUIRE(buf[4] == 0xfe);
    REQUIRE(buf[5] == 0xca);
    REQUIRE(buf[6] == 0x01);
    REQUIRE(buf[7] == 0xc0);
    REQUIRE(cnt == 8);
}

TEST_CASE("Byteorder: store16_be()", "[store16_be]")
{
    uint8_t buf[] = {0, 0};
    int cnt;

    cnt = store16_be(buf, 0x4711);
    REQUIRE(buf[0] == 0x47);
    REQUIRE(buf[1] == 0x11);
    REQUIRE(cnt == 2);
}

TEST_CASE("Byteorder: store32_be()", "[store32_be]")
{
    uint8_t buf[] = {0, 0, 0, 0};
    int cnt;

    cnt = store32_be(buf, 0x08154711);
    REQUIRE(buf[0] == 0x08);
    REQUIRE(buf[1] == 0x15);
    REQUIRE(buf[2] == 0x47);
    REQUIRE(buf[3] == 0x11);
    REQUIRE(cnt == 4);
}

TEST_CASE("Byteorder: store64_be()", "[store64_le]")
{
    uint8_t buf[] = {0, 0, 0, 0, 0, 0, 0, 0};
    int cnt;

    cnt = store64_be(buf, 0xc001cafe08154711LLU);
    REQUIRE(buf[0] == 0xc0);
    REQUIRE(buf[1] == 0x01);
    REQUIRE(buf[2] == 0xca);
    REQUIRE(buf[3] == 0xfe);
    REQUIRE(buf[4] == 0x08);
    REQUIRE(buf[5] == 0x15);
    REQUIRE(buf[6] == 0x47);
    REQUIRE(buf[7] == 0x11);
    REQUIRE(cnt == 8);
}

TEST_CASE("Byteorder: is_cpu_little_endian()", "[is_cpu_little_endian]")
{
    REQUIRE(is_cpu_little_endian() == true);

}

TEST_CASE("Byteorder: is_cpu_big_endian()", "[is_cpu_big_endian]")
{
    REQUIRE(is_cpu_big_endian() == false);

}
<commit_msg>tests for cpu endianness removed<commit_after>// Copyright (c) 2017, Franz Hollerer. All rights reserved.
// This code is licensed under the MIT License (MIT).
// See LICENSE file for full details.
#include <iostream>
#include <stdint.h>
#include <catch/catch.hpp>
#include <hodea/utils/byteorder.hpp>

using namespace hodea;

TEST_CASE("Byteorder: fetch8()", "[fetch8]")
{
    uint8_t buf[] = {0xaa};
    unsigned v;
    int cnt;

    cnt = fetch8(v, buf);
    REQUIRE(v == 0xaa);
    REQUIRE(cnt == 1);
}

TEST_CASE("Byteorder: fetch16_le()", "[fetch16_le]")
{
    uint8_t buf[] = {0x08, 0x15};
    unsigned v;
    int cnt;

    cnt = fetch16_le(v, buf);
    REQUIRE(v == 0x1508);
    REQUIRE(cnt == 2);
}

TEST_CASE("Byteorder: fetch32_le()", "[fetch32_le]")
{
    uint8_t buf[] = {0x08, 0x15, 0xca, 0xfe};
    unsigned v;
    int cnt;

    cnt = fetch32_le(v, buf);
    REQUIRE(v == 0xfeca1508U);
    REQUIRE(cnt == 4);
}

TEST_CASE("Byteorder: fetch64_le()", "[fetch64_le]")
{
    uint8_t buf[] = {0x08, 0x15, 0xca, 0xfe, 0x41, 0x11, 0xc0, 0x01};
    uint64_t v;
    int cnt;

    cnt = fetch64_le(v, buf);
    REQUIRE(v == 0x01c01141feca1508LLU);
    REQUIRE(cnt == 8);
}

TEST_CASE("Byteorder: fetch16_be()", "[fetch16_be]")
{
    uint8_t buf[] = {0x08, 0x15};
    unsigned v;
    int cnt;

    cnt = fetch16_be(v, buf);
    REQUIRE(v == 0x0815);
    REQUIRE(cnt == 2);
}

TEST_CASE("Byteorder: fetch32_be()", "[fetch32_be]")
{
    uint8_t buf[] = {0x08, 0x15, 0xca, 0xfe};
    unsigned v;
    int cnt;

    cnt = fetch32_be(v, buf);
    REQUIRE(v == 0x0815cafe);
    REQUIRE(cnt == 4);
}

TEST_CASE("Byteorder: fetch64_be()", "[fetch64_be]")
{
    uint8_t buf[] = {0x08, 0x15, 0xca, 0xfe, 0x41, 0x11, 0xc0, 0x01};
    uint64_t v;
    unsigned cnt;

    cnt = fetch64_be(v, buf);
    REQUIRE(v == 0x0815cafe4111c001LLU);
    REQUIRE(cnt == 8);
}

TEST_CASE("Byteorder: store8()", "[store8]")
{
    uint8_t buf[] = {0};
    int cnt;

    cnt = store8(buf, 0x11);
    REQUIRE(buf[0] == 0x11);
    REQUIRE(cnt == 1);
}

TEST_CASE("Byteorder: store16_le()", "[store16_le]")
{
    uint8_t buf[] = {0, 0};
    int cnt;

    cnt = store16_le(buf, 0x4711);
    REQUIRE(buf[0] == 0x11);
    REQUIRE(buf[1] == 0x47);
    REQUIRE(cnt == 2);
}

TEST_CASE("Byteorder: store32_le()", "[store32_le]")
{
    uint8_t buf[] = {0, 0, 0, 0};
    int cnt;

    cnt = store32_le(buf, 0x08154711);
    REQUIRE(buf[0] == 0x11);
    REQUIRE(buf[1] == 0x47);
    REQUIRE(buf[2] == 0x15);
    REQUIRE(buf[3] == 0x08);
    REQUIRE(cnt == 4);
}

TEST_CASE("Byteorder: store64_le()", "[store64_le]")
{
    uint8_t buf[] = {0, 0, 0, 0, 0, 0, 0, 0};
    int cnt;

    cnt = store64_le(buf, 0xc001cafe08154711LLU);
    REQUIRE(buf[0] == 0x11);
    REQUIRE(buf[1] == 0x47);
    REQUIRE(buf[2] == 0x15);
    REQUIRE(buf[3] == 0x08);
    REQUIRE(buf[4] == 0xfe);
    REQUIRE(buf[5] == 0xca);
    REQUIRE(buf[6] == 0x01);
    REQUIRE(buf[7] == 0xc0);
    REQUIRE(cnt == 8);
}

TEST_CASE("Byteorder: store16_be()", "[store16_be]")
{
    uint8_t buf[] = {0, 0};
    int cnt;

    cnt = store16_be(buf, 0x4711);
    REQUIRE(buf[0] == 0x47);
    REQUIRE(buf[1] == 0x11);
    REQUIRE(cnt == 2);
}

TEST_CASE("Byteorder: store32_be()", "[store32_be]")
{
    uint8_t buf[] = {0, 0, 0, 0};
    int cnt;

    cnt = store32_be(buf, 0x08154711);
    REQUIRE(buf[0] == 0x08);
    REQUIRE(buf[1] == 0x15);
    REQUIRE(buf[2] == 0x47);
    REQUIRE(buf[3] == 0x11);
    REQUIRE(cnt == 4);
}

TEST_CASE("Byteorder: store64_be()", "[store64_le]")
{
    uint8_t buf[] = {0, 0, 0, 0, 0, 0, 0, 0};
    int cnt;

    cnt = store64_be(buf, 0xc001cafe08154711LLU);
    REQUIRE(buf[0] == 0xc0);
    REQUIRE(buf[1] == 0x01);
    REQUIRE(buf[2] == 0xca);
    REQUIRE(buf[3] == 0xfe);
    REQUIRE(buf[4] == 0x08);
    REQUIRE(buf[5] == 0x15);
    REQUIRE(buf[6] == 0x47);
    REQUIRE(buf[7] == 0x11);
    REQUIRE(cnt == 8);
}

<|endoftext|>


<commit_before>#include "DeserializerStream.h"
#include "Serializable.h"
#include <cstdint>

DeserializerStream::DeserializerStream(std::istream &stream): stream(&stream){
}

std::vector<std::pair<std::uint32_t, TypeHash> > DeserializerStream::read_typehashes(){
	std::vector<std::pair<std::uint32_t, TypeHash> > ret;
	std::uint32_t size;
	this->deserialize(size);
	ret.reserve(size);
	while (ret.size() < size){
		std::pair<std::uint32_t, TypeHash> pair;
		this->deserialize(pair.first);
		this->deserialize_array(pair.second.digest);
		ret.push_back(pair);
	}
	return ret;
}

Serializable *DeserializerStream::begin_deserialization(SerializableMetadata &metadata, bool includes_typehashes){
	std::map<objectid_t, std::uint32_t> object_types;
	std::vector<std::pair<std::uint32_t, void *> > initialized;
	void *main_object = nullptr;
	try{
		this->state = State::ReadingTypeHashes;
		if (includes_typehashes)
			metadata.set_type_mappings(this->read_typehashes());
		this->state = State::Safe;

		std::vector<std::pair<std::uint32_t, objectid_t>> type_map;
		wire_size_t size;
		this->deserialize(size);
		type_map.reserve((size_t)size);
		for (auto i = size; size--;){
			std::uint32_t type_id;
			objectid_t object_id;
			this->deserialize(type_id);
			this->deserialize(object_id);
			type_map.push_back(std::make_pair(type_id, object_id));
		}

		objectid_t root_object_id;
		this->deserialize(root_object_id);

		this->state = State::AllocatingMemory;
		std::uint32_t main_object_type = 0;
		{
			objectid_t object_id = 1;
			for (auto &p : type_map){
				std::uint32_t type_id = p.first;
				for (; object_id <= p.second; object_id++){
					object_types[object_id] = type_id;
					auto mem = metadata.allocate_memory(type_id);
					if (!main_object && object_id == root_object_id){
						main_object = mem;
						main_object_type = type_id;
					}
					try{
						this->node_map[object_id] = mem;
					}catch (...){
						::operator delete(mem);
						throw;
					}
				}
			}
		}

		this->state = State::InitializingObjects;
		for (auto &kv : this->node_map){
			auto type = object_types[kv.first];
			metadata.construct_memory(type, kv.second, *this);
			initialized.push_back(std::make_pair(type, kv.second));
		}
		this->state = State::SanityCheck;
		if (!main_object_type || !main_object)
			throw std::exception("Program in unknown state!");
		if (!metadata.type_is_serializable(main_object_type))
			throw std::exception("Main object is not an instance of Serializable. Deserilization cannot continue.");
		this->state = State::Done;
	}catch (...){
		switch (this->state){
			case State::Safe:
				break;
			case State::ReadingTypeHashes:
				break;
			case State::SanityCheck:
			case State::InitializingObjects:
				for (auto &p : initialized)
					metadata.rollback_construction(object_types[p.first], p.second);
			case State::AllocatingMemory:
				for (auto &pair : this->node_map)
					::operator delete(pair.second);
				this->node_map.clear();
				break;
		}
	}
	for (auto &p : this->known_shared_ptrs)
		p.second.second(p.second.first);
	this->known_shared_ptrs.clear();
	for (auto &p : this->known_unique_ptrs)
		p.second.second(p.second.first);
	this->known_unique_ptrs.clear();
	return (Serializable *)main_object;
}
<commit_msg>Added missing rethrows.<commit_after>#include "DeserializerStream.h"
#include "Serializable.h"
#include <cstdint>

DeserializerStream::DeserializerStream(std::istream &stream): stream(&stream){
}

std::vector<std::pair<std::uint32_t, TypeHash> > DeserializerStream::read_typehashes(){
	std::vector<std::pair<std::uint32_t, TypeHash> > ret;
	std::uint32_t size;
	this->deserialize(size);
	ret.reserve(size);
	while (ret.size() < size){
		std::pair<std::uint32_t, TypeHash> pair;
		this->deserialize(pair.first);
		this->deserialize_array(pair.second.digest);
		ret.push_back(pair);
	}
	return ret;
}

Serializable *DeserializerStream::begin_deserialization(SerializableMetadata &metadata, bool includes_typehashes){
	std::map<objectid_t, std::uint32_t> object_types;
	std::vector<std::pair<std::uint32_t, void *> > initialized;
	void *main_object = nullptr;
	try{
		this->state = State::ReadingTypeHashes;
		if (includes_typehashes)
			metadata.set_type_mappings(this->read_typehashes());
		this->state = State::Safe;

		std::vector<std::pair<std::uint32_t, objectid_t>> type_map;
		wire_size_t size;
		this->deserialize(size);
		type_map.reserve((size_t)size);
		for (auto i = size; size--;){
			std::uint32_t type_id;
			objectid_t object_id;
			this->deserialize(type_id);
			this->deserialize(object_id);
			type_map.push_back(std::make_pair(type_id, object_id));
		}

		objectid_t root_object_id;
		this->deserialize(root_object_id);

		this->state = State::AllocatingMemory;
		std::uint32_t main_object_type = 0;
		{
			objectid_t object_id = 1;
			for (auto &p : type_map){
				std::uint32_t type_id = p.first;
				for (; object_id <= p.second; object_id++){
					object_types[object_id] = type_id;
					auto mem = metadata.allocate_memory(type_id);
					if (!main_object && object_id == root_object_id){
						main_object = mem;
						main_object_type = type_id;
					}
					try{
						this->node_map[object_id] = mem;
					}catch (...){
						::operator delete(mem);
						throw;
					}
				}
			}
		}

		this->state = State::InitializingObjects;
		for (auto &kv : this->node_map){
			auto type = object_types[kv.first];
			metadata.construct_memory(type, kv.second, *this);
			initialized.push_back(std::make_pair(type, kv.second));
		}
		this->state = State::SanityCheck;
		if (!main_object_type || !main_object)
			throw std::exception("Program in unknown state!");
		if (!metadata.type_is_serializable(main_object_type))
			throw std::exception("Main object is not an instance of Serializable. Deserilization cannot continue.");
		this->state = State::Done;
	}catch (std::bad_alloc &){
		throw;
	}catch (...){
		switch (this->state){
			case State::Safe:
				break;
			case State::ReadingTypeHashes:
				break;
			case State::SanityCheck:
			case State::InitializingObjects:
				for (auto &p : initialized)
					metadata.rollback_construction(object_types[p.first], p.second);
			case State::AllocatingMemory:
				for (auto &pair : this->node_map)
					::operator delete(pair.second);
				this->node_map.clear();
				break;
		}
		throw;
	}
	for (auto &p : this->known_shared_ptrs)
		p.second.second(p.second.first);
	this->known_shared_ptrs.clear();
	for (auto &p : this->known_unique_ptrs)
		p.second.second(p.second.first);
	this->known_unique_ptrs.clear();
	return (Serializable *)main_object;
}
<|endoftext|>


<commit_before>#include <iostream>

// Class Box stored length, breadth and height
// Class ColouredBox extends Box to store the colour of the box
// ColouredBox has two constructors one taking just the colour
// and one taking colour and the dimensions

using namespace std;

class Box {
   private:
      double length;   // Length of a box
      double breadth;  // Breadth of a box
      double height;   // Height of a box
   public :
      void setLength(double v_length) {
         length = v_length;
      }
      void setBreadth(double v_breadth) {
         breadth = v_breadth;
      }
      void setHeight(double v_height) {
         height = v_height;
      }
      double getVolume() {
         if ( (int) length == 0 or (int) breadth == 0 or (int) height == 0 ) {
           return 0;
         } else {
           return length * breadth * height;
         }
      }
};

class ColouredBox: public Box {
   public :
      void setColour(string v_colour) {
         colour = v_colour;
      }
      string getColour() {
         return colour;
      }
      ColouredBox( string v_colour ) {
         colour = v_colour;
      }
      ColouredBox( string v_colour, double v_length, double v_breadth, double v_height ) {
         colour = v_colour;
         Box::setLength(v_length);
         Box::setBreadth(v_breadth);
         Box::setHeight(v_height);
      }

   private:
      string colour; // The colour of the box
};

int main( ) {
   Box Box1;        // Declare Box1 of type Box
   Box Box2;        // Declare Box2 of type Box
   Box Box3;        // Declare Box3 of type Box
   // Declare a box with colour
   ColouredBox Box4("Red");
   // box 5 specification
   // Using the second constructor
   ColouredBox Box5("Blue", 5.0, 6.0, 2.0);

   // box 1 specification
   Box1.setHeight(5.0);
   Box1.setLength(6.0);
   Box1.setBreadth(7.0);

   // box 2 specification
   Box2.setHeight(10.0);
   Box2.setLength(12.0);
   Box2.setBreadth(13.0);

   // box 3 specification
   Box3.setHeight(10.0);
   Box3.setBreadth(13.0);
   // Box3.setColour("Blue"); // This is illegal because it's not a coloured box

   // box 4 specification
   Box4.setHeight(6.0);
   Box4.setLength(3.0);
   Box4.setBreadth(2.0);

   // volume of box 1
   cout << "Volume of Box1 : " << Box1.getVolume() << endl;

   // volume of box 2
   cout << "Volume of Box2 : " << Box2.getVolume() << endl;

   // volume of box 3
   cout << "Volume of Box3 : " << Box3.getVolume() << endl;

   // Box 4
   cout << "Box 4 is " << Box4.getColour() << " and has a volume of " << Box4.getVolume() <<endl;

   // Box 5
   cout << "Box 5 is " << Box5.getColour() << " and has a volume of " << Box5.getVolume() <<endl;

   return 0;
}
<commit_msg>Updates<commit_after>#include <iostream>

// Class Box stored length, breadth and height
// Class ColouredBox extends Box to store the colour of the box
// ColouredBox has two constructors one taking just the colour
// and one taking colour and the dimensions

using namespace std;

class Box {
   private:
      double length;   // Length of a box
      double breadth;  // Breadth of a box
      double height;   // Height of a box
   public :
      Box();
      Box( double v_length, double v_breadth, double v_height );
      void setLength(double v_length) {
         length = v_length;
      }
      void setBreadth(double v_breadth) {
         breadth = v_breadth;
      }
      void setHeight(double v_height) {
         height = v_height;
      }
      double getVolume() {
         if ( (int) length == 0 or (int) breadth == 0 or (int) height == 0 ) {
           return 0;
         } else {
           return length * breadth * height;
         }
      }
};
Box::Box(void) { }
Box::Box( double v_length, double v_breadth, double v_height ) {
   length  = v_length;
   breadth = v_breadth;
   height  = v_height;
}

class ColouredBox: public Box {
   private:
      string colour; // The colour of the box

   public :
      void setColour(string v_colour) {
         colour = v_colour;
      }
      string getColour() {
         return colour;
      }
      ColouredBox( string v_colour ) {
         colour = v_colour;
      }
      ColouredBox( string v_colour, double v_length, double v_breadth, double v_height ) {
         colour = v_colour;
         Box::setLength(v_length);
         Box::setBreadth(v_breadth);
         Box::setHeight(v_height);
      }
};

int main( ) {
   Box Box1;                  // Declare Box1 of type Box
   Box Box2(10.0,12.0,13.0);  // Declare Box2 using the constructor
   Box Box3;                  // Declare Box3 of type Box
   // Declare a box with colour
   ColouredBox Box4("Red");
   // box 5 specification
   // Using the second constructor
   ColouredBox Box5("Blue", 5.0, 6.0, 2.0);

   // box 1 specification
   Box1.setHeight(5.0);
   Box1.setLength(6.0);
   Box1.setBreadth(7.0);

   // box 3 specification
   Box3.setHeight(10.0);
   Box3.setBreadth(13.0);
   // Box3.setColour("Blue"); // This is illegal because it's not a coloured box

   // box 4 specification
   Box4.setHeight(6.0);
   Box4.setLength(3.0);
   Box4.setBreadth(2.0);

   // volume of box 1
   cout << "Volume of Box1 : " << Box1.getVolume() << endl;

   // volume of box 2
   cout << "Volume of Box2 : " << Box2.getVolume() << endl;

   // volume of box 3
   cout << "Volume of Box3 : " << Box3.getVolume() << endl;

   // Box 4
   cout << "Box 4 is " << Box4.getColour() << " and has a volume of " << Box4.getVolume() <<endl;

   // Box 5
   cout << "Box 5 is " << Box5.getColour() << " and has a volume of " << Box5.getVolume() <<endl;

   return 0;
}
<|endoftext|>


<commit_before>
// Copyright (c) 2012 Nokia, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <errno.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "portal.h"

#include <sys/cdefs.h>
#include <android/log.h>
#define ALOGD(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, "PORTAL", fmt, __VA_ARGS__)
#define ALOGE(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, "PORTAL", fmt, __VA_ARGS__)

#define PORTAL_ALLOC _IOWR('B', 10, PortalAlloc)
#define PORTAL_PUTGET _IOWR('B', 17, PortalMessage)
#define PORTAL_PUT _IOWR('B', 18, PortalMessage)
#define PORTAL_GET _IOWR('B', 19, PortalMessage)
#define PORTAL_REGS _IOWR('B', 20, PortalMessage)
#define PORTAL_SET_FCLK_RATE _IOWR('B', 40, PortalClockRequest)

PortalInterface portal;

void PortalInstance::close()
{
    if (fd > 0) {
        ::close(fd);
        fd = -1;
    }
}

PortalInstance::PortalInstance(const char *instanceName, PortalIndications *indications)
  : instanceName(strdup(instanceName)), indications(indications)
{
    char path[128];
    snprintf(path, sizeof(path), "/dev/%s", instanceName);
    this->fd = open(path, O_RDWR);
    void *mappedAddress = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, this->fd, 0);
    fprintf(stderr, "Mapped device %s at %p\n", instanceName, mappedAddress);
    portal.registerInstance(this);
}

PortalInstance::~PortalInstance()
{
    close();
    if (instanceName)
        free(instanceName);
}

PortalInstance *portalOpen(const char *instanceName)
{
    return new PortalInstance(instanceName);
}

int PortalInstance::sendMessage(PortalMessage *msg)
{
    int rc = ioctl(fd, PORTAL_PUT, msg);
    //ALOGD("sendmessage portal fd=%d rc=%d\n", fd, rc);
    if (rc)
        ALOGE("PortalInstance::sendMessage fd=%d rc=%d errno=%d:%s PUTGET=%x PUT=%x GET=%x\n", fd, rc, errno, strerror(errno),
                PORTAL_PUTGET, PORTAL_PUT, PORTAL_GET);
    return rc;
}

int PortalInstance::receiveMessage(PortalMessage *msg)
{
    int status  = ioctl(fd, PORTAL_GET, msg);
    if (status) {
        fprintf(stderr, "receiveMessage rc=%d errno=%d:%s\n", status, errno, strerror(errno));
        return -status;
    }
    return 1;
}

PortalInterface::PortalInterface()
    : fds(0), numFds(0)
{
}

PortalInterface::~PortalInterface()
{
    if (fds) {
        ::free(fds);
        fds = 0;
    }
}

int PortalInterface::registerInstance(PortalInstance *instance)
{
    numFds++;
    instances = (PortalInstance **)realloc(instances, numFds*sizeof(PortalInstance *));
    instances[numFds-1] = instance;
    fds = (struct pollfd *)realloc(fds, numFds*sizeof(struct pollfd));
    struct pollfd *pollfd = &fds[numFds-1];
    memset(pollfd, 0, sizeof(struct pollfd));
    pollfd->fd = instance->fd;
    pollfd->events = POLLIN;
    return 0;
}

int PortalInterface::alloc(size_t size, int *fd, PortalAlloc *portalAlloc)
{
    PortalAlloc alloc;
    memset(&alloc, 0, sizeof(alloc));
    void *ptr = 0;
    alloc.size = size;
    int rc = ioctl(portal.fds[0].fd, PORTAL_ALLOC, &alloc);
    if (rc)
      return rc;
    ptr = mmap(0, alloc.size, PROT_READ|PROT_WRITE, MAP_SHARED, alloc.fd, 0);
    fprintf(stderr, "alloc size=%d rc=%d alloc.fd=%d ptr=%p\n", size, rc, alloc.fd, ptr);
    if (fd)
      *fd = alloc.fd;
    if (portalAlloc)
      *portalAlloc = alloc;
    return 0;
}

int PortalInterface::free(int fd)
{
    return 0;
}

int PortalInterface::setClockFrequency(int clkNum, long requestedFrequency, long *actualFrequency)
{
    PortalClockRequest request;
    request.clknum = clkNum;
    request.requested_rate = requestedFrequency;
    int status = ioctl(portal.fds[0].fd, (long)&request);
    if (status == 0 && actualFrequency)
	*actualFrequency = request.actual_rate;
    return status;
}

int PortalInterface::dumpRegs()
{
    int foo = 0;
    int rc = ioctl(portal.fds[0].fd, PORTAL_REGS, &foo);
    return rc;
}

int PortalInterface::exec(idleFunc func)
{
    unsigned int *buf = new unsigned int[1024];
    PortalMessage *msg = (PortalMessage *)(buf);
    fprintf(stderr, "PortalInterface::exec()\n");
    int messageReceived = 0;

    if (!portal.numFds) {
        fprintf(stderr, "PortalInterface::exec No fds open\n");
        return -ENODEV;
    }

    int rc;
    while ((rc = poll(portal.fds, portal.numFds, 100)) >= 0) {
        //fprintf(stderr, "pid %d poll rc=%d\n", getpid(), rc);
        for (int i = 0; i < portal.numFds; i++) {
            if (portal.fds[i].revents == 0)
                continue;
            if (!portal.instances) {
                fprintf(stderr, "No instances but rc=%d revents=%d\n", rc, portal.fds[i].revents);
            }
            PortalInstance *instance = portal.instances[i];
            memset(buf, 0, 1024);
            int messageReceived = instance->receiveMessage(msg);
            //fprintf(stderr, "messageReceived=%d\n", messageReceived);
            if (!messageReceived)
                continue;
            size_t size = msg->size;
            //fprintf(stderr, "msg->size=%d msg->channel=%d\n", msg->size, msg->channel);
            if (!size)
                continue;
	    if (instance->indications)
		instance->indications->handleMessage(msg);
        }
        if (rc == 0) {
            if (0)
            ALOGD("poll returned rc=%d errno=%d:%s func=%p\n",
                  rc, errno, strerror(errno), func);
          if (func)
            func();
        }
    }
    if (rc < 0) {
        fprintf(stderr, "poll returned rc=%d errno=%d:%s\n", rc, errno, strerror(errno));
        return rc;
    }

    return 0;
}
<commit_msg>forgot to include command PORTAL_SET_FCLK_RATE in call to ioctl<commit_after>
// Copyright (c) 2012 Nokia, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <errno.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "portal.h"

#include <sys/cdefs.h>
#include <android/log.h>
#define ALOGD(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, "PORTAL", fmt, __VA_ARGS__)
#define ALOGE(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, "PORTAL", fmt, __VA_ARGS__)

#define PORTAL_ALLOC _IOWR('B', 10, PortalAlloc)
#define PORTAL_PUTGET _IOWR('B', 17, PortalMessage)
#define PORTAL_PUT _IOWR('B', 18, PortalMessage)
#define PORTAL_GET _IOWR('B', 19, PortalMessage)
#define PORTAL_REGS _IOWR('B', 20, PortalMessage)
#define PORTAL_SET_FCLK_RATE _IOWR('B', 40, PortalClockRequest)

PortalInterface portal;

void PortalInstance::close()
{
    if (fd > 0) {
        ::close(fd);
        fd = -1;
    }
}

PortalInstance::PortalInstance(const char *instanceName, PortalIndications *indications)
  : instanceName(strdup(instanceName)), indications(indications)
{
    char path[128];
    snprintf(path, sizeof(path), "/dev/%s", instanceName);
    this->fd = open(path, O_RDWR);
    void *mappedAddress = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, this->fd, 0);
    fprintf(stderr, "Mapped device %s at %p\n", instanceName, mappedAddress);
    portal.registerInstance(this);
}

PortalInstance::~PortalInstance()
{
    close();
    if (instanceName)
        free(instanceName);
}

PortalInstance *portalOpen(const char *instanceName)
{
    return new PortalInstance(instanceName);
}

int PortalInstance::sendMessage(PortalMessage *msg)
{
    int rc = ioctl(fd, PORTAL_PUT, msg);
    //ALOGD("sendmessage portal fd=%d rc=%d\n", fd, rc);
    if (rc)
        ALOGE("PortalInstance::sendMessage fd=%d rc=%d errno=%d:%s PUTGET=%x PUT=%x GET=%x\n", fd, rc, errno, strerror(errno),
                PORTAL_PUTGET, PORTAL_PUT, PORTAL_GET);
    return rc;
}

int PortalInstance::receiveMessage(PortalMessage *msg)
{
    int status  = ioctl(fd, PORTAL_GET, msg);
    if (status) {
        fprintf(stderr, "receiveMessage rc=%d errno=%d:%s\n", status, errno, strerror(errno));
        return -status;
    }
    return 1;
}

PortalInterface::PortalInterface()
    : fds(0), numFds(0)
{
}

PortalInterface::~PortalInterface()
{
    if (fds) {
        ::free(fds);
        fds = 0;
    }
}

int PortalInterface::registerInstance(PortalInstance *instance)
{
    numFds++;
    instances = (PortalInstance **)realloc(instances, numFds*sizeof(PortalInstance *));
    instances[numFds-1] = instance;
    fds = (struct pollfd *)realloc(fds, numFds*sizeof(struct pollfd));
    struct pollfd *pollfd = &fds[numFds-1];
    memset(pollfd, 0, sizeof(struct pollfd));
    pollfd->fd = instance->fd;
    pollfd->events = POLLIN;
    return 0;
}

int PortalInterface::alloc(size_t size, int *fd, PortalAlloc *portalAlloc)
{
    PortalAlloc alloc;
    memset(&alloc, 0, sizeof(alloc));
    void *ptr = 0;
    alloc.size = size;
    int rc = ioctl(portal.fds[0].fd, PORTAL_ALLOC, &alloc);
    if (rc)
      return rc;
    ptr = mmap(0, alloc.size, PROT_READ|PROT_WRITE, MAP_SHARED, alloc.fd, 0);
    fprintf(stderr, "alloc size=%d rc=%d alloc.fd=%d ptr=%p\n", size, rc, alloc.fd, ptr);
    if (fd)
      *fd = alloc.fd;
    if (portalAlloc)
      *portalAlloc = alloc;
    return 0;
}

int PortalInterface::free(int fd)
{
    return 0;
}

int PortalInterface::setClockFrequency(int clkNum, long requestedFrequency, long *actualFrequency)
{
    PortalClockRequest request;
    request.clknum = clkNum;
    request.requested_rate = requestedFrequency;
    int status = ioctl(portal.fds[0].fd, PORTAL_SET_FCLK_RATE, (long)&request);
    if (status == 0 && actualFrequency)
	*actualFrequency = request.actual_rate;
    if (status < 0)
	status = errno;
    return status;
}

int PortalInterface::dumpRegs()
{
    int foo = 0;
    int rc = ioctl(portal.fds[0].fd, PORTAL_REGS, &foo);
    return rc;
}

int PortalInterface::exec(idleFunc func)
{
    unsigned int *buf = new unsigned int[1024];
    PortalMessage *msg = (PortalMessage *)(buf);
    fprintf(stderr, "PortalInterface::exec()\n");
    int messageReceived = 0;

    if (!portal.numFds) {
        fprintf(stderr, "PortalInterface::exec No fds open\n");
        return -ENODEV;
    }

    int rc;
    while ((rc = poll(portal.fds, portal.numFds, 100)) >= 0) {
        //fprintf(stderr, "pid %d poll rc=%d\n", getpid(), rc);
        for (int i = 0; i < portal.numFds; i++) {
            if (portal.fds[i].revents == 0)
                continue;
            if (!portal.instances) {
                fprintf(stderr, "No instances but rc=%d revents=%d\n", rc, portal.fds[i].revents);
            }
            PortalInstance *instance = portal.instances[i];
            memset(buf, 0, 1024);
            int messageReceived = instance->receiveMessage(msg);
            //fprintf(stderr, "messageReceived=%d\n", messageReceived);
            if (!messageReceived)
                continue;
            size_t size = msg->size;
            //fprintf(stderr, "msg->size=%d msg->channel=%d\n", msg->size, msg->channel);
            if (!size)
                continue;
	    if (instance->indications)
		instance->indications->handleMessage(msg);
        }
        if (rc == 0) {
            if (0)
            ALOGD("poll returned rc=%d errno=%d:%s func=%p\n",
                  rc, errno, strerror(errno), func);
          if (func)
            func();
        }
    }
    if (rc < 0) {
        fprintf(stderr, "poll returned rc=%d errno=%d:%s\n", rc, errno, strerror(errno));
        return rc;
    }

    return 0;
}
<|endoftext|>