<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id:  */

//____________________________________________________________________
//
// T0 - T0.
//
// This class is a singleton that handles various parameters of
// the T0 detectors.
// Eventually, this class will use the Conditions DB to get the
// various parameters, which code can then request from here.
//
#include "AliT0.h"
#include "AliLog.h"
#include "AliT0Parameters.h"
#include "AliT0CalibData.h"
#include "AliT0CalibWalk.h"
#include "AliT0CalibTimeEq.h"
#include "AliT0CalibLatency.h"
#include "AliT0LookUpKey.h"
#include "AliT0LookUpValue.h"
#include <AliCDBManager.h>
#include <AliCDBEntry.h>
#include <AliCDBStorage.h>
#include <TMath.h>
#include <TSystem.h>
//#include <Riostream.h>
#include <TGeoManager.h>
#include <TGeoPhysicalNode.h>
#include <TGeoMatrix.h>
#include <AliGeomManager.h>

AliT0CalibTimeEq* AliT0Parameters::fgCalibData = 0;
AliT0CalibData* AliT0Parameters::fgLookUp = 0;
AliT0CalibWalk* AliT0Parameters::fgSlewCorr =0;
AliT0CalibLatency *AliT0Parameters::fgLatency=0;
//====================================================================
ClassImp(AliT0Parameters)
#if 0
  ; // This is here to keep Emacs for indenting the next line
#endif

//____________________________________________________________________
AliT0Parameters* AliT0Parameters::fgInstance = 0;
//____________________________________________________________________
AliT0Parameters* AliT0Parameters::Instance()
{
  // Get static instance
  if (!fgInstance) {
    fgInstance = new AliT0Parameters;
  }
  return fgInstance;
}

//____________________________________________________________________
AliT0Parameters::AliT0Parameters()
  :fIsInit(kFALSE),
   fPh2Mip(0),fmV2Mip(0),
   fChannelWidth(0),fmV2Channel(0),
   fQTmin(0),fQTmax(0),
   fAmpLEDRec(0),
   fPMTeff(),
   fWalk(0),
   fQTC(0),
   fAmpLED(0),
   fTimeDelayCFD(0),
 //  fTimeV0(0),
   fTimeDelayTVD(0),
   fMeanT0(512),
   fMeanVertex(0),
   fLookUp(0),
   fNumberOfTRMs(2),
   fCalibentry(), fLookUpentry(),fSlewCorr()

{
  // Default constructor
  for (Int_t ipmt=0; ipmt<24; ipmt++)
    {
      SetPh2Mip();
      SetmV2Mip();
      SetChannelWidth();
      SetmV2channel();
      SetQTmin();
      SetQTmax();
      SetPMTeff(ipmt);
    }
  SetTimeDelayTVD();
  SetZposition();

}

//__________________________________________________________________
void
AliT0Parameters::Init()
{
  // Initialize the parameters manager.  We need to get stuff from the
  // CDB here.
   if (fIsInit) return;

   AliCDBManager *stor =AliCDBManager::Instance();
   //time equalizing
   fCalibentry  = stor->Get("T0/Calib/TimeDelay");
   if (fCalibentry)
     fgCalibData  = (AliT0CalibTimeEq*)fCalibentry->GetObject();
   else {
         AliFatal(" ALARM !!!! No time delays in CDB ");
     fIsInit = kFALSE;
     return;
   }
 //slewing correction
  fSlewCorr  = stor->Get("T0/Calib/Slewing_Walk");
  if (fSlewCorr){
    fgSlewCorr  = (AliT0CalibWalk*)fSlewCorr->GetObject();
  }
  else {
      AliFatal(" ALARM !!!! No slewing correction in CDB ");
    fIsInit = kFALSE;
    return;
  }
  //lookup table
  fLookUpentry  = stor->Get("T0/Calib/LookUp_Table");
  if (fLookUpentry){
    fgLookUp  = (AliT0CalibData*)fLookUpentry->GetObject();
  }
  else {
     AliFatal(" ALARM !!!! No Lookup table  in CDB ");
    fIsInit = kFALSE;
    return;
  }
  //latency

 fLatency  = stor->Get("T0/Calib/Latency");
  if (fLatency){
    fgLatency  = (AliT0CalibLatency*)fLatency->GetObject();
  }
  else {
     AliWarning(" !!! no latency  in CDB ");
    return;
  }

fIsInit = kTRUE;
}

//__________________________________________________________________

void AliT0Parameters::InitIfOnline()
{
// should be used in online
// for switching to this one should write
  // AliT0RawReader myrawreader(rawReader);
//	myrawreader.SetOnlineMode(kTRUE);

  if (fIsInit) return;
   //standart configuration (used for simulation)
   //Int_t trm=0; Int_t tdc=0; Int_t chain=0; Int_t channel=0;
  // configuration for test Jun07.
   fgLookUp = new AliT0CalibData("T0");

  fNumberOfTRMs = 1;
 fgLookUp-> SetNumberOfTRMs(fNumberOfTRMs);
  Int_t trm=7; Int_t tdc=0; Int_t chain=0; Int_t channel=0;
  for (Int_t ik=0; ik<105; ik++)
        {
         AliT0LookUpKey * lookkey= new AliT0LookUpKey();
         AliT0LookUpValue * lookvalue= new AliT0LookUpValue();

          lookvalue->SetTRM(trm);
          lookvalue->SetTDC(tdc);
          lookvalue->SetChain(chain);
          lookvalue->SetChannel(channel);
          lookkey->SetKey(ik);
	  fgLookUp->GetMapLookup()->Add((TObject*)lookvalue,(TObject*)lookkey);
	  if (channel<6) channel +=2;
	  else {channel = 0; tdc++;}
	  if(ik==56) { tdc=0; channel=0; chain = 1;}

       }

  fIsInit=kTRUE;
}
//__________________________________________________________________
Float_t
AliT0Parameters::GetTimeDelayCFD(Int_t ipmt)
  {
  // return time delay for CFD channel
   //
  if (!fCalibentry)
    {
      fTimeDelayCFD = 1000+ipmt*100;
      return fTimeDelayCFD;
    }

  return fgCalibData->GetTimeEq(ipmt);
}

//__________________________________________________________________
Float_t
AliT0Parameters::GetLatencyHPTDC()
  {
  // return LatencyHPTDC for CFD channel
  if (!fLatency)
    {
      fLatencyHPTDC=9000.;
      return fLatencyHPTDC;
    }

  return fgLatency->GetLatencyHPTDC();
}
//__________________________________________________________________
Float_t
AliT0Parameters::GetLatencyL1()
  {
  // return time delay for CFD channel

  return fgLatency->GetLatencyL1();
}

//__________________________________________________________________
Float_t
AliT0Parameters::GetLatencyL1A()
  {
  // return time delay for CFD channel

  return fgLatency->GetLatencyL1A();
}

//__________________________________________________________________
Float_t
AliT0Parameters::GetLatencyL1C()
  {
  // return time delay for CFD channel

  return fgLatency->GetLatencyL1C();
}
//__________________________________________________________________

Float_t
AliT0Parameters:: GetMeanVertex()
{
  if (!fCalibentry)
    {
      fMeanVertex=0;
      return fMeanVertex;
    }

  return fgCalibData->GetMeanVertex();
}
//__________________________________________________________________

TGraph *AliT0Parameters::GetAmpLEDRec(Int_t ipmt) const
{
   if (!fSlewCorr) {
     AliError("No slewing correction is available!");
     return  (TGraph*)fAmpLEDRec.At(ipmt);
  }
  return fgSlewCorr -> GetAmpLEDRec(ipmt) ;
}

//__________________________________________________________________

TGraph *AliT0Parameters::GetWalk(Int_t ipmt) const
{
  if (!fSlewCorr) {
    AliError("No walk correction is available!");
    return  (TGraph*)fWalk.At(ipmt);
  }
  return fgSlewCorr -> GetWalk(ipmt) ;
}

//__________________________________________________________________

TGraph *AliT0Parameters::GetQTC(Int_t ipmt) const
{
  if (!fSlewCorr) {
    AliError("No walk correction is available!");
    //    return  (TGraph*)fQTC.At(ipmt);
   return  0;
  }
  return fgSlewCorr -> GetQTC(ipmt) ;
}

//__________________________________________________________________
TGraph *AliT0Parameters::GetAmpLED(Int_t ipmt) const
{
  if (!fSlewCorr) {
    AliError("No walk correction is available!");
    //    return  (TGraph*)fQTC.At(ipmt);
   return  0;
  }
  return fgSlewCorr -> GetAmpLED(ipmt) ;
}

//__________________________________________________________________
void
AliT0Parameters::SetPMTeff(Int_t ipmt)
{
  Float_t lambda[50];
  Float_t eff[50 ] = {0,        0,       0.23619,  0.202909, 0.177913,
		    0.175667, 0.17856, 0.190769, 0.206667, 0.230286,
		    0.252276, 0.256267,0.26,     0.27125,  0.281818,
		    0.288118, 0.294057,0.296222, 0.301622, 0.290421,
		    0.276615, 0.2666,  0.248,    0.23619,  0.227814,
		    0.219818, 0.206667,0.194087, 0.184681, 0.167917,
		    0.154367, 0.1364,  0.109412, 0.0834615,0.0725283,
		    0.0642963,0.05861, 0.0465,   0.0413333,0.032069,
		    0.0252203,0.02066, 0.016262, 0.012,    0.00590476,
		    0.003875, 0.00190, 0,        0,        0          } ;
  for (Int_t i=0; i<50; i++) lambda[i]=200+10*i;

  TGraph* gr = new TGraph(50,lambda,eff);
  fPMTeff.AddAtAndExpand(gr,ipmt);
}
//________________________________________________________________

Int_t
AliT0Parameters::GetChannel(Int_t trm,  Int_t tdc, Int_t chain, Int_t channel)
{

  if (fgLookUp) {
    AliT0LookUpValue key(trm,tdc,chain,channel);
      AliT0LookUpKey *val = (AliT0LookUpKey*) fgLookUp->GetMapLookup()->GetValue((TObject*)&key);
      // AliT0LookUpKey *val = (AliT0LookUpKey*) fLookUp.GetValue((TObject*)&key);
    if (val )
      return val->GetKey();
    else {
      AliWarning(Form("No such address (%d %d %d %d)!",trm,tdc,chain,channel));
      return -1;
    }
  }
  else {
    AliError("No look up table has been loader!");
    return -1;
  }

}
//__________________________________________________________________
TMap *AliT0Parameters::GetMapLookup()
{
  if (!fgLookUp){
    cout<<" No look up table in OCDB";
    return 0;
  }
  return   fgLookUp->GetMapLookup();
}
//__________________________________________________________________

Int_t
AliT0Parameters::GetNumberOfTRMs()
{
  // return number of trms
  //
  if (!fgLookUp) {
    //  fNumberOfTRMs = 2;
    return  fNumberOfTRMs;
  }
  return  fgLookUp ->GetNumberOfTRMs();
}
/*
//________________________________________________________________________________
Double_t AliT0Parameters::GetZPosition(const char* symname){
// Get the global z coordinate of the given T0 alignable volume
//
  Double_t *tr = AliGeomManager::GetMatrix(symname)->GetTranslation();

  return tr[2];
}
*/
//________________________________________________________________________________
Double_t AliT0Parameters::GetZPosition(const char* symname){
// Get the global z coordinate of the given T0 alignable volume
//
  Double_t *tr;
  TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(symname);
  if (!pne) return 0;

  TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
  if(pnode){
          TGeoHMatrix* hm = pnode->GetMatrix();
           tr = hm->GetTranslation();
  }else{
          const char* path = pne->GetTitle();
          if(!gGeoManager->cd(path)){
                  AliErrorClass(Form("Volume path %s not valid!",path));
                  return 0;
          }
         tr = gGeoManager->GetCurrentMatrix()->GetTranslation();
  }
  return tr[2];

}
//________________________________________________________________________________

Double_t AliT0Parameters::GetZPositionShift(const char* symname)
{
// Get the global z coordinate of the given T0 alignable volume
//
  Double_t *tr = AliGeomManager::GetMatrix(symname)->GetTranslation();

  TGeoHMatrix origmat;
  AliGeomManager::GetOrigGlobalMatrix(symname,origmat);
  Double_t *otr = origmat.GetTranslation();

  return (tr[2]-otr[2]);
}

<commit_msg>fixed warnings<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id:  */

//____________________________________________________________________
//
// T0 - T0.
//
// This class is a singleton that handles various parameters of
// the T0 detectors.
// Eventually, this class will use the Conditions DB to get the
// various parameters, which code can then request from here.
//
#include "AliT0.h"
#include "AliLog.h"
#include "AliT0Parameters.h"
#include "AliT0CalibData.h"
#include "AliT0CalibWalk.h"
#include "AliT0CalibTimeEq.h"
#include "AliT0CalibLatency.h"
#include "AliT0LookUpKey.h"
#include "AliT0LookUpValue.h"
#include <AliCDBManager.h>
#include <AliCDBEntry.h>
#include <AliCDBStorage.h>
#include <TMath.h>
#include <TSystem.h>
//#include <Riostream.h>
#include <TGeoManager.h>
#include <TGeoPhysicalNode.h>
#include <TGeoMatrix.h>
#include <AliGeomManager.h>

AliT0CalibTimeEq* AliT0Parameters::fgCalibData = 0;
AliT0CalibData* AliT0Parameters::fgLookUp = 0;
AliT0CalibWalk* AliT0Parameters::fgSlewCorr =0;
AliT0CalibLatency *AliT0Parameters::fgLatency=0;
//====================================================================
ClassImp(AliT0Parameters)
#if 0
  ; // This is here to keep Emacs for indenting the next line
#endif

//____________________________________________________________________
AliT0Parameters* AliT0Parameters::fgInstance = 0;
//____________________________________________________________________
AliT0Parameters* AliT0Parameters::Instance()
{
  // Get static instance
  if (!fgInstance) {
    fgInstance = new AliT0Parameters;
  }
  return fgInstance;
}

//____________________________________________________________________
AliT0Parameters::AliT0Parameters()
  :fIsInit(kFALSE),
   fPh2Mip(0),fmV2Mip(0),
   fChannelWidth(0),fmV2Channel(0),
   fQTmin(0),fQTmax(0),
   fAmpLEDRec(0),
   fPMTeff(),
   fWalk(0),
   fQTC(0),
   fAmpLED(0),
   fTimeDelayCFD(0),
 //  fTimeV0(0),
   fTimeDelayTVD(0),
   fMeanT0(512),
   fMeanVertex(0),
   fLatencyHPTDC(0),
   fLatencyL1(0),
   fLatencyL1A(0),
   fLatencyL1C(0),
   fLookUp(0),
   fNumberOfTRMs(2),
   fCalibentry(), fLookUpentry(),fSlewCorr()

{
  // Default constructor
  for (Int_t ipmt=0; ipmt<24; ipmt++)
    {
      SetPh2Mip();
      SetmV2Mip();
      SetChannelWidth();
      SetmV2channel();
      SetQTmin();
      SetQTmax();
      SetPMTeff(ipmt);
    }
  SetTimeDelayTVD();
  SetZposition();

}

//__________________________________________________________________
void
AliT0Parameters::Init()
{
  // Initialize the parameters manager.  We need to get stuff from the
  // CDB here.
   if (fIsInit) return;

   AliCDBManager *stor =AliCDBManager::Instance();
   //time equalizing
   fCalibentry  = stor->Get("T0/Calib/TimeDelay");
   if (fCalibentry)
     fgCalibData  = (AliT0CalibTimeEq*)fCalibentry->GetObject();
   else {
         AliFatal(" ALARM !!!! No time delays in CDB ");
     fIsInit = kFALSE;
     return;
   }
 //slewing correction
  fSlewCorr  = stor->Get("T0/Calib/Slewing_Walk");
  if (fSlewCorr){
    fgSlewCorr  = (AliT0CalibWalk*)fSlewCorr->GetObject();
  }
  else {
      AliFatal(" ALARM !!!! No slewing correction in CDB ");
    fIsInit = kFALSE;
    return;
  }
  //lookup table
  fLookUpentry  = stor->Get("T0/Calib/LookUp_Table");
  if (fLookUpentry){
    fgLookUp  = (AliT0CalibData*)fLookUpentry->GetObject();
  }
  else {
     AliFatal(" ALARM !!!! No Lookup table  in CDB ");
    fIsInit = kFALSE;
    return;
  }
  //latency

 fLatency  = stor->Get("T0/Calib/Latency");
  if (fLatency){
    fgLatency  = (AliT0CalibLatency*)fLatency->GetObject();
  }
  else {
     AliWarning(" !!! no latency  in CDB ");
    return;
  }

fIsInit = kTRUE;
}

//__________________________________________________________________

void AliT0Parameters::InitIfOnline()
{
// should be used in online
// for switching to this one should write
  // AliT0RawReader myrawreader(rawReader);
//	myrawreader.SetOnlineMode(kTRUE);

  if (fIsInit) return;
   //standart configuration (used for simulation)
   //Int_t trm=0; Int_t tdc=0; Int_t chain=0; Int_t channel=0;
  // configuration for test Jun07.
   fgLookUp = new AliT0CalibData("T0");

  fNumberOfTRMs = 1;
 fgLookUp-> SetNumberOfTRMs(fNumberOfTRMs);
  Int_t trm=7; Int_t tdc=0; Int_t chain=0; Int_t channel=0;
  for (Int_t ik=0; ik<105; ik++)
        {
         AliT0LookUpKey * lookkey= new AliT0LookUpKey();
         AliT0LookUpValue * lookvalue= new AliT0LookUpValue();

          lookvalue->SetTRM(trm);
          lookvalue->SetTDC(tdc);
          lookvalue->SetChain(chain);
          lookvalue->SetChannel(channel);
          lookkey->SetKey(ik);
	  fgLookUp->GetMapLookup()->Add((TObject*)lookvalue,(TObject*)lookkey);
	  if (channel<6) channel +=2;
	  else {channel = 0; tdc++;}
	  if(ik==56) { tdc=0; channel=0; chain = 1;}

       }

  fIsInit=kTRUE;
}
//__________________________________________________________________
Float_t
AliT0Parameters::GetTimeDelayCFD(Int_t ipmt)
  {
  // return time delay for CFD channel
   //
  if (!fCalibentry)
    {
      fTimeDelayCFD = 1000+ipmt*100;
      return fTimeDelayCFD;
    }

  return fgCalibData->GetTimeEq(ipmt);
}

//__________________________________________________________________
Float_t
AliT0Parameters::GetLatencyHPTDC()
  {
  // return LatencyHPTDC for CFD channel
  if (!fLatency)
    {
      fLatencyHPTDC=9000.;
      return fLatencyHPTDC;
    }

  return fgLatency->GetLatencyHPTDC();
}
//__________________________________________________________________
Float_t
AliT0Parameters::GetLatencyL1()
  {
  // return time delay for CFD channel

  return fgLatency->GetLatencyL1();
}

//__________________________________________________________________
Float_t
AliT0Parameters::GetLatencyL1A()
  {
  // return time delay for CFD channel

  return fgLatency->GetLatencyL1A();
}

//__________________________________________________________________
Float_t
AliT0Parameters::GetLatencyL1C()
  {
  // return time delay for CFD channel

  return fgLatency->GetLatencyL1C();
}
//__________________________________________________________________

Float_t
AliT0Parameters:: GetMeanVertex()
{
  if (!fCalibentry)
    {
      fMeanVertex=0;
      return fMeanVertex;
    }

  return fgCalibData->GetMeanVertex();
}
//__________________________________________________________________

TGraph *AliT0Parameters::GetAmpLEDRec(Int_t ipmt) const
{
   if (!fSlewCorr) {
     AliError("No slewing correction is available!");
     return  (TGraph*)fAmpLEDRec.At(ipmt);
  }
  return fgSlewCorr -> GetAmpLEDRec(ipmt) ;
}

//__________________________________________________________________

TGraph *AliT0Parameters::GetWalk(Int_t ipmt) const
{
  if (!fSlewCorr) {
    AliError("No walk correction is available!");
    return  (TGraph*)fWalk.At(ipmt);
  }
  return fgSlewCorr -> GetWalk(ipmt) ;
}

//__________________________________________________________________

TGraph *AliT0Parameters::GetQTC(Int_t ipmt) const
{
  if (!fSlewCorr) {
    AliError("No walk correction is available!");
    //    return  (TGraph*)fQTC.At(ipmt);
   return  0;
  }
  return fgSlewCorr -> GetQTC(ipmt) ;
}

//__________________________________________________________________
TGraph *AliT0Parameters::GetAmpLED(Int_t ipmt) const
{
  if (!fSlewCorr) {
    AliError("No walk correction is available!");
    //    return  (TGraph*)fQTC.At(ipmt);
   return  0;
  }
  return fgSlewCorr -> GetAmpLED(ipmt) ;
}

//__________________________________________________________________
void
AliT0Parameters::SetPMTeff(Int_t ipmt)
{
  Float_t lambda[50];
  Float_t eff[50 ] = {0,        0,       0.23619,  0.202909, 0.177913,
		    0.175667, 0.17856, 0.190769, 0.206667, 0.230286,
		    0.252276, 0.256267,0.26,     0.27125,  0.281818,
		    0.288118, 0.294057,0.296222, 0.301622, 0.290421,
		    0.276615, 0.2666,  0.248,    0.23619,  0.227814,
		    0.219818, 0.206667,0.194087, 0.184681, 0.167917,
		    0.154367, 0.1364,  0.109412, 0.0834615,0.0725283,
		    0.0642963,0.05861, 0.0465,   0.0413333,0.032069,
		    0.0252203,0.02066, 0.016262, 0.012,    0.00590476,
		    0.003875, 0.00190, 0,        0,        0          } ;
  for (Int_t i=0; i<50; i++) lambda[i]=200+10*i;

  TGraph* gr = new TGraph(50,lambda,eff);
  fPMTeff.AddAtAndExpand(gr,ipmt);
}
//________________________________________________________________

Int_t
AliT0Parameters::GetChannel(Int_t trm,  Int_t tdc, Int_t chain, Int_t channel)
{

  if (fgLookUp) {
    AliT0LookUpValue key(trm,tdc,chain,channel);
      AliT0LookUpKey *val = (AliT0LookUpKey*) fgLookUp->GetMapLookup()->GetValue((TObject*)&key);
      // AliT0LookUpKey *val = (AliT0LookUpKey*) fLookUp.GetValue((TObject*)&key);
    if (val )
      return val->GetKey();
    else {
      AliWarning(Form("No such address (%d %d %d %d)!",trm,tdc,chain,channel));
      return -1;
    }
  }
  else {
    AliError("No look up table has been loader!");
    return -1;
  }

}
//__________________________________________________________________
TMap *AliT0Parameters::GetMapLookup()
{
  if (!fgLookUp){
    cout<<" No look up table in OCDB";
    return 0;
  }
  return   fgLookUp->GetMapLookup();
}
//__________________________________________________________________

Int_t
AliT0Parameters::GetNumberOfTRMs()
{
  // return number of trms
  //
  if (!fgLookUp) {
    //  fNumberOfTRMs = 2;
    return  fNumberOfTRMs;
  }
  return  fgLookUp ->GetNumberOfTRMs();
}
/*
//________________________________________________________________________________
Double_t AliT0Parameters::GetZPosition(const char* symname){
// Get the global z coordinate of the given T0 alignable volume
//
  Double_t *tr = AliGeomManager::GetMatrix(symname)->GetTranslation();

  return tr[2];
}
*/
//________________________________________________________________________________
Double_t AliT0Parameters::GetZPosition(const char* symname){
// Get the global z coordinate of the given T0 alignable volume
//
  Double_t *tr;
  TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(symname);
  if (!pne) return 0;

  TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
  if(pnode){
          TGeoHMatrix* hm = pnode->GetMatrix();
           tr = hm->GetTranslation();
  }else{
          const char* path = pne->GetTitle();
          if(!gGeoManager->cd(path)){
                  AliErrorClass(Form("Volume path %s not valid!",path));
                  return 0;
          }
         tr = gGeoManager->GetCurrentMatrix()->GetTranslation();
  }
  return tr[2];

}
//________________________________________________________________________________

Double_t AliT0Parameters::GetZPositionShift(const char* symname)
{
// Get the global z coordinate of the given T0 alignable volume
//
  Double_t *tr = AliGeomManager::GetMatrix(symname)->GetTranslation();

  TGeoHMatrix origmat;
  AliGeomManager::GetOrigGlobalMatrix(symname,origmat);
  Double_t *otr = origmat.GetTranslation();

  return (tr[2]-otr[2]);
}

<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>

using namespace std;

int main() {
    int a, b;
    cin >> a >> b;
    cout << "SOMA = " << a + b << endl;
}
<commit_msg>remove unused include<commit_after>#include <iostream>

using namespace std;

int main() {
    int a, b;
    cin >> a >> b;
    cout << "SOMA = " << a + b << endl;
}
<|endoftext|>


<commit_before><commit_msg>Camera: put flag aarch64 to avoid calling set_adv_trigger on ARM platform (#8980)<commit_after><|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkCollection.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkCollection.h"
#include "vtkObjectFactory.h"

#include <stdlib.h>
#include <math.h>

vtkCxxRevisionMacro(vtkCollection, "1.40");
vtkStandardNewMacro(vtkCollection);

// Construct with empty list.
vtkCollection::vtkCollection()
{
  this->NumberOfItems = 0;
  this->Top = NULL;
  this->Bottom = NULL;
  this->Current = NULL;
}

// Desctructor for the vtkCollection class. This removes all
// objects from the collection.
vtkCollection::~vtkCollection()
{
  vtkCollectionElement *elem;

  while (this->NumberOfItems )
    {
    elem = this->Top;
    this->Top = elem->Next;
    this->Current = elem->Next;
    this->DeleteElement(elem);
    this->NumberOfItems--;
    }
}

// protected function to delete an element. Internal use only.
void vtkCollection::DeleteElement(vtkCollectionElement *e)
{
  if (e->Item != NULL)
    {
    e->Item->UnRegister(this);
    }
  delete e;
}

// Add an object to the list. Does not prevent duplicate entries.
void vtkCollection::AddItem(vtkObject *a)
{
  vtkCollectionElement *elem;

  elem = new vtkCollectionElement;

  if (!this->Top)
    {
    this->Top = elem;
    }
  else
    {
    this->Bottom->Next = elem;
    }
  this->Bottom = elem;

  a->Register(this);
  elem->Item = a;
  elem->Next = NULL;

  this->Modified();

  this->NumberOfItems++;
}

// Remove an object from the list. Removes the first object found, not
// all occurrences. If no object found, list is unaffected.  See warning
// in description of RemoveItem(int).
void vtkCollection::RemoveItem(vtkObject *a)
{
  int i;
  vtkCollectionElement *elem;

  if (!this->Top)
    {
    return;
    }

  elem = this->Top;
  for (i = 0; i < this->NumberOfItems; i++)
    {
    if (elem->Item == a)
      {
      this->RemoveItem(i);
      this->Modified();
      return;
      }
    else
      {
      elem = elem->Next;
      }
    }
}

// Remove all objects from the list.
void vtkCollection::RemoveAllItems()
{
  vtkCollectionElement *elem;

  while (this->NumberOfItems )
    {
    elem = this->Top;
    this->Top = elem->Next;
    this->Current = elem->Next;
    this->DeleteElement(elem);
    this->NumberOfItems--;
    }

  this->Modified();
}

// Search for an object and return location in list. If location == 0,
// object was not found.
int vtkCollection::IsItemPresent(vtkObject *a)
{
  int i;
  vtkCollectionElement *elem;

  if (!this->Top)
    {
    return 0;
    }

  elem = this->Top;
  for (i = 0; i < this->NumberOfItems; i++)
    {
    if (elem->Item == a)
      {
      return i + 1;
      }
    else
      {
      elem = elem->Next;
      }
    }

  return 0;
}

// Return the number of objects in the list.
int vtkCollection::GetNumberOfItems()
{
  return this->NumberOfItems;
}

void vtkCollection::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Number Of Items: " << this->NumberOfItems << "\n";
}

// Get the i'th item in the collection. NULL is returned if i is out
// of range
vtkObject *vtkCollection::GetItemAsObject(int i)
{
  vtkCollectionElement *elem=this->Top;

  if (i < 0)
    {
    return NULL;
    }

  while (elem != NULL && i > 0)
    {
    elem = elem->Next;
    i--;
    }

  if ( elem != NULL )
    {
    return elem->Item;
    }
  else
    {
    return NULL;
    }
}

// Replace the i'th item in the collection with a
void vtkCollection::ReplaceItem(int i, vtkObject *a)
{
  vtkCollectionElement *elem;

  if( i < 0 || i >= this->NumberOfItems )
    {
    return;
    }

  elem = this->Top;
  for (int j = 0; j < i; j++, elem = elem->Next )
    {}

  // Take care of reference counting
  if (elem->Item != NULL)
    {
    elem->Item->UnRegister(this);
    }
  a->Register(this);

  // j == i
  elem->Item = a;

  this->Modified();
}

// Remove the i'th item in the list.
// Be careful if using this function during traversal of the list using
// GetNextItemAsObject (or GetNextItem in derived class).  The list WILL
// be shortened if a valid index is given!  If this->Current is equal to the
// element being removed, have it point to then next element in the list.
void vtkCollection::RemoveItem(int i)
{
  vtkCollectionElement *elem,*prev;

  if( i < 0 || i >= this->NumberOfItems )
    {
    return;
    }

  this->Modified();

  elem = this->Top;
  prev = NULL;
  for (int j = 0; j < i; j++)
    {
    prev = elem;
    elem = elem->Next;
    }

  // j == i
  if (prev)
    {
    prev->Next = elem->Next;
    }
  else
    {
    this->Top = elem->Next;
    }

  if (!elem->Next)
    {
    this->Bottom = prev;
    }

  if ( this->Current == elem )
    {
    this->Current = elem->Next;
    }

  this->DeleteElement(elem);
  this->NumberOfItems--;
}

<commit_msg>Optimize for the case where the last element of the collection is being accessed or replaced.  It's only one compare per access, versus searching the whole list.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkCollection.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkCollection.h"
#include "vtkObjectFactory.h"

#include <stdlib.h>
#include <math.h>

vtkCxxRevisionMacro(vtkCollection, "1.41");
vtkStandardNewMacro(vtkCollection);

// Construct with empty list.
vtkCollection::vtkCollection()
{
  this->NumberOfItems = 0;
  this->Top = NULL;
  this->Bottom = NULL;
  this->Current = NULL;
}

// Desctructor for the vtkCollection class. This removes all
// objects from the collection.
vtkCollection::~vtkCollection()
{
  vtkCollectionElement *elem;

  while (this->NumberOfItems )
    {
    elem = this->Top;
    this->Top = elem->Next;
    this->Current = elem->Next;
    this->DeleteElement(elem);
    this->NumberOfItems--;
    }
}

// protected function to delete an element. Internal use only.
void vtkCollection::DeleteElement(vtkCollectionElement *e)
{
  if (e->Item != NULL)
    {
    e->Item->UnRegister(this);
    }
  delete e;
}

// Add an object to the list. Does not prevent duplicate entries.
void vtkCollection::AddItem(vtkObject *a)
{
  vtkCollectionElement *elem;

  elem = new vtkCollectionElement;

  if (!this->Top)
    {
    this->Top = elem;
    }
  else
    {
    this->Bottom->Next = elem;
    }
  this->Bottom = elem;

  a->Register(this);
  elem->Item = a;
  elem->Next = NULL;

  this->Modified();

  this->NumberOfItems++;
}

// Remove an object from the list. Removes the first object found, not
// all occurrences. If no object found, list is unaffected.  See warning
// in description of RemoveItem(int).
void vtkCollection::RemoveItem(vtkObject *a)
{
  int i;
  vtkCollectionElement *elem;

  if (!this->Top)
    {
    return;
    }

  elem = this->Top;
  for (i = 0; i < this->NumberOfItems; i++)
    {
    if (elem->Item == a)
      {
      this->RemoveItem(i);
      this->Modified();
      return;
      }
    else
      {
      elem = elem->Next;
      }
    }
}

// Remove all objects from the list.
void vtkCollection::RemoveAllItems()
{
  vtkCollectionElement *elem;

  while (this->NumberOfItems )
    {
    elem = this->Top;
    this->Top = elem->Next;
    this->Current = elem->Next;
    this->DeleteElement(elem);
    this->NumberOfItems--;
    }

  this->Modified();
}

// Search for an object and return location in list. If location == 0,
// object was not found.
int vtkCollection::IsItemPresent(vtkObject *a)
{
  int i;
  vtkCollectionElement *elem;

  if (!this->Top)
    {
    return 0;
    }

  elem = this->Top;
  for (i = 0; i < this->NumberOfItems; i++)
    {
    if (elem->Item == a)
      {
      return i + 1;
      }
    else
      {
      elem = elem->Next;
      }
    }

  return 0;
}

// Return the number of objects in the list.
int vtkCollection::GetNumberOfItems()
{
  return this->NumberOfItems;
}

void vtkCollection::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Number Of Items: " << this->NumberOfItems << "\n";
}

// Get the i'th item in the collection. NULL is returned if i is out
// of range
vtkObject *vtkCollection::GetItemAsObject(int i)
{
  vtkCollectionElement *elem=this->Top;

  if (i < 0)
    {
    return NULL;
    }

  if (i == this->NumberOfItems - 1)
    {
    // optimize for the special case where we're looking for the last elem
    elem = this->Bottom;
    }
  else
    {
    while (elem != NULL && i > 0)
      {
      elem = elem->Next;
      i--;
      }
    }
  if ( elem != NULL )
    {
    return elem->Item;
    }
  else
    {
    return NULL;
    }
}

// Replace the i'th item in the collection with a
void vtkCollection::ReplaceItem(int i, vtkObject *a)
{
  vtkCollectionElement *elem;

  if( i < 0 || i >= this->NumberOfItems )
    {
    return;
    }

  elem = this->Top;
  if (i == this->NumberOfItems - 1)
    {
    elem = this->Bottom;
    }
  else
    {
    for (int j = 0; j < i; j++, elem = elem->Next )
      {}
    }

  // Take care of reference counting
  if (elem->Item != NULL)
    {
    elem->Item->UnRegister(this);
    }
  a->Register(this);

  // j == i
  elem->Item = a;

  this->Modified();
}

// Remove the i'th item in the list.
// Be careful if using this function during traversal of the list using
// GetNextItemAsObject (or GetNextItem in derived class).  The list WILL
// be shortened if a valid index is given!  If this->Current is equal to the
// element being removed, have it point to then next element in the list.
void vtkCollection::RemoveItem(int i)
{
  vtkCollectionElement *elem,*prev;

  if( i < 0 || i >= this->NumberOfItems )
    {
    return;
    }

  this->Modified();

  elem = this->Top;
  prev = NULL;
  for (int j = 0; j < i; j++)
    {
    prev = elem;
    elem = elem->Next;
    }

  // j == i
  if (prev)
    {
    prev->Next = elem->Next;
    }
  else
    {
    this->Top = elem->Next;
    }

  if (!elem->Next)
    {
    this->Bottom = prev;
    }

  if ( this->Current == elem )
    {
    this->Current = elem->Next;
    }

  this->DeleteElement(elem);
  this->NumberOfItems--;
}

<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/XMLString.hpp>
#include <util/XMLUniDefs.hpp>
#include <util/XMLUni.hpp>
#include <framework/XMLBuffer.hpp>
#include <validators/common/DFAContentModel.hpp>
#include <validators/common/ContentSpecNode.hpp>
#include <validators/common/MixedContentModel.hpp>
#include <validators/common/SimpleContentModel.hpp>
#include <validators/DTD/DTDAttDefList.hpp>
#include <validators/DTD/DTDElementDecl.hpp>

// ---------------------------------------------------------------------------
//  DTDElementDecl: Destructor is out of line to prevent having to expose
//  the ContentSpecNode header.
// ---------------------------------------------------------------------------
DTDElementDecl::~DTDElementDecl()
{
    delete fAttDefs;
    delete fAttList;
    delete fContentSpec;
    delete [] fBaseName;
    delete [] fQName;
}

// ---------------------------------------------------------------------------
//  The virtual element decl interface
// ---------------------------------------------------------------------------
XMLAttDef* DTDElementDecl::findAttr(const   XMLCh* const    qName
                                    , const unsigned int    uriId
                                    , const XMLCh* const    baseName
                                    , const XMLCh* const    prefix
                                    , const LookupOpts      options
                                    ,       bool&           wasAdded) const
{
    DTDAttDef* retVal = 0;

    // If no att list faulted in yet, then it cannot exist
    if (fAttDefs)
        retVal = fAttDefs->get(qName);

    // Fault it in if not found and ask to add it
    if (!retVal && (options == XMLElementDecl::AddIfNotFound))
    {
        // Fault in the list itself if not already
        if (!fAttDefs)
            faultInAttDefList();

        // And add a default attribute for this name
        retVal = new DTDAttDef(qName);
        retVal->setElemId(getId());
        fAttDefs->put((void*)retVal->getFullName(), retVal);

        wasAdded = true;
    }
     else
    {
        wasAdded = false;
    }
    return retVal;
}

XMLAttDefList& DTDElementDecl::getAttDefList() const
{
    if (!fAttList)
    {
        // If the att def list is not made yet, then fault it in too
        if (!fAttDefs)
            faultInAttDefList();

        ((DTDElementDecl*)this)->fAttList = new DTDAttDefList(fAttDefs);
    }

    // Reset it before we return it
    fAttList->Reset();
    return *fAttList;
}

const XMLCh* DTDElementDecl::getBaseName() const
{
    //
    //  If the base name nas not been extraced, then do it now. Since we are
    //  faulting it in from a const method, we have to cast off the constness.
    //
    if (!fBaseName)
    {
        //
        //  Search for the first colon in the name. Note that, if its not
        //  found, then it will be -1, which will still make the replicate
        //  logic work correctly.
        //
        int colonPos = XMLString::indexOf(fQName, chColon);
        ((DTDElementDecl*)this)->fBaseName = XMLString::replicate(&fQName[colonPos + 1]);
    }

    // Just return our QName
    return fBaseName;
}

XMLCh* DTDElementDecl::getBaseName()
{
    //
    //  If the base name nas not been extraced, then do it now. Since we are
    //  faulting it in from a const method, we have to cast off the constness.
    //
    if (!fBaseName)
    {
        //
        //  Search for the first colon in the name. Note that, if its not
        //  found, then it will be -1, which will still make the replicate
        //  logic work correctly.
        //
        int colonPos = XMLString::indexOf(fQName, chColon);
        ((DTDElementDecl*)this)->fBaseName = XMLString::replicate(&fQName[colonPos + 1]);
    }

    // Just return our QName
    return fBaseName;
}

XMLElementDecl::CharDataOpts DTDElementDecl::getCharDataOpts() const
{
    XMLElementDecl::CharDataOpts retVal;
    switch(fModelType)
    {
        case Children :
            retVal = XMLElementDecl::SpacesOk;
            break;

        case Empty :
            retVal = XMLElementDecl::NoCharData;
            break;

        default :
            retVal = XMLElementDecl::AllCharData;
            break;
    }
    return retVal;
}

bool DTDElementDecl::hasAttDefs() const
{
    // If the collection hasn't been faulted in, then no att defs
    if (!fAttDefs)
        return false;

    return !fAttDefs->isEmpty();
}

bool DTDElementDecl::resetDefs()
{
    // If the collection hasn't been faulted in, then no att defs
    if (!fAttDefs)
        return false;

    //
    //  Ok, run through them and clear the 'provided' flag on each of them.
    //  This lets the scanner use them to track which has been provided and
    //  which have not.
    //
    RefHashTableOfEnumerator<DTDAttDef> enumDefs(fAttDefs);
    while (enumDefs.hasMoreElements())
        enumDefs.nextElement().setProvided(false);
    return true;
}

void
DTDElementDecl::setContentSpec(ContentSpecNode* toAdopt)
{
    delete fContentSpec;
    fContentSpec = toAdopt;
}

// ---------------------------------------------------------------------------
//  DTDElementDecl: Getter methods
// ---------------------------------------------------------------------------
const DTDAttDef* DTDElementDecl::getAttDef(const XMLCh* const attName) const
{
    // If no list, then return a null
    if (!fAttDefs)
        return 0;

    return fAttDefs->get(attName);
}

DTDAttDef* DTDElementDecl::getAttDef(const XMLCh* const attName)
{
    // If no list, then return a null
    if (!fAttDefs)
        return 0;

    return fAttDefs->get(attName);
}

// ---------------------------------------------------------------------------
//  DTDElementDecl: Implementation of the protected virtual interface
// ---------------------------------------------------------------------------
void DTDElementDecl::addAttDef(DTDAttDef* const toAdd)
{
    // Fault in the att list if required
    if (!fAttDefs)
            faultInAttDefList();

    // Tell this guy the element id of its parent (us)
    toAdd->setElemId(getId());

    fAttDefs->put((void*)(toAdd->getFullName()), toAdd);
}

// ---------------------------------------------------------------------------
//  DTDElementDecl: Implementation of the protected virtual interface
// ---------------------------------------------------------------------------
XMLCh*
DTDElementDecl::formatContentModel(const Grammar& grammar) const
{
    XMLCh* newValue = 0;
    if (fModelType == Any)
    {
        newValue = XMLString::replicate(XMLUni::fgAnyString);
    }
     else if (fModelType == Empty)
    {
        newValue = XMLString::replicate(XMLUni::fgEmptyString);
    }
     else
    {
        //
        //  Use a temp XML buffer to format into. Content models could be
        //  pretty long, but very few will be longer than one K. The buffer
        //  will expand to handle the more pathological ones.
        //
        XMLBuffer bufFmt;
        fContentSpec->formatSpec(grammar, bufFmt);
        newValue = XMLString::replicate(bufFmt.getRawBuffer());
    }
    return newValue;
}

XMLContentModel* DTDElementDecl::makeContentModel(const Grammar* grammar) const
{
    XMLContentModel* cmRet = 0;
    if (fModelType == Mixed)
    {
        //
        //  Just create a mixel content model object. This type of
        //  content model is optimized for mixed content validation.
        //
        cmRet = new MixedContentModel(*this);
    }
     else if (fModelType == Children)
    {
        //
        //  This method will create an optimal model for the complexity
        //  of the element's defined model. If its simple, it will create
        //  a SimpleContentModel object. If its a simple list, it will
        //  create a SimpleListContentModel object. If its complex, it
        //  will create a DFAContentModel object.
        //
        cmRet = createChildModel(grammar);
    }
     else
    {
        ThrowXML(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren);
    }
    return cmRet;
}

// ---------------------------------------------------------------------------
//  DTDElementDecl: Private helper methods
// ---------------------------------------------------------------------------
XMLContentModel* DTDElementDecl::createChildModel(const Grammar* grammar) const
{
    // Get the content spec node of the element
    const ContentSpecNode* specNode = getContentSpec();

    //
    //  Do a sanity check that the node is does not have a PCDATA id. Since,
    //  if it was, it should have already gotten taken by the Mixed model.
    //
    if (specNode->getElemId() == XMLElementDecl::fgPCDataElemId)
        ThrowXML(RuntimeException, XMLExcepts::CM_NoPCDATAHere);

    //
    //  According to the type of node, we will create the correct type of
    //  content model.
    //
    if (specNode->getType() == ContentSpecNode::Leaf)
    {
        // Create a simple content model
        return new SimpleContentModel
        (
            specNode->getElemId()
            , XMLElementDecl::fgInvalidElemId
            , ContentSpecNode::Leaf
        );
    }
     else if ((specNode->getType() == ContentSpecNode::Choice)
          ||  (specNode->getType() == ContentSpecNode::Sequence))
    {
        //
        //  Lets see if both of the children are leafs. If so, then it has to
        //  be a simple content model
        //
        if ((specNode->getFirst()->getType() == ContentSpecNode::Leaf)
        &&  (specNode->getSecond()->getType() == ContentSpecNode::Leaf))
        {
            return new SimpleContentModel
            (
                specNode->getFirst()->getElemId()
                , specNode->getSecond()->getElemId()
                , specNode->getType()
            );
        }
    }
     else if ((specNode->getType() == ContentSpecNode::OneOrMore)
          ||  (specNode->getType() == ContentSpecNode::ZeroOrMore)
          ||  (specNode->getType() == ContentSpecNode::ZeroOrOne))
    {
        //
        //  Its a repetition, so see if its one child is a leaf. If so its a
        //  repetition of a single element, so we can do a simple content
        //  model for that.
        //
        if (specNode->getFirst()->getType() == ContentSpecNode::Leaf)
        {
            return new SimpleContentModel
            (
                specNode->getFirst()->getElemId()
                , XMLElementDecl::fgInvalidElemId
                , specNode->getType()
            );
        }
    }
     else
    {
        ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);
    }

    // Its not any simple type of content, so create a DFA based content model
    return new DFAContentModel(*this);
}

void DTDElementDecl::faultInAttDefList() const
{
    // Use a hash modulus of 29 and tell it owns its elements
    ((DTDElementDecl*)this)->fAttDefs = new RefHashTableOf<DTDAttDef>(29, true);
}
<commit_msg>Error checking for null content spec.  By Alberto Massari.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/XMLString.hpp>
#include <util/XMLUniDefs.hpp>
#include <util/XMLUni.hpp>
#include <framework/XMLBuffer.hpp>
#include <validators/common/DFAContentModel.hpp>
#include <validators/common/ContentSpecNode.hpp>
#include <validators/common/MixedContentModel.hpp>
#include <validators/common/SimpleContentModel.hpp>
#include <validators/DTD/DTDAttDefList.hpp>
#include <validators/DTD/DTDElementDecl.hpp>

// ---------------------------------------------------------------------------
//  DTDElementDecl: Destructor is out of line to prevent having to expose
//  the ContentSpecNode header.
// ---------------------------------------------------------------------------
DTDElementDecl::~DTDElementDecl()
{
    delete fAttDefs;
    delete fAttList;
    delete fContentSpec;
    delete [] fBaseName;
    delete [] fQName;
}

// ---------------------------------------------------------------------------
//  The virtual element decl interface
// ---------------------------------------------------------------------------
XMLAttDef* DTDElementDecl::findAttr(const   XMLCh* const    qName
                                    , const unsigned int    uriId
                                    , const XMLCh* const    baseName
                                    , const XMLCh* const    prefix
                                    , const LookupOpts      options
                                    ,       bool&           wasAdded) const
{
    DTDAttDef* retVal = 0;

    // If no att list faulted in yet, then it cannot exist
    if (fAttDefs)
        retVal = fAttDefs->get(qName);

    // Fault it in if not found and ask to add it
    if (!retVal && (options == XMLElementDecl::AddIfNotFound))
    {
        // Fault in the list itself if not already
        if (!fAttDefs)
            faultInAttDefList();

        // And add a default attribute for this name
        retVal = new DTDAttDef(qName);
        retVal->setElemId(getId());
        fAttDefs->put((void*)retVal->getFullName(), retVal);

        wasAdded = true;
    }
     else
    {
        wasAdded = false;
    }
    return retVal;
}

XMLAttDefList& DTDElementDecl::getAttDefList() const
{
    if (!fAttList)
    {
        // If the att def list is not made yet, then fault it in too
        if (!fAttDefs)
            faultInAttDefList();

        ((DTDElementDecl*)this)->fAttList = new DTDAttDefList(fAttDefs);
    }

    // Reset it before we return it
    fAttList->Reset();
    return *fAttList;
}

const XMLCh* DTDElementDecl::getBaseName() const
{
    //
    //  If the base name nas not been extraced, then do it now. Since we are
    //  faulting it in from a const method, we have to cast off the constness.
    //
    if (!fBaseName)
    {
        //
        //  Search for the first colon in the name. Note that, if its not
        //  found, then it will be -1, which will still make the replicate
        //  logic work correctly.
        //
        int colonPos = XMLString::indexOf(fQName, chColon);
        ((DTDElementDecl*)this)->fBaseName = XMLString::replicate(&fQName[colonPos + 1]);
    }

    // Just return our QName
    return fBaseName;
}

XMLCh* DTDElementDecl::getBaseName()
{
    //
    //  If the base name nas not been extraced, then do it now. Since we are
    //  faulting it in from a const method, we have to cast off the constness.
    //
    if (!fBaseName)
    {
        //
        //  Search for the first colon in the name. Note that, if its not
        //  found, then it will be -1, which will still make the replicate
        //  logic work correctly.
        //
        int colonPos = XMLString::indexOf(fQName, chColon);
        ((DTDElementDecl*)this)->fBaseName = XMLString::replicate(&fQName[colonPos + 1]);
    }

    // Just return our QName
    return fBaseName;
}

XMLElementDecl::CharDataOpts DTDElementDecl::getCharDataOpts() const
{
    XMLElementDecl::CharDataOpts retVal;
    switch(fModelType)
    {
        case Children :
            retVal = XMLElementDecl::SpacesOk;
            break;

        case Empty :
            retVal = XMLElementDecl::NoCharData;
            break;

        default :
            retVal = XMLElementDecl::AllCharData;
            break;
    }
    return retVal;
}

bool DTDElementDecl::hasAttDefs() const
{
    // If the collection hasn't been faulted in, then no att defs
    if (!fAttDefs)
        return false;

    return !fAttDefs->isEmpty();
}

bool DTDElementDecl::resetDefs()
{
    // If the collection hasn't been faulted in, then no att defs
    if (!fAttDefs)
        return false;

    //
    //  Ok, run through them and clear the 'provided' flag on each of them.
    //  This lets the scanner use them to track which has been provided and
    //  which have not.
    //
    RefHashTableOfEnumerator<DTDAttDef> enumDefs(fAttDefs);
    while (enumDefs.hasMoreElements())
        enumDefs.nextElement().setProvided(false);
    return true;
}

void
DTDElementDecl::setContentSpec(ContentSpecNode* toAdopt)
{
    delete fContentSpec;
    fContentSpec = toAdopt;
}

// ---------------------------------------------------------------------------
//  DTDElementDecl: Getter methods
// ---------------------------------------------------------------------------
const DTDAttDef* DTDElementDecl::getAttDef(const XMLCh* const attName) const
{
    // If no list, then return a null
    if (!fAttDefs)
        return 0;

    return fAttDefs->get(attName);
}

DTDAttDef* DTDElementDecl::getAttDef(const XMLCh* const attName)
{
    // If no list, then return a null
    if (!fAttDefs)
        return 0;

    return fAttDefs->get(attName);
}

// ---------------------------------------------------------------------------
//  DTDElementDecl: Implementation of the protected virtual interface
// ---------------------------------------------------------------------------
void DTDElementDecl::addAttDef(DTDAttDef* const toAdd)
{
    // Fault in the att list if required
    if (!fAttDefs)
            faultInAttDefList();

    // Tell this guy the element id of its parent (us)
    toAdd->setElemId(getId());

    fAttDefs->put((void*)(toAdd->getFullName()), toAdd);
}

// ---------------------------------------------------------------------------
//  DTDElementDecl: Implementation of the protected virtual interface
// ---------------------------------------------------------------------------
XMLCh*
DTDElementDecl::formatContentModel(const Grammar& grammar) const
{
    XMLCh* newValue = 0;
    if (fModelType == Any)
    {
        newValue = XMLString::replicate(XMLUni::fgAnyString);
    }
     else if (fModelType == Empty)
    {
        newValue = XMLString::replicate(XMLUni::fgEmptyString);
    }
     else
    {
        //
        //  Use a temp XML buffer to format into. Content models could be
        //  pretty long, but very few will be longer than one K. The buffer
        //  will expand to handle the more pathological ones.
        //
        XMLBuffer bufFmt;
        fContentSpec->formatSpec(grammar, bufFmt);
        newValue = XMLString::replicate(bufFmt.getRawBuffer());
    }
    return newValue;
}

XMLContentModel* DTDElementDecl::makeContentModel(const Grammar* grammar) const
{
    XMLContentModel* cmRet = 0;
    if (fModelType == Mixed)
    {
        //
        //  Just create a mixel content model object. This type of
        //  content model is optimized for mixed content validation.
        //
        cmRet = new MixedContentModel(*this);
    }
     else if (fModelType == Children)
    {
        //
        //  This method will create an optimal model for the complexity
        //  of the element's defined model. If its simple, it will create
        //  a SimpleContentModel object. If its a simple list, it will
        //  create a SimpleListContentModel object. If its complex, it
        //  will create a DFAContentModel object.
        //
        cmRet = createChildModel(grammar);
    }
     else
    {
        ThrowXML(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren);
    }
    return cmRet;
}

// ---------------------------------------------------------------------------
//  DTDElementDecl: Private helper methods
// ---------------------------------------------------------------------------
XMLContentModel* DTDElementDecl::createChildModel(const Grammar* grammar) const
{
    // Get the content spec node of the element
    const ContentSpecNode* specNode = getContentSpec();

    if(!specNode)
        ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);

    //
    //  Do a sanity check that the node is does not have a PCDATA id. Since,
    //  if it was, it should have already gotten taken by the Mixed model.
    //
    if (specNode->getElemId() == XMLElementDecl::fgPCDataElemId)
        ThrowXML(RuntimeException, XMLExcepts::CM_NoPCDATAHere);

    //
    //  According to the type of node, we will create the correct type of
    //  content model.
    //
    if (specNode->getType() == ContentSpecNode::Leaf)
    {
        // Create a simple content model
        return new SimpleContentModel
        (
            specNode->getElemId()
            , XMLElementDecl::fgInvalidElemId
            , ContentSpecNode::Leaf
        );
    }
     else if ((specNode->getType() == ContentSpecNode::Choice)
          ||  (specNode->getType() == ContentSpecNode::Sequence))
    {
        //
        //  Lets see if both of the children are leafs. If so, then it has to
        //  be a simple content model
        //
        if ((specNode->getFirst()->getType() == ContentSpecNode::Leaf)
        &&  (specNode->getSecond()->getType() == ContentSpecNode::Leaf))
        {
            return new SimpleContentModel
            (
                specNode->getFirst()->getElemId()
                , specNode->getSecond()->getElemId()
                , specNode->getType()
            );
        }
    }
     else if ((specNode->getType() == ContentSpecNode::OneOrMore)
          ||  (specNode->getType() == ContentSpecNode::ZeroOrMore)
          ||  (specNode->getType() == ContentSpecNode::ZeroOrOne))
    {
        //
        //  Its a repetition, so see if its one child is a leaf. If so its a
        //  repetition of a single element, so we can do a simple content
        //  model for that.
        //
        if (specNode->getFirst()->getType() == ContentSpecNode::Leaf)
        {
            return new SimpleContentModel
            (
                specNode->getFirst()->getElemId()
                , XMLElementDecl::fgInvalidElemId
                , specNode->getType()
            );
        }
    }
     else
    {
        ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);
    }

    // Its not any simple type of content, so create a DFA based content model
    return new DFAContentModel(*this);
}

void DTDElementDecl::faultInAttDefList() const
{
    // Use a hash modulus of 29 and tell it owns its elements
    ((DTDElementDecl*)this)->fAttDefs = new RefHashTableOf<DTDAttDef>(29, true);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "bitcoinrpc.h"

using namespace json_spirit;
using namespace std;

extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry);
extern enum Checkpoints::CPMode CheckpointsMode;

double GetDifficulty(const CBlockIndex* blockindex)
{
    // Floating point number that is a multiple of the minimum difficulty,
    // minimum difficulty = 1.0.
    if (blockindex == NULL)
    {
        if (pindexBest == NULL)
            return 1.0;
        else
            blockindex = GetLastBlockIndex(pindexBest, false);
    }

    int nShift = (blockindex->nBits >> 24) & 0xff;

    double dDiff =
        (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);

    while (nShift < 29)
    {
        dDiff *= 256.0;
        nShift++;
    }
    while (nShift > 29)
    {
        dDiff /= 256.0;
        nShift--;
    }

    return dDiff;
}

double GetPoWMHashPS()
{
    if (pindexBest->nHeight >= LAST_POW_BLOCK)
        return 0;

    int nPoWInterval = 72;
    int64_t nTargetSpacingWorkMin = 30, nTargetSpacingWork = 30;

    CBlockIndex* pindex = pindexGenesisBlock;
    CBlockIndex* pindexPrevWork = pindexGenesisBlock;

    while (pindex)
    {
        if (pindex->IsProofOfWork())
        {
            int64_t nActualSpacingWork = pindex->GetBlockTime() - pindexPrevWork->GetBlockTime();
            nTargetSpacingWork = ((nPoWInterval - 1) * nTargetSpacingWork + nActualSpacingWork + nActualSpacingWork) / (nPoWInterval + 1);
            nTargetSpacingWork = max(nTargetSpacingWork, nTargetSpacingWorkMin);
            pindexPrevWork = pindex;
        }

        pindex = pindex->pnext;
    }

    return GetDifficulty() * 4294.967296 / nTargetSpacingWork;
}

double GetPoSKernelPS()
{
    int nPoSInterval = 72;
    double dStakeKernelsTriedAvg = 0;
    int nStakesHandled = 0, nStakesTime = 0;

    CBlockIndex* pindex = pindexBest;;
    CBlockIndex* pindexPrevStake = NULL;

    while (pindex && nStakesHandled < nPoSInterval)
    {
        if (pindex->IsProofOfStake())
        {
            dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0;
            nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0;
            pindexPrevStake = pindex;
            nStakesHandled++;
        }

        pindex = pindex->pprev;
    }

    return nStakesTime ? dStakeKernelsTriedAvg / nStakesTime : 0;
}

Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail)
{
    Object result;
    result.push_back(Pair("hash", block.GetHash().GetHex()));
    CMerkleTx txGen(block.vtx[0]);
    txGen.SetMerkleBranch(&block);
    result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain()));
    result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
    result.push_back(Pair("height", blockindex->nHeight));
    result.push_back(Pair("version", block.nVersion));
    result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
    result.push_back(Pair("mint", ValueFromAmount(blockindex->nMint)));
    result.push_back(Pair("time", (int64_t)block.GetBlockTime()));
    result.push_back(Pair("nonce", (uint64_t)block.nNonce));
    result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
    result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
    result.push_back(Pair("blocktrust", leftTrim(blockindex->GetBlockTrust().GetHex(), '0')));
    result.push_back(Pair("chaintrust", leftTrim(blockindex->nChainTrust.GetHex(), '0')));
    if (blockindex->pprev)
        result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
    if (blockindex->pnext)
        result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex()));

    result.push_back(Pair("flags", strprintf("%s%s", blockindex->IsProofOfStake()? "proof-of-stake" : "proof-of-work", blockindex->GeneratedStakeModifier()? " stake-modifier": "")));
    result.push_back(Pair("proofhash", blockindex->hashProof.GetHex()));
    result.push_back(Pair("entropybit", (int)blockindex->GetStakeEntropyBit()));
    result.push_back(Pair("modifier", strprintf("%016"PRIx64, blockindex->nStakeModifier)));
    result.push_back(Pair("modifierchecksum", strprintf("%08x", blockindex->nStakeModifierChecksum)));
    Array txinfo;
    BOOST_FOREACH (const CTransaction& tx, block.vtx)
    {
        if (fPrintTransactionDetail)
        {
            Object entry;

            entry.push_back(Pair("txid", tx.GetHash().GetHex()));
            TxToJSON(tx, 0, entry);

            txinfo.push_back(entry);
        }
        else
            txinfo.push_back(tx.GetHash().GetHex());
    }

    result.push_back(Pair("tx", txinfo));

    if (block.IsProofOfStake())
        result.push_back(Pair("signature", HexStr(block.vchBlockSig.begin(), block.vchBlockSig.end())));

    return result;
}

Value getbestblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getbestblockhash\n"
            "Returns the hash of the best block in the longest block chain.");

    return hashBestChain.GetHex();
}

Value getblockcount(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getblockcount\n"
            "Returns the number of blocks in the longest block chain.");

    return nBestHeight;
}

Value getdifficulty(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getdifficulty\n"
            "Returns the difficulty as a multiple of the minimum difficulty.");

    Object obj;
    obj.push_back(Pair("proof-of-work",        GetDifficulty()));
    obj.push_back(Pair("proof-of-stake",       GetDifficulty(GetLastBlockIndex(pindexBest, true))));
    obj.push_back(Pair("search-interval",      (int)nLastCoinStakeSearchInterval));
    return obj;
}

Value settxfee(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 1 || AmountFromValue(params[0]) < MIN_TX_FEE)
        throw runtime_error(
            "settxfee <amount>\n"
            "<amount> is a real and is rounded to the nearest 0.01");

    nTransactionFee = AmountFromValue(params[0]);
    nTransactionFee = (nTransactionFee / CENT) * CENT;  // round to cent

    return true;
}

Value getrawmempool(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getrawmempool\n"
            "Returns all transaction ids in memory pool.");

    vector<uint256> vtxid;
    mempool.queryHashes(vtxid);

    Array a;
    BOOST_FOREACH(const uint256& hash, vtxid)
        a.push_back(hash.ToString());

    return a;
}

Value getblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "getblockhash <index>\n"
            "Returns hash of block in best-block-chain at <index>.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlockIndex* pblockindex = FindBlockByHeight(nHeight);
    return pblockindex->phashBlock->GetHex();
}

Value getblock(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw runtime_error(
            "getblock <hash> [txinfo]\n"
            "txinfo optional to print more detailed tx info\n"
            "Returns details of a block with given block-hash.");

    std::string strHash = params[0].get_str();
    uint256 hash(strHash);

    if (mapBlockIndex.count(hash) == 0)
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex, true);

    return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
}

Value getblockbynumber(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw runtime_error(
            "getblock <hash> \n"
            "Returns details of a block with given block-hash.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
    while (pblockindex->nHeight > nHeight)
        pblockindex = pblockindex->pprev;

    uint256 hash = *pblockindex->phashBlock;

    pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex, true);

    return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
}

// ppcoin: get information of sync-checkpoint
Value getcheckpoint(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getcheckpoint\n"
            "Show info of synchronized checkpoint.\n");

    Object result;
    CBlockIndex* pindexCheckpoint;

    result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str()));
    pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint];
    result.push_back(Pair("height", pindexCheckpoint->nHeight));
    result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str()));

    // Check that the block satisfies synchronized checkpoint
    if (CheckpointsMode == Checkpoints::STRICT)
        result.push_back(Pair("policy", "strict"));

    if (CheckpointsMode == Checkpoints::ADVISORY)
        result.push_back(Pair("policy", "advisory"));

    if (CheckpointsMode == Checkpoints::PERMISSIVE)
        result.push_back(Pair("policy", "permissive"));

    if (mapArgs.count("-checkpointkey"))
        result.push_back(Pair("checkpointmaster", true));

    return result;
}
<commit_msg>rpc: Compute number of confirmations of a block from block height<commit_after>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "bitcoinrpc.h"

using namespace json_spirit;
using namespace std;

extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry);
extern enum Checkpoints::CPMode CheckpointsMode;

double GetDifficulty(const CBlockIndex* blockindex)
{
    // Floating point number that is a multiple of the minimum difficulty,
    // minimum difficulty = 1.0.
    if (blockindex == NULL)
    {
        if (pindexBest == NULL)
            return 1.0;
        else
            blockindex = GetLastBlockIndex(pindexBest, false);
    }

    int nShift = (blockindex->nBits >> 24) & 0xff;

    double dDiff =
        (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);

    while (nShift < 29)
    {
        dDiff *= 256.0;
        nShift++;
    }
    while (nShift > 29)
    {
        dDiff /= 256.0;
        nShift--;
    }

    return dDiff;
}

double GetPoWMHashPS()
{
    if (pindexBest->nHeight >= LAST_POW_BLOCK)
        return 0;

    int nPoWInterval = 72;
    int64_t nTargetSpacingWorkMin = 30, nTargetSpacingWork = 30;

    CBlockIndex* pindex = pindexGenesisBlock;
    CBlockIndex* pindexPrevWork = pindexGenesisBlock;

    while (pindex)
    {
        if (pindex->IsProofOfWork())
        {
            int64_t nActualSpacingWork = pindex->GetBlockTime() - pindexPrevWork->GetBlockTime();
            nTargetSpacingWork = ((nPoWInterval - 1) * nTargetSpacingWork + nActualSpacingWork + nActualSpacingWork) / (nPoWInterval + 1);
            nTargetSpacingWork = max(nTargetSpacingWork, nTargetSpacingWorkMin);
            pindexPrevWork = pindex;
        }

        pindex = pindex->pnext;
    }

    return GetDifficulty() * 4294.967296 / nTargetSpacingWork;
}

double GetPoSKernelPS()
{
    int nPoSInterval = 72;
    double dStakeKernelsTriedAvg = 0;
    int nStakesHandled = 0, nStakesTime = 0;

    CBlockIndex* pindex = pindexBest;;
    CBlockIndex* pindexPrevStake = NULL;

    while (pindex && nStakesHandled < nPoSInterval)
    {
        if (pindex->IsProofOfStake())
        {
            dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0;
            nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0;
            pindexPrevStake = pindex;
            nStakesHandled++;
        }

        pindex = pindex->pprev;
    }

    return nStakesTime ? dStakeKernelsTriedAvg / nStakesTime : 0;
}

Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail)
{
    Object result;
    result.push_back(Pair("hash", block.GetHash().GetHex()));
    int confirmations = -1;
    // Only report confirmations if the block is on the main chain
    if (blockindex->IsInMainChain())
        confirmations = nBestHeight - blockindex->nHeight + 1;
    result.push_back(Pair("confirmations", confirmations));
    result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
    result.push_back(Pair("height", blockindex->nHeight));
    result.push_back(Pair("version", block.nVersion));
    result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
    result.push_back(Pair("mint", ValueFromAmount(blockindex->nMint)));
    result.push_back(Pair("time", (int64_t)block.GetBlockTime()));
    result.push_back(Pair("nonce", (uint64_t)block.nNonce));
    result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
    result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
    result.push_back(Pair("blocktrust", leftTrim(blockindex->GetBlockTrust().GetHex(), '0')));
    result.push_back(Pair("chaintrust", leftTrim(blockindex->nChainTrust.GetHex(), '0')));
    if (blockindex->pprev)
        result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
    if (blockindex->pnext)
        result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex()));

    result.push_back(Pair("flags", strprintf("%s%s", blockindex->IsProofOfStake()? "proof-of-stake" : "proof-of-work", blockindex->GeneratedStakeModifier()? " stake-modifier": "")));
    result.push_back(Pair("proofhash", blockindex->hashProof.GetHex()));
    result.push_back(Pair("entropybit", (int)blockindex->GetStakeEntropyBit()));
    result.push_back(Pair("modifier", strprintf("%016"PRIx64, blockindex->nStakeModifier)));
    result.push_back(Pair("modifierchecksum", strprintf("%08x", blockindex->nStakeModifierChecksum)));
    Array txinfo;
    BOOST_FOREACH (const CTransaction& tx, block.vtx)
    {
        if (fPrintTransactionDetail)
        {
            Object entry;

            entry.push_back(Pair("txid", tx.GetHash().GetHex()));
            TxToJSON(tx, 0, entry);

            txinfo.push_back(entry);
        }
        else
            txinfo.push_back(tx.GetHash().GetHex());
    }

    result.push_back(Pair("tx", txinfo));

    if (block.IsProofOfStake())
        result.push_back(Pair("signature", HexStr(block.vchBlockSig.begin(), block.vchBlockSig.end())));

    return result;
}

Value getbestblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getbestblockhash\n"
            "Returns the hash of the best block in the longest block chain.");

    return hashBestChain.GetHex();
}

Value getblockcount(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getblockcount\n"
            "Returns the number of blocks in the longest block chain.");

    return nBestHeight;
}

Value getdifficulty(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getdifficulty\n"
            "Returns the difficulty as a multiple of the minimum difficulty.");

    Object obj;
    obj.push_back(Pair("proof-of-work",        GetDifficulty()));
    obj.push_back(Pair("proof-of-stake",       GetDifficulty(GetLastBlockIndex(pindexBest, true))));
    obj.push_back(Pair("search-interval",      (int)nLastCoinStakeSearchInterval));
    return obj;
}

Value settxfee(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 1 || AmountFromValue(params[0]) < MIN_TX_FEE)
        throw runtime_error(
            "settxfee <amount>\n"
            "<amount> is a real and is rounded to the nearest 0.01");

    nTransactionFee = AmountFromValue(params[0]);
    nTransactionFee = (nTransactionFee / CENT) * CENT;  // round to cent

    return true;
}

Value getrawmempool(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getrawmempool\n"
            "Returns all transaction ids in memory pool.");

    vector<uint256> vtxid;
    mempool.queryHashes(vtxid);

    Array a;
    BOOST_FOREACH(const uint256& hash, vtxid)
        a.push_back(hash.ToString());

    return a;
}

Value getblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "getblockhash <index>\n"
            "Returns hash of block in best-block-chain at <index>.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlockIndex* pblockindex = FindBlockByHeight(nHeight);
    return pblockindex->phashBlock->GetHex();
}

Value getblock(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw runtime_error(
            "getblock <hash> [txinfo]\n"
            "txinfo optional to print more detailed tx info\n"
            "Returns details of a block with given block-hash.");

    std::string strHash = params[0].get_str();
    uint256 hash(strHash);

    if (mapBlockIndex.count(hash) == 0)
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex, true);

    return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
}

Value getblockbynumber(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw runtime_error(
            "getblock <hash> \n"
            "Returns details of a block with given block-hash.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
    while (pblockindex->nHeight > nHeight)
        pblockindex = pblockindex->pprev;

    uint256 hash = *pblockindex->phashBlock;

    pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex, true);

    return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
}

// ppcoin: get information of sync-checkpoint
Value getcheckpoint(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getcheckpoint\n"
            "Show info of synchronized checkpoint.\n");

    Object result;
    CBlockIndex* pindexCheckpoint;

    result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str()));
    pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint];
    result.push_back(Pair("height", pindexCheckpoint->nHeight));
    result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str()));

    // Check that the block satisfies synchronized checkpoint
    if (CheckpointsMode == Checkpoints::STRICT)
        result.push_back(Pair("policy", "strict"));

    if (CheckpointsMode == Checkpoints::ADVISORY)
        result.push_back(Pair("policy", "advisory"));

    if (CheckpointsMode == Checkpoints::PERMISSIVE)
        result.push_back(Pair("policy", "permissive"));

    if (mapArgs.count("-checkpointkey"))
        result.push_back(Pair("checkpointmaster", true));

    return result;
}
<|endoftext|>