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

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// ALICE Reconstruction parameterization:                                    //
//                                                                           //
//                                                                           //
// Base Class for Detector reconstruction parameters                         //
// Revision: cvetan.cheshkov@cern.ch 12/06/2008                              //
// Its structure has been revised and it is interfaced to AliEventInfo.      //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "TClass.h"
#include "TObjArray.h"
#include "TMath.h"
#include "THashTable.h"
#include "AliDetectorRecoParam.h"

#include "AliLog.h"
#include "AliRecoParam.h"
#include "AliRunInfo.h"
#include "AliEventInfo.h"
#include "AliLog.h"

ClassImp(AliRecoParam)

TString AliRecoParam::fkgEventSpecieName[] = {"Default", "LowMultiplicity", "HighMultiplicity", "Cosmic", "Calib", "Unknown"} ;

AliRecoParam::AliRecoParam():
  TObject(),
  fEventSpecie(kDefault)
{
  // Default constructor
  // ...
  for(Int_t iDet = 0; iDet < kNDetectors; iDet++)
    fDetRecoParams[iDet] = NULL;
  for(Int_t iSpecie = 0; iSpecie < kNSpecies; iSpecie++) {
    for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
      fDetRecoParamsIndex[iSpecie][iDet] = -1;
    }
  }
}

AliRecoParam::AliRecoParam(const AliRecoParam& par) :
  TObject(),
  fEventSpecie(par.fEventSpecie)
{
  // copy constructor
  for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
    if (par.fDetRecoParams[iDet])
      fDetRecoParams[iDet] = (TObjArray*)(par.fDetRecoParams[iDet]->Clone());
    else
      fDetRecoParams[iDet] = NULL;
  }
  for(Int_t iSpecie = 0; iSpecie < kNSpecies; iSpecie++) {
    for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
      fDetRecoParamsIndex[iSpecie][iDet] = par.fDetRecoParamsIndex[iSpecie][iDet];
    }
  }
}

//_____________________________________________________________________________
AliRecoParam& AliRecoParam::operator = (const AliRecoParam& par)
{
  // assignment operator

  if(&par == this) return *this;

  this->~AliRecoParam();
  new(this) AliRecoParam(par);
  return *this;
}

AliRecoParam::~AliRecoParam(){
  // Destructor
  // ...
  // Delete the array with the reco-param objects
  for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
    if (fDetRecoParams[iDet]){
      fDetRecoParams[iDet]->Delete();
      delete fDetRecoParams[iDet];
    }
  }
}

Int_t AliRecoParam::AConvert(EventSpecie_t es)
{
  //Converts EventSpecie_t  into int
  Int_t rv = -1 ;
  switch (es) {
    case kDefault:
      rv = 0 ;
      break;
    case kLowMult:
      rv = 1 ;
      break;
    case kHighMult:
      rv = 2 ;
      break;
    case kCosmic:
      rv = 3 ;
      break;
    case kCalib:
      rv = 4 ;
      break;
    default:
      break;
  }

  if (rv < 0)
    AliFatalClass(Form("Wrong event specie conversion %d", es)) ;

  return rv ;
}

AliRecoParam::EventSpecie_t AliRecoParam::Convert(Int_t ies)
{
  //Converts int into EventSpecie_t
  AliRecoParam::EventSpecie_t es = kDefault ;
  if ( ies >> 1)
    es = kLowMult ;
  if ( ies >> 2)
    es = kHighMult ;
  if ( ies >> 3)
    es = kCosmic ;
  if ( ies >> 4)
    es = kCalib ;

  return es ;
}

AliRecoParam::EventSpecie_t AliRecoParam::ConvertIndex(Int_t index)
{
  //Converts index of lists into eventspecie
  EventSpecie_t es = kDefault ;
  switch (index) {
    case 0:
      es = kDefault ;
      break;
    case 1:
      es = kLowMult ;
      break;
    case 2:
      es = kHighMult ;
      break;
    case 3:
      es = kCosmic ;
      break;
    case 4:
      es = kCalib ;
      break;
    default:
      break;
  }
  return es ;
}

void  AliRecoParam::Print(Option_t *option) const {
  //
  // Print reconstruction setup
  //
  for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
    if (fDetRecoParams[iDet]){
      printf("AliDetectorRecoParam objects for detector %d:\n",iDet);
      Int_t nparam = fDetRecoParams[iDet]->GetEntriesFast();
      for (Int_t iparam=0; iparam<nparam; iparam++){
	AliDetectorRecoParam * param = (AliDetectorRecoParam *)fDetRecoParams[iDet]->At(iparam);
	if (!param) continue;
	param->Print(option);
      }
    }
    else {
      printf("No AliDetectorRecoParam objects specified for detector %d\n",iDet);
    }
  }
}

void AliRecoParam::SetEventSpecie(const AliRunInfo *runInfo, const AliEventInfo &evInfo,
				  const THashTable *cosmicTriggersList)
{
  // Implemented according to the discussions
  // and meetings with physics and trigger coordination

  fEventSpecie = kDefault;

  if (strcmp(runInfo->GetRunType(),"PHYSICS")) {
    // Not a physics run, the event specie is set to kCalib
    fEventSpecie = kCalib;
    return;
  }

  // Special DAQ events considered as calibration events
  if (evInfo.GetEventType() != 7) {
    // START_OF_*, END_OF_*, CALIBRATION etc events
    fEventSpecie = kCalib;
    return;
  }

    if ((strcmp(runInfo->GetLHCState(),"STABLE_BEAMS") == 0) &&
	((strcmp(runInfo->GetBeamType(),"A-A") == 0) ||
	(strcmp(runInfo->GetBeamType(),"A-") == 0) ||
	(strcmp(runInfo->GetBeamType(),"-A") == 0))) {
      // Heavy ion run (any beam that is not pp, the event specie is set to kHighMult
      fEventSpecie = kHighMult;
    }
    else if ((strcmp(runInfo->GetLHCState(),"STABLE_BEAMS") == 0) &&
	     ((strcmp(runInfo->GetBeamType(),"p-p") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"p-") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"-p") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"P-P") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"P-") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"-P") == 0))) {
      // Proton run, the event specie is set to kLowMult
      fEventSpecie = kLowMult;
    }
    else if (strcmp(runInfo->GetBeamType(),"-") == 0) {
      // No beams, we assume cosmic data
      fEventSpecie = kCosmic;
    }

    // Now we look into the trigger type in order to decide
    // on the remaining cases (cosmic event within LHC run,
    // calibration, for example TPC laser, triggers within physics run
    TString triggerClasses = evInfo.GetTriggerClasses();
    TObjArray* trClassArray = triggerClasses.Tokenize(" ");
    Int_t nTrClasses = trClassArray->GetEntriesFast();
    Bool_t cosmicTrigger = kFALSE,
      calibTrigger = kFALSE,
      otherTrigger = kFALSE;
    for( Int_t i=0; i<nTrClasses; ++i ) {
      TString trClass = ((TObjString*)trClassArray->At(i))->String();

      if (trClass.BeginsWith("C0L")) {
	// Calibration triggers always start with C0L
	calibTrigger = kTRUE;
	continue;
      }

      if (cosmicTriggersList) {
	if (cosmicTriggersList->FindObject(trClass.Data())) {
	  // Cosmic trigger accorind to the table
	  // provided in OCDB
	  cosmicTrigger = kTRUE;
	  AliDebug(1,Form("Trigger %s identified as cosmic according to the list defined in OCDB.",
			  trClass.Data()));
	  continue;
	}
      }
      else {
	AliDebug(1,"Cosmic trigger list is not provided, cosmic event specie is effectively disabled!");
      }

      otherTrigger = kTRUE;
    }
    delete trClassArray;

    if (calibTrigger) {
      fEventSpecie = kCalib;
      return;
    }
    if (cosmicTrigger && !otherTrigger) {
      fEventSpecie = kCosmic;
      return;
    }

    // Here we have to add if we have other cases
    // and also HLT info if any...
}

const AliDetectorRecoParam *AliRecoParam::GetDetRecoParam(Int_t iDet) const
{
  // Return AliDetectorRecoParam object for a given detector
  // according to the event specie provided as an argument
  if ( iDet >= kNDetectors) return NULL;
  if (!fDetRecoParams[iDet]) return NULL;
  if (fDetRecoParams[iDet]->GetEntries() == 0) return NULL;

  for(Int_t iBit = 0; iBit < kNSpecies; iBit++) {
    if (fEventSpecie & (1 << iBit)) {
      if (fDetRecoParamsIndex[iBit][iDet] >= 0)
	return (AliDetectorRecoParam *)fDetRecoParams[iDet]->At(fDetRecoParamsIndex[iBit][iDet]);
      else if (fDetRecoParamsIndex[0][iDet] >= 0)
	return (AliDetectorRecoParam *)fDetRecoParams[iDet]->At(fDetRecoParamsIndex[0][iDet]);
      else {
	AliError(Form("no RecoParam set for detector %d", iDet));
	return NULL;
      }
    }
  }

  // Default one
  AliError(Form("Invalid event specie: %d!",fEventSpecie));
  if (fDetRecoParamsIndex[0][iDet] >= 0)
    return (AliDetectorRecoParam *)fDetRecoParams[iDet]->At(fDetRecoParamsIndex[0][iDet]);

  AliError(Form("no RecoParam set for detector %d", iDet));
  return NULL;
}

void  AliRecoParam::AddDetRecoParam(Int_t iDet, AliDetectorRecoParam* param)
{
  // Add an instance of reco params object into
  // the fDetRecoParams for detector iDet
  // Updates the fDetRecoParams index
  if (!fDetRecoParams[iDet]) fDetRecoParams[iDet] = new TObjArray;
  fDetRecoParams[iDet]->AddLast(param);
  Int_t index = fDetRecoParams[iDet]->GetLast();

  // Index
  Int_t specie = param->GetEventSpecie();
  for(Int_t iBit = 0; iBit < kNSpecies; iBit++) {
    if (specie & (1 << iBit)) {
      fDetRecoParamsIndex[iBit][iDet] = index;
    }
  }
}

Bool_t AliRecoParam::AddDetRecoParamArray(Int_t iDet, TObjArray* parArray)
{
  // Add an array of reconstruction parameter objects
  // for a given detector
  // Basic check on the consistency of the array
  Bool_t defaultFound = kFALSE;
  for(Int_t i = 0; i < parArray->GetEntriesFast(); i++) {
    AliDetectorRecoParam *par = (AliDetectorRecoParam*)parArray->At(i);
    if (!par) continue;
    if (par->IsDefault()) defaultFound = kTRUE;

    Int_t specie = par->GetEventSpecie();
    for(Int_t iBit = 0; iBit < kNSpecies; iBit++) {
      if (specie & (1 << iBit)) {
	fDetRecoParamsIndex[iBit][iDet] = i;
      }
    }
 }

  fDetRecoParams[iDet] = parArray;

  return defaultFound;
}

const char*  AliRecoParam::PrintEventSpecie() const
{
  // Print the current
  // event specie
  switch (fEventSpecie) {
  case kDefault:
    return fkgEventSpecieName[0].Data() ;
    break;
  case kLowMult:
    return fkgEventSpecieName[1].Data() ;
    break;
  case kHighMult:
    return fkgEventSpecieName[2].Data() ;
    break;
  case kCosmic:
    return fkgEventSpecieName[3].Data() ;
    break;
  case kCalib:
    return fkgEventSpecieName[4].Data() ;
    break;
  default:
    return fkgEventSpecieName[5].Data() ;
    break;
  }
}

const char * AliRecoParam::GetEventSpecieName(EventSpecie_t es)
{
  switch (es) {
    case kDefault:
      return fkgEventSpecieName[0].Data() ;
      break;
    case kLowMult:
      return fkgEventSpecieName[1].Data() ;
      break;
    case kHighMult:
      return fkgEventSpecieName[2].Data() ;
      break;
    case kCosmic:
      return fkgEventSpecieName[3].Data() ;
      break;
    case kCalib:
      return fkgEventSpecieName[4].Data() ;
      break;
    default:
      return fkgEventSpecieName[5].Data() ;
      break;
  }
}

const char * AliRecoParam::GetEventSpecieName(Int_t esIndex)
{
  if ( esIndex >= 0 && esIndex < kNSpecies)
    return fkgEventSpecieName[esIndex].Data() ;
  else
    return fkgEventSpecieName[kNSpecies].Data() ;
}
<commit_msg>Allowing another syntax of the stable beams lhc state. To be ported to the releases.<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.                  *
 **************************************************************************/

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// ALICE Reconstruction parameterization:                                    //
//                                                                           //
//                                                                           //
// Base Class for Detector reconstruction parameters                         //
// Revision: cvetan.cheshkov@cern.ch 12/06/2008                              //
// Its structure has been revised and it is interfaced to AliEventInfo.      //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "TClass.h"
#include "TObjArray.h"
#include "TMath.h"
#include "THashTable.h"
#include "AliDetectorRecoParam.h"

#include "AliLog.h"
#include "AliRecoParam.h"
#include "AliRunInfo.h"
#include "AliEventInfo.h"
#include "AliLog.h"

ClassImp(AliRecoParam)

TString AliRecoParam::fkgEventSpecieName[] = {"Default", "LowMultiplicity", "HighMultiplicity", "Cosmic", "Calib", "Unknown"} ;

AliRecoParam::AliRecoParam():
  TObject(),
  fEventSpecie(kDefault)
{
  // Default constructor
  // ...
  for(Int_t iDet = 0; iDet < kNDetectors; iDet++)
    fDetRecoParams[iDet] = NULL;
  for(Int_t iSpecie = 0; iSpecie < kNSpecies; iSpecie++) {
    for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
      fDetRecoParamsIndex[iSpecie][iDet] = -1;
    }
  }
}

AliRecoParam::AliRecoParam(const AliRecoParam& par) :
  TObject(),
  fEventSpecie(par.fEventSpecie)
{
  // copy constructor
  for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
    if (par.fDetRecoParams[iDet])
      fDetRecoParams[iDet] = (TObjArray*)(par.fDetRecoParams[iDet]->Clone());
    else
      fDetRecoParams[iDet] = NULL;
  }
  for(Int_t iSpecie = 0; iSpecie < kNSpecies; iSpecie++) {
    for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
      fDetRecoParamsIndex[iSpecie][iDet] = par.fDetRecoParamsIndex[iSpecie][iDet];
    }
  }
}

//_____________________________________________________________________________
AliRecoParam& AliRecoParam::operator = (const AliRecoParam& par)
{
  // assignment operator

  if(&par == this) return *this;

  this->~AliRecoParam();
  new(this) AliRecoParam(par);
  return *this;
}

AliRecoParam::~AliRecoParam(){
  // Destructor
  // ...
  // Delete the array with the reco-param objects
  for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
    if (fDetRecoParams[iDet]){
      fDetRecoParams[iDet]->Delete();
      delete fDetRecoParams[iDet];
    }
  }
}

Int_t AliRecoParam::AConvert(EventSpecie_t es)
{
  //Converts EventSpecie_t  into int
  Int_t rv = -1 ;
  switch (es) {
    case kDefault:
      rv = 0 ;
      break;
    case kLowMult:
      rv = 1 ;
      break;
    case kHighMult:
      rv = 2 ;
      break;
    case kCosmic:
      rv = 3 ;
      break;
    case kCalib:
      rv = 4 ;
      break;
    default:
      break;
  }

  if (rv < 0)
    AliFatalClass(Form("Wrong event specie conversion %d", es)) ;

  return rv ;
}

AliRecoParam::EventSpecie_t AliRecoParam::Convert(Int_t ies)
{
  //Converts int into EventSpecie_t
  AliRecoParam::EventSpecie_t es = kDefault ;
  if ( ies >> 1)
    es = kLowMult ;
  if ( ies >> 2)
    es = kHighMult ;
  if ( ies >> 3)
    es = kCosmic ;
  if ( ies >> 4)
    es = kCalib ;

  return es ;
}

AliRecoParam::EventSpecie_t AliRecoParam::ConvertIndex(Int_t index)
{
  //Converts index of lists into eventspecie
  EventSpecie_t es = kDefault ;
  switch (index) {
    case 0:
      es = kDefault ;
      break;
    case 1:
      es = kLowMult ;
      break;
    case 2:
      es = kHighMult ;
      break;
    case 3:
      es = kCosmic ;
      break;
    case 4:
      es = kCalib ;
      break;
    default:
      break;
  }
  return es ;
}

void  AliRecoParam::Print(Option_t *option) const {
  //
  // Print reconstruction setup
  //
  for(Int_t iDet = 0; iDet < kNDetectors; iDet++) {
    if (fDetRecoParams[iDet]){
      printf("AliDetectorRecoParam objects for detector %d:\n",iDet);
      Int_t nparam = fDetRecoParams[iDet]->GetEntriesFast();
      for (Int_t iparam=0; iparam<nparam; iparam++){
	AliDetectorRecoParam * param = (AliDetectorRecoParam *)fDetRecoParams[iDet]->At(iparam);
	if (!param) continue;
	param->Print(option);
      }
    }
    else {
      printf("No AliDetectorRecoParam objects specified for detector %d\n",iDet);
    }
  }
}

void AliRecoParam::SetEventSpecie(const AliRunInfo *runInfo, const AliEventInfo &evInfo,
				  const THashTable *cosmicTriggersList)
{
  // Implemented according to the discussions
  // and meetings with physics and trigger coordination

  fEventSpecie = kDefault;

  if (strcmp(runInfo->GetRunType(),"PHYSICS")) {
    // Not a physics run, the event specie is set to kCalib
    fEventSpecie = kCalib;
    return;
  }

  // Special DAQ events considered as calibration events
  if (evInfo.GetEventType() != 7) {
    // START_OF_*, END_OF_*, CALIBRATION etc events
    fEventSpecie = kCalib;
    return;
  }

    if (((strcmp(runInfo->GetLHCState(),"STABLE_BEAMS") == 0) ||
         (strcmp(runInfo->GetLHCState(),"STABLE BEAMS") == 0)) &&
	((strcmp(runInfo->GetBeamType(),"A-A") == 0) ||
	(strcmp(runInfo->GetBeamType(),"A-") == 0) ||
	(strcmp(runInfo->GetBeamType(),"-A") == 0))) {
      // Heavy ion run (any beam that is not pp, the event specie is set to kHighMult
      fEventSpecie = kHighMult;
    }
    else if (((strcmp(runInfo->GetLHCState(),"STABLE_BEAMS") == 0) ||
	      (strcmp(runInfo->GetLHCState(),"STABLE BEAMS") == 0)) &&
	     ((strcmp(runInfo->GetBeamType(),"p-p") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"p-") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"-p") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"P-P") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"P-") == 0) ||
	      (strcmp(runInfo->GetBeamType(),"-P") == 0))) {
      // Proton run, the event specie is set to kLowMult
      fEventSpecie = kLowMult;
    }
    else if (strcmp(runInfo->GetBeamType(),"-") == 0) {
      // No beams, we assume cosmic data
      fEventSpecie = kCosmic;
    }

    // Now we look into the trigger type in order to decide
    // on the remaining cases (cosmic event within LHC run,
    // calibration, for example TPC laser, triggers within physics run
    TString triggerClasses = evInfo.GetTriggerClasses();
    TObjArray* trClassArray = triggerClasses.Tokenize(" ");
    Int_t nTrClasses = trClassArray->GetEntriesFast();
    Bool_t cosmicTrigger = kFALSE,
      calibTrigger = kFALSE,
      otherTrigger = kFALSE;
    for( Int_t i=0; i<nTrClasses; ++i ) {
      TString trClass = ((TObjString*)trClassArray->At(i))->String();

      if (trClass.BeginsWith("C0L")) {
	// Calibration triggers always start with C0L
	calibTrigger = kTRUE;
	continue;
      }

      if (cosmicTriggersList) {
	if (cosmicTriggersList->FindObject(trClass.Data())) {
	  // Cosmic trigger accorind to the table
	  // provided in OCDB
	  cosmicTrigger = kTRUE;
	  AliDebug(1,Form("Trigger %s identified as cosmic according to the list defined in OCDB.",
			  trClass.Data()));
	  continue;
	}
      }
      else {
	AliDebug(1,"Cosmic trigger list is not provided, cosmic event specie is effectively disabled!");
      }

      otherTrigger = kTRUE;
    }
    delete trClassArray;

    if (calibTrigger) {
      fEventSpecie = kCalib;
      return;
    }
    if (cosmicTrigger && !otherTrigger) {
      fEventSpecie = kCosmic;
      return;
    }

    // Here we have to add if we have other cases
    // and also HLT info if any...
}

const AliDetectorRecoParam *AliRecoParam::GetDetRecoParam(Int_t iDet) const
{
  // Return AliDetectorRecoParam object for a given detector
  // according to the event specie provided as an argument
  if ( iDet >= kNDetectors) return NULL;
  if (!fDetRecoParams[iDet]) return NULL;
  if (fDetRecoParams[iDet]->GetEntries() == 0) return NULL;

  for(Int_t iBit = 0; iBit < kNSpecies; iBit++) {
    if (fEventSpecie & (1 << iBit)) {
      if (fDetRecoParamsIndex[iBit][iDet] >= 0)
	return (AliDetectorRecoParam *)fDetRecoParams[iDet]->At(fDetRecoParamsIndex[iBit][iDet]);
      else if (fDetRecoParamsIndex[0][iDet] >= 0)
	return (AliDetectorRecoParam *)fDetRecoParams[iDet]->At(fDetRecoParamsIndex[0][iDet]);
      else {
	AliError(Form("no RecoParam set for detector %d", iDet));
	return NULL;
      }
    }
  }

  // Default one
  AliError(Form("Invalid event specie: %d!",fEventSpecie));
  if (fDetRecoParamsIndex[0][iDet] >= 0)
    return (AliDetectorRecoParam *)fDetRecoParams[iDet]->At(fDetRecoParamsIndex[0][iDet]);

  AliError(Form("no RecoParam set for detector %d", iDet));
  return NULL;
}

void  AliRecoParam::AddDetRecoParam(Int_t iDet, AliDetectorRecoParam* param)
{
  // Add an instance of reco params object into
  // the fDetRecoParams for detector iDet
  // Updates the fDetRecoParams index
  if (!fDetRecoParams[iDet]) fDetRecoParams[iDet] = new TObjArray;
  fDetRecoParams[iDet]->AddLast(param);
  Int_t index = fDetRecoParams[iDet]->GetLast();

  // Index
  Int_t specie = param->GetEventSpecie();
  for(Int_t iBit = 0; iBit < kNSpecies; iBit++) {
    if (specie & (1 << iBit)) {
      fDetRecoParamsIndex[iBit][iDet] = index;
    }
  }
}

Bool_t AliRecoParam::AddDetRecoParamArray(Int_t iDet, TObjArray* parArray)
{
  // Add an array of reconstruction parameter objects
  // for a given detector
  // Basic check on the consistency of the array
  Bool_t defaultFound = kFALSE;
  for(Int_t i = 0; i < parArray->GetEntriesFast(); i++) {
    AliDetectorRecoParam *par = (AliDetectorRecoParam*)parArray->At(i);
    if (!par) continue;
    if (par->IsDefault()) defaultFound = kTRUE;

    Int_t specie = par->GetEventSpecie();
    for(Int_t iBit = 0; iBit < kNSpecies; iBit++) {
      if (specie & (1 << iBit)) {
	fDetRecoParamsIndex[iBit][iDet] = i;
      }
    }
 }

  fDetRecoParams[iDet] = parArray;

  return defaultFound;
}

const char*  AliRecoParam::PrintEventSpecie() const
{
  // Print the current
  // event specie
  switch (fEventSpecie) {
  case kDefault:
    return fkgEventSpecieName[0].Data() ;
    break;
  case kLowMult:
    return fkgEventSpecieName[1].Data() ;
    break;
  case kHighMult:
    return fkgEventSpecieName[2].Data() ;
    break;
  case kCosmic:
    return fkgEventSpecieName[3].Data() ;
    break;
  case kCalib:
    return fkgEventSpecieName[4].Data() ;
    break;
  default:
    return fkgEventSpecieName[5].Data() ;
    break;
  }
}

const char * AliRecoParam::GetEventSpecieName(EventSpecie_t es)
{
  switch (es) {
    case kDefault:
      return fkgEventSpecieName[0].Data() ;
      break;
    case kLowMult:
      return fkgEventSpecieName[1].Data() ;
      break;
    case kHighMult:
      return fkgEventSpecieName[2].Data() ;
      break;
    case kCosmic:
      return fkgEventSpecieName[3].Data() ;
      break;
    case kCalib:
      return fkgEventSpecieName[4].Data() ;
      break;
    default:
      return fkgEventSpecieName[5].Data() ;
      break;
  }
}

const char * AliRecoParam::GetEventSpecieName(Int_t esIndex)
{
  if ( esIndex >= 0 && esIndex < kNSpecies)
    return fkgEventSpecieName[esIndex].Data() ;
  else
    return fkgEventSpecieName[kNSpecies].Data() ;
}
<|endoftext|>


<commit_before>#include "optional.h"
#include "variant.h"

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"

#include <string>
#include <vector>
#include <type_traits>

TEST_CASE("std::variant<T...> traits")
{
    typedef std::variant<bool, float> bool_float_variant;
    typedef std::variant<int, double, std::string> int_double_string_variant;

    CHECK(std::variant_size<bool_float_variant>::value == 2);
    CHECK(std::variant_size<const bool_float_variant>::value == 2);
    CHECK(std::variant_size<volatile bool_float_variant>::value == 2);
    CHECK(std::variant_size<const volatile bool_float_variant>::value == 2);

    CHECK(std::variant_size<int_double_string_variant>::value == 3);
    CHECK(std::variant_size<const int_double_string_variant>::value == 3);
    CHECK(std::variant_size<volatile int_double_string_variant>::value == 3);
    CHECK(std::variant_size<const volatile int_double_string_variant>::value == 3);

    CHECK(typeid(std::variant_alternative_t<0, std::variant<bool, float>> *) == typeid(bool *));
    CHECK(typeid(std::variant_alternative_t<1, std::variant<bool, float>> *) == typeid(float *));
    CHECK(typeid(std::variant_alternative_t<0, const std::variant<bool, float>> *) == typeid(const bool *));
    CHECK(typeid(std::variant_alternative_t<1, const std::variant<bool, float>> *) == typeid(const float *));
    CHECK(typeid(std::variant_alternative_t<0, volatile std::variant<bool, float>> *) == typeid(volatile bool *));
    CHECK(typeid(std::variant_alternative_t<1, volatile std::variant<bool, float>> *) == typeid(volatile float *));
    CHECK(typeid(std::variant_alternative_t<0, const volatile std::variant<bool, float>> *) == typeid(const volatile bool *));
    CHECK(typeid(std::variant_alternative_t<1, const volatile std::variant<bool, float>> *) == typeid(const volatile float *));

    CHECK(typeid(std::variant_alternative_t<0, std::variant<int, double, std::string>> *) == typeid(int *));
    CHECK(typeid(std::variant_alternative_t<1, std::variant<int, double, std::string>> *) == typeid(double *));
    CHECK(typeid(std::variant_alternative_t<2, std::variant<int, double, std::string>> *) == typeid(std::string *));
    CHECK(typeid(std::variant_alternative_t<0, const std::variant<int, double, std::string>> *) == typeid(const int *));
    CHECK(typeid(std::variant_alternative_t<1, const std::variant<int, double, std::string>> *) == typeid(const double *));
    CHECK(typeid(std::variant_alternative_t<2, const std::variant<int, double, std::string>> *) == typeid(const std::string *));
    CHECK(typeid(std::variant_alternative_t<0, volatile std::variant<int, double, std::string>> *) == typeid(volatile int *));
    CHECK(typeid(std::variant_alternative_t<1, volatile std::variant<int, double, std::string>> *) == typeid(volatile double *));
    CHECK(typeid(std::variant_alternative_t<2, volatile std::variant<int, double, std::string>> *) == typeid(volatile std::string *));
    CHECK(typeid(std::variant_alternative_t<0, const volatile std::variant<int, double, std::string>> *) == typeid(const volatile int *));
    CHECK(typeid(std::variant_alternative_t<1, const volatile std::variant<int, double, std::string>> *) == typeid(const volatile double *));
    CHECK(typeid(std::variant_alternative_t<2, const volatile std::variant<int, double, std::string>> *) == typeid(const volatile std::string *));
}

TEST_CASE("construct std::variant<T...>")
{
    std::variant<int, double, std::string> a;
    std::variant<int, double, std::string> b {55};
    std::variant<int, double, std::string> c {3.14};
    std::variant<int, double, std::string> d {"Hello world!"};

    CHECK(!a.valueless_by_exception());
    CHECK(!b.valueless_by_exception());
    CHECK(!c.valueless_by_exception());
    CHECK(!d.valueless_by_exception());

    CHECK(a.index() == 0);
    CHECK(b.index() == 0);
    CHECK(c.index() == 1);
    CHECK(d.index() == 2);

    CHECK(std::get<0>(a) == int{0});
    CHECK(std::get<0>(b) == int{55});
    CHECK(std::get<1>(c) == double{3.14});
    CHECK(std::get<2>(d) == std::string{"Hello world!"});

    b = d;
    CHECK(!b.valueless_by_exception());
    CHECK(b.index() == 2);
    CHECK(std::get<2>(b) == std::string{"Hello world!"});

    d = c;
    CHECK(!d.valueless_by_exception());
    CHECK(d.index() == 1);
    CHECK(std::get<1>(d) == double{3.14});
}

TEST_CASE("variant move and copy construction and assignment")
{
    typedef std::variant<int, std::vector<double>> variant_t;

    // Construct an int alternative
    variant_t a {5};
    CHECK(a.index() == 0);
    CHECK(std::get<0>(a) == 5);

    // Construct a std::vector<double> alternative
    variant_t b {std::vector<double>{1,2,3,4,5,6,7,8,9,10}};
    CHECK(b.index() == 1);
    CHECK(std::get<1>(b).size() == 10);

    // Copy construct from b, which should leave b unchanged
    variant_t c {b};
    CHECK(c.index() == 1);
    CHECK(std::get<1>(c).size() == 10);
    CHECK(b.index() == 1);
    CHECK(std::get<1>(b).size() == 10);

    // Move construct from b, which should leave b representing a moved-from std::vector<double>
    variant_t d {std::move(b)};
    CHECK(d.index() == 1);
    CHECK(std::get<1>(d).size() == 10);
    CHECK(b.index() == 1);
    CHECK(std::get<1>(b).size() == 0);

    // Now copy a into b, which should change b to represent an int
    b = a;
    CHECK(b.index() == 0);
    CHECK(std::get<0>(b) == 5);
    CHECK(a.index() == 0);
    CHECK(std::get<0>(a) == 5);

    // Now move d into a, which should change a to represent a std::vector<double> and leave d as a moved-from std::vector<double>
    a = std::move(d);
    CHECK(a.index() == 1);
    CHECK(std::get<1>(a).size() == 10);
    CHECK(d.index() == 1);
    CHECK(std::get<1>(d).size() == 0);
}

TEST_CASE("variant emplace()")
{
    // Default-construct several variants
    std::variant<int, std::vector<double>> a, b, c, d;
    CHECK(a.index() == 0);
    CHECK(std::get<0>(a) == 0);

    // Emplace the first alternative by index
    a.emplace<0>(55);
    CHECK(a.index() == 0);
    CHECK(std::get<0>(a) == 55);

    // Emplace the second alternative by index
    b.emplace<1>(std::vector<double>{1,2,3,4,5});
    CHECK(b.index() == 1);
    CHECK(std::get<1>(b).size() == 5);

    // Emplace the first alternative by type
    c.emplace<int>(72);
    CHECK(c.index() == 0);
    CHECK(std::get<0>(c) == 72);

    // Emplace the second alternative by type
    d.emplace<std::vector<double>>(std::vector<double>{3,2,1});
    CHECK(d.index() == 1);
    CHECK(std::get<1>(d).size() == 3);
}

TEST_CASE("construct null std::optional<T>")
{
    const std::optional<int> a;
    CHECK(!a);
    CHECK(!a.has_value());
    CHECK(a == std::nullopt);
    CHECK(std::nullopt == a);

    const std::optional<std::string> b {std::nullopt};
    CHECK(!b);
    CHECK(!b.has_value());
    CHECK(b == std::nullopt);
    CHECK(std::nullopt == b);
}

TEST_CASE("construct std::optional<T> with a value")
{
    const std::optional<int> a {55};
    CHECK(a);
    CHECK(a.has_value());
    CHECK(a.value() == 55);
    CHECK(a == 55);
    CHECK(55 == a);

    const std::optional<std::string> b {"Hello world!"};
    CHECK(b);
    CHECK(b.has_value());

    const std::string s {"Hello world!"};
    CHECK(b.value() == s);
    CHECK(b == s);
    CHECK(s == b);
}<commit_msg>More tests.<commit_after>#include "optional.h"
#include "variant.h"

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"

#include <string>
#include <vector>
#include <type_traits>

TEST_CASE("std::variant<T...> traits")
{
    typedef std::variant<bool, float> bool_float_variant;
    typedef std::variant<int, double, std::string> int_double_string_variant;

    CHECK(std::variant_size<bool_float_variant>::value == 2);
    CHECK(std::variant_size<const bool_float_variant>::value == 2);
    CHECK(std::variant_size<volatile bool_float_variant>::value == 2);
    CHECK(std::variant_size<const volatile bool_float_variant>::value == 2);

    CHECK(std::variant_size<int_double_string_variant>::value == 3);
    CHECK(std::variant_size<const int_double_string_variant>::value == 3);
    CHECK(std::variant_size<volatile int_double_string_variant>::value == 3);
    CHECK(std::variant_size<const volatile int_double_string_variant>::value == 3);

    CHECK(typeid(std::variant_alternative_t<0, std::variant<bool, float>> *) == typeid(bool *));
    CHECK(typeid(std::variant_alternative_t<1, std::variant<bool, float>> *) == typeid(float *));
    CHECK(typeid(std::variant_alternative_t<0, const std::variant<bool, float>> *) == typeid(const bool *));
    CHECK(typeid(std::variant_alternative_t<1, const std::variant<bool, float>> *) == typeid(const float *));
    CHECK(typeid(std::variant_alternative_t<0, volatile std::variant<bool, float>> *) == typeid(volatile bool *));
    CHECK(typeid(std::variant_alternative_t<1, volatile std::variant<bool, float>> *) == typeid(volatile float *));
    CHECK(typeid(std::variant_alternative_t<0, const volatile std::variant<bool, float>> *) == typeid(const volatile bool *));
    CHECK(typeid(std::variant_alternative_t<1, const volatile std::variant<bool, float>> *) == typeid(const volatile float *));

    CHECK(typeid(std::variant_alternative_t<0, std::variant<int, double, std::string>> *) == typeid(int *));
    CHECK(typeid(std::variant_alternative_t<1, std::variant<int, double, std::string>> *) == typeid(double *));
    CHECK(typeid(std::variant_alternative_t<2, std::variant<int, double, std::string>> *) == typeid(std::string *));
    CHECK(typeid(std::variant_alternative_t<0, const std::variant<int, double, std::string>> *) == typeid(const int *));
    CHECK(typeid(std::variant_alternative_t<1, const std::variant<int, double, std::string>> *) == typeid(const double *));
    CHECK(typeid(std::variant_alternative_t<2, const std::variant<int, double, std::string>> *) == typeid(const std::string *));
    CHECK(typeid(std::variant_alternative_t<0, volatile std::variant<int, double, std::string>> *) == typeid(volatile int *));
    CHECK(typeid(std::variant_alternative_t<1, volatile std::variant<int, double, std::string>> *) == typeid(volatile double *));
    CHECK(typeid(std::variant_alternative_t<2, volatile std::variant<int, double, std::string>> *) == typeid(volatile std::string *));
    CHECK(typeid(std::variant_alternative_t<0, const volatile std::variant<int, double, std::string>> *) == typeid(const volatile int *));
    CHECK(typeid(std::variant_alternative_t<1, const volatile std::variant<int, double, std::string>> *) == typeid(const volatile double *));
    CHECK(typeid(std::variant_alternative_t<2, const volatile std::variant<int, double, std::string>> *) == typeid(const volatile std::string *));
}

TEST_CASE("construct std::variant<T...>")
{
    std::variant<int, double, std::string> a;
    std::variant<int, double, std::string> b {55};
    std::variant<int, double, std::string> c {3.14};
    std::variant<int, double, std::string> d {"Hello world!"};

    CHECK(!a.valueless_by_exception());
    CHECK(!b.valueless_by_exception());
    CHECK(!c.valueless_by_exception());
    CHECK(!d.valueless_by_exception());

    CHECK(a.index() == 0);
    CHECK(b.index() == 0);
    CHECK(c.index() == 1);
    CHECK(d.index() == 2);

    CHECK(std::get<0>(a) == int{0});
    CHECK(std::get<0>(b) == int{55});
    CHECK(std::get<1>(c) == double{3.14});
    CHECK(std::get<2>(d) == std::string{"Hello world!"});

    b = d;
    CHECK(!b.valueless_by_exception());
    CHECK(b.index() == 2);
    CHECK(std::get<2>(b) == std::string{"Hello world!"});

    d = c;
    CHECK(!d.valueless_by_exception());
    CHECK(d.index() == 1);
    CHECK(std::get<1>(d) == double{3.14});
}

TEST_CASE("variant move and copy construction and assignment")
{
    typedef std::variant<int, std::vector<double>> variant_t;

    // Construct an int alternative
    variant_t a {5};
    CHECK(a.index() == 0);
    CHECK(std::get<0>(a) == 5);

    // Construct a std::vector<double> alternative
    variant_t b {std::vector<double>{1,2,3,4,5,6,7,8,9,10}};
    CHECK(b.index() == 1);
    CHECK(std::get<1>(b).size() == 10);

    // Copy construct from b, which should leave b unchanged
    variant_t c {b};
    CHECK(c.index() == 1);
    CHECK(std::get<1>(c).size() == 10);
    CHECK(b.index() == 1);
    CHECK(std::get<1>(b).size() == 10);

    // Move construct from b, which should leave b representing a moved-from std::vector<double>
    variant_t d {std::move(b)};
    CHECK(d.index() == 1);
    CHECK(std::get<1>(d).size() == 10);
    CHECK(b.index() == 1);
    CHECK(std::get<1>(b).size() == 0);

    // Now copy a into b, which should change b to represent an int
    b = a;
    CHECK(b.index() == 0);
    CHECK(std::get<0>(b) == 5);
    CHECK(a.index() == 0);
    CHECK(std::get<0>(a) == 5);

    // Now move d into a, which should change a to represent a std::vector<double> and leave d as a moved-from std::vector<double>
    a = std::move(d);
    CHECK(a.index() == 1);
    CHECK(std::get<1>(a).size() == 10);
    CHECK(d.index() == 1);
    CHECK(std::get<1>(d).size() == 0);
}

TEST_CASE("variant emplace()")
{
    // Default-construct several variants
    std::variant<int, std::vector<double>> a, b, c, d;
    CHECK(a.index() == 0);
    CHECK(std::get<0>(a) == 0);

    // Emplace the first alternative by index
    a.emplace<0>(55);
    CHECK(a.index() == 0);
    CHECK(std::get<0>(a) == 55);

    // Emplace the second alternative by index
    b.emplace<1>(std::vector<double>{1,2,3,4,5});
    CHECK(b.index() == 1);
    CHECK(std::get<1>(b).size() == 5);

    // Emplace the first alternative by type
    c.emplace<int>(72);
    CHECK(c.index() == 0);
    CHECK(std::get<0>(c) == 72);

    // Emplace the second alternative by type
    d.emplace<std::vector<double>>(std::vector<double>{3,2,1});
    CHECK(d.index() == 1);
    CHECK(std::get<1>(d).size() == 3);
}

TEST_CASE("visit variant")
{
    // Construct some variants
    std::variant<int, double, std::string> a {5}, b {3.14}, c {"foo"};

    // Create a visitor that prints to a stream
    std::ostringstream ss;
    const auto print = [&ss](const auto & x) { ss << x; };

    // Visit a, which should print the int alternative
    ss.str("");
    visit(print, a);
    CHECK(ss.str() == "5");

    // Visit b, which should print the double alternative
    ss.str("");
    visit(print, b);
    CHECK(ss.str() == "3.14");

    // Visit c, which should print the string alternative
    ss.str("");
    visit(print, c);
    CHECK(ss.str() == "foo");

    // Visit all three variants at once
    ss.str("");
    visit([&ss](auto x, auto y, auto z)
    {
        ss << x << ' ' << y << ' ' << z;
    }, a, b, c);
    CHECK(ss.str() == "5 3.14 foo");

    // Use a modifying visitor on all three variants
    const auto add_letter_a = [](auto & x) { x += 'A'; };
    visit(add_letter_a, a);
    visit(add_letter_a, b);
    visit(add_letter_a, c);
    CHECK(std::get<0>(a) == 5 + 'A');
    CHECK(std::get<1>(b) == 3.14 + 'A');
    CHECK(std::get<2>(c) == "fooA");
}

TEST_CASE("construct null std::optional<T>")
{
    const std::optional<int> a;
    CHECK(!a);
    CHECK(!a.has_value());
    CHECK(a == std::nullopt);
    CHECK(std::nullopt == a);

    const std::optional<std::string> b {std::nullopt};
    CHECK(!b);
    CHECK(!b.has_value());
    CHECK(b == std::nullopt);
    CHECK(std::nullopt == b);
}

TEST_CASE("construct std::optional<T> with a value")
{
    const std::optional<int> a {55};
    CHECK(a);
    CHECK(a.has_value());
    CHECK(a.value() == 55);
    CHECK(a == 55);
    CHECK(55 == a);

    const std::optional<std::string> b {"Hello world!"};
    CHECK(b);
    CHECK(b.has_value());

    const std::string s {"Hello world!"};
    CHECK(b.value() == s);
    CHECK(b == s);
    CHECK(s == b);
}<|endoftext|>


<commit_before>#include "master.hpp"

namespace factor {

factor_vm::factor_vm(THREADHANDLE thread)
    : ctx(NULL),
      nursery(0, 0),
      faulting_p(false),
      thread(thread),
#if defined(WINDOWS)
      thread_id(GetCurrentThreadId()),
      ctrl_break_thread(NULL),
#endif
      callback_id(0),
      c_to_factor_func(NULL),
      sampling_profiler_p(false),
      signal_pipe_input(0),
      signal_pipe_output(0),
      current_sample(0, 0, 0, 0, 0),
      gc_off(false),
      data(NULL), code(NULL), callbacks(NULL),
      current_gc(NULL),
      current_gc_p(false),
      current_jit_count(0),
      gc_events(NULL),
      fep_p(false),
      fep_help_was_shown(false),
      fep_disabled(false),
      full_output(false),
      last_nano_count(0),
      signal_callstack_seg(NULL),
      safepoint_fep_p(false),
      stop_on_ctrl_break(false) {
  primitive_reset_dispatch_stats();
}

factor_vm::~factor_vm() {
  free(alien_offset(special_objects[OBJ_EXECUTABLE]));
  free(alien_offset(special_objects[OBJ_IMAGE]));
  close_console();
  FACTOR_ASSERT(!ctx);
  FACTOR_FOR_EACH(unused_contexts) {
    delete *iter;
  }
  FACTOR_FOR_EACH(active_contexts) {
    delete *iter;
  }
  if (callbacks)
    delete callbacks;
  if (data)
    delete data;
  if (code)
    delete code;
  if (signal_callstack_seg) {
    delete signal_callstack_seg;
    signal_callstack_seg = NULL;
  }
  FACTOR_FOR_EACH(function_descriptors) {
    delete[] * iter;
  }
}

}
<commit_msg>VM: init object_counter, silences valgrind #1886<commit_after>#include "master.hpp"

namespace factor {

factor_vm::factor_vm(THREADHANDLE thread)
    : ctx(NULL),
      nursery(0, 0),
      faulting_p(false),
      thread(thread),
#if defined(WINDOWS)
      thread_id(GetCurrentThreadId()),
      ctrl_break_thread(NULL),
#endif
      callback_id(0),
      c_to_factor_func(NULL),
      sampling_profiler_p(false),
      signal_pipe_input(0),
      signal_pipe_output(0),
      current_sample(0, 0, 0, 0, 0),
      gc_off(false),
      data(NULL), code(NULL), callbacks(NULL),
      current_gc(NULL),
      current_gc_p(false),
      current_jit_count(0),
      gc_events(NULL),
      fep_p(false),
      fep_help_was_shown(false),
      fep_disabled(false),
      full_output(false),
      object_counter(0),
      last_nano_count(0),
      signal_callstack_seg(NULL),
      safepoint_fep_p(false),
      stop_on_ctrl_break(false) {
  primitive_reset_dispatch_stats();
}

factor_vm::~factor_vm() {
  free(alien_offset(special_objects[OBJ_EXECUTABLE]));
  free(alien_offset(special_objects[OBJ_IMAGE]));
  close_console();
  FACTOR_ASSERT(!ctx);
  FACTOR_FOR_EACH(unused_contexts) {
    delete *iter;
  }
  FACTOR_FOR_EACH(active_contexts) {
    delete *iter;
  }
  if (callbacks)
    delete callbacks;
  if (data)
    delete data;
  if (code)
    delete code;
  if (signal_callstack_seg) {
    delete signal_callstack_seg;
    signal_callstack_seg = NULL;
  }
  FACTOR_FOR_EACH(function_descriptors) {
    delete[] * iter;
  }
}

}
<|endoftext|>


<commit_before>#include "vm.hpp"
#include "objectmemory.hpp"
#include "objects.hpp"
#include "event.hpp"
#include "global_cache.hpp"
#include "llvm.hpp"
#include "builtin/class.hpp"
#include "builtin/contexts.hpp"
#include "builtin/fixnum.hpp"
#include "builtin/list.hpp"
#include "builtin/symbol.hpp"
#include "builtin/thread.hpp"
#include "builtin/tuple.hpp"
#include "builtin/string.hpp"

#include "config.hpp"

#include <iostream>

namespace rubinius {
  VM::VM(size_t bytes) : probe(NULL), wait_events(false) {
    config.compile_up_front = false;
    context_cache = NULL;

    user_config = new ConfigParser();

    om = new ObjectMemory(bytes);

    MethodContext::initialize_cache(this);

    bootstrap_ontology();

    events = new event::Loop(EVFLAG_FORKCHECK);
    global_cache = new GlobalCache;

    VMLLVMMethod::init("vm/instructions.bc");
    boot_threads();
  }

  VM::~VM() {
    delete om;
    delete events;
    delete global_cache;
    llvm_cleanup();
  }

  void VM::boot_threads() {
    Thread* thr = Thread::create(this);
    thr->boot_task(this);

    activate_thread(thr);
  }

  OBJECT VM::new_object(Class *cls) {
    return om->new_object(cls, cls->instance_fields->to_native());
  }

  SYMBOL VM::symbol(const char* str) {
    return symbols.lookup(this, str);
  }

  SYMBOL VM::symbol(String* str) {
    return symbols.lookup(this, str);
  }

  SYMBOL VM::symbol(std::string str) {
    return symbols.lookup(this, str);
  }

  OBJECT VM::new_struct(Class* cls, size_t bytes) {
    return om->new_object_bytes(cls, bytes);
  }

  void type_assert(OBJECT obj, object_type type, const char* reason) {
    if(obj->reference_p() && obj->obj_type != type) {
      TypeError::raise(type, obj, reason);
    } else if(type == FixnumType && !obj->fixnum_p()) {
      TypeError::raise(type, obj, reason);
    }
  }

  void VM::add_type_info(TypeInfo* ti) {
    om->add_type_info(ti);
    ti->state = this;
  }

  TypeInfo* VM::find_type(int type) {
    return om->type_info[type];
  }

  Thread *VM::current_thread() {
    return globals.current_thread.get();
  }

  void VM::collect() {
    om->collect_young(globals.roots);
    om->collect_mature(globals.roots);
  }

  void VM::run_best_thread() {
    Thread* next = NULL;

    events->poll();

    for(size_t i = globals.scheduled_threads->field_count - 1; i > 0; i--) {
      List* lst = as<List>(globals.scheduled_threads->at(i));
      if(lst->empty_p()) continue;
      next = as<Thread>(lst->shift(this));
      break;
    }

    if(!next) {
      if(events->num_of_events() == 0) {
        throw DeadLock("no runnable threads, present or future.");
      }

      wait_events = true;
      return;
    }

    activate_thread(next);
  }

  void VM::return_value(OBJECT val) {
    globals.current_task->push(val);
  }

  void VM::queue_thread(Thread* thread) {
    List* lst = as<List>(globals.scheduled_threads->at(thread->priority->to_native()));
    lst->append(this, thread);
  }

  void VM::activate_thread(Thread* thread) {
    globals.current_thread.set(thread);
    globals.current_task.set(thread->task);
  }

  OBJECT VM::current_block() {
    return globals.current_task->active->block;
  }

  void VM::raise_from_errno(const char* msg) {
    // TODO: implement me
  }

  void VM::raise_exception(Exception* exc) {
    // TODO: implement me
  }

  void VM::inspect(OBJECT obj) {
    if(obj->symbol_p()) {
      String* str = as<Symbol>(obj)->to_str(this);
      std::cout << "<Symbol :" << (char*)*str << ">" << std::endl;
    } else if(obj->fixnum_p()) {
      std::cout << "<Fixnum " << as<Fixnum>(obj)->to_native() << ">" << std::endl;
    } else {
      std::cout << "<Object: " << (void*)obj << ">" << std::endl;
    }
  }

  void VM::set_const(const char* name, OBJECT val) {
    globals.object->set_const(this, (char*)name, val);
  }

  void VM::set_const(Module* mod, const char* name, OBJECT val) {
    mod->set_const(this, (char*)name, val);
  }

  void VM::print_backtrace() {
    MethodContext* ctx = globals.current_task.get()->active;

    while(!ctx->nil_p()) {
      std::cout << (void*)ctx << ": ";
      // HACK reports Object#[] instead of Hash::[], etc
      std::cout << *ctx->module->name->to_str(this) << "#";

      SYMBOL name = try_as<Symbol>(ctx->name);
      if(name) {
        std::cout << *name->to_str(this);
      } else {
        std::cout << *ctx->cm->name->to_str(this);
      }

      std::cout << ":" << ctx->line() << " in " << *ctx->cm->file->to_str(this);

      std::cout << "\n";
      ctx = ctx->sender;
    }
  }

  Task* VM::new_task() {
    Task* task = Task::create(this);
    globals.current_task.set(task);
    return task;
  }

  /* For debugging. */
  extern "C" {
    void __printbt__(STATE) {
      state->print_backtrace();
    }
  }
};
<commit_msg>Handle BlockContext in the ruby backtrace<commit_after>#include "vm.hpp"
#include "objectmemory.hpp"
#include "objects.hpp"
#include "event.hpp"
#include "global_cache.hpp"
#include "llvm.hpp"
#include "builtin/class.hpp"
#include "builtin/contexts.hpp"
#include "builtin/fixnum.hpp"
#include "builtin/list.hpp"
#include "builtin/symbol.hpp"
#include "builtin/thread.hpp"
#include "builtin/tuple.hpp"
#include "builtin/string.hpp"

#include "config.hpp"

#include <iostream>

namespace rubinius {
  VM::VM(size_t bytes) : probe(NULL), wait_events(false) {
    config.compile_up_front = false;
    context_cache = NULL;

    user_config = new ConfigParser();

    om = new ObjectMemory(bytes);

    MethodContext::initialize_cache(this);

    bootstrap_ontology();

    events = new event::Loop(EVFLAG_FORKCHECK);
    global_cache = new GlobalCache;

    VMLLVMMethod::init("vm/instructions.bc");
    boot_threads();
  }

  VM::~VM() {
    delete om;
    delete events;
    delete global_cache;
    llvm_cleanup();
  }

  void VM::boot_threads() {
    Thread* thr = Thread::create(this);
    thr->boot_task(this);

    activate_thread(thr);
  }

  OBJECT VM::new_object(Class *cls) {
    return om->new_object(cls, cls->instance_fields->to_native());
  }

  SYMBOL VM::symbol(const char* str) {
    return symbols.lookup(this, str);
  }

  SYMBOL VM::symbol(String* str) {
    return symbols.lookup(this, str);
  }

  SYMBOL VM::symbol(std::string str) {
    return symbols.lookup(this, str);
  }

  OBJECT VM::new_struct(Class* cls, size_t bytes) {
    return om->new_object_bytes(cls, bytes);
  }

  void type_assert(OBJECT obj, object_type type, const char* reason) {
    if(obj->reference_p() && obj->obj_type != type) {
      TypeError::raise(type, obj, reason);
    } else if(type == FixnumType && !obj->fixnum_p()) {
      TypeError::raise(type, obj, reason);
    }
  }

  void VM::add_type_info(TypeInfo* ti) {
    om->add_type_info(ti);
    ti->state = this;
  }

  TypeInfo* VM::find_type(int type) {
    return om->type_info[type];
  }

  Thread *VM::current_thread() {
    return globals.current_thread.get();
  }

  void VM::collect() {
    om->collect_young(globals.roots);
    om->collect_mature(globals.roots);
  }

  void VM::run_best_thread() {
    Thread* next = NULL;

    events->poll();

    for(size_t i = globals.scheduled_threads->field_count - 1; i > 0; i--) {
      List* lst = as<List>(globals.scheduled_threads->at(i));
      if(lst->empty_p()) continue;
      next = as<Thread>(lst->shift(this));
      break;
    }

    if(!next) {
      if(events->num_of_events() == 0) {
        throw DeadLock("no runnable threads, present or future.");
      }

      wait_events = true;
      return;
    }

    activate_thread(next);
  }

  void VM::return_value(OBJECT val) {
    globals.current_task->push(val);
  }

  void VM::queue_thread(Thread* thread) {
    List* lst = as<List>(globals.scheduled_threads->at(thread->priority->to_native()));
    lst->append(this, thread);
  }

  void VM::activate_thread(Thread* thread) {
    globals.current_thread.set(thread);
    globals.current_task.set(thread->task);
  }

  OBJECT VM::current_block() {
    return globals.current_task->active->block;
  }

  void VM::raise_from_errno(const char* msg) {
    // TODO: implement me
  }

  void VM::raise_exception(Exception* exc) {
    // TODO: implement me
  }

  void VM::inspect(OBJECT obj) {
    if(obj->symbol_p()) {
      String* str = as<Symbol>(obj)->to_str(this);
      std::cout << "<Symbol :" << (char*)*str << ">" << std::endl;
    } else if(obj->fixnum_p()) {
      std::cout << "<Fixnum " << as<Fixnum>(obj)->to_native() << ">" << std::endl;
    } else {
      std::cout << "<Object: " << (void*)obj << ">" << std::endl;
    }
  }

  void VM::set_const(const char* name, OBJECT val) {
    globals.object->set_const(this, (char*)name, val);
  }

  void VM::set_const(Module* mod, const char* name, OBJECT val) {
    mod->set_const(this, (char*)name, val);
  }

  void VM::print_backtrace() {
    MethodContext* ctx = globals.current_task.get()->active;

    while(!ctx->nil_p()) {
      std::cout << (void*)ctx << ": ";
      if(kind_of<BlockContext>(ctx)) {
        std::cout << "__block__";
      } else {
        // HACK reports Object#[] instead of Hash::[], etc
        std::cout << *ctx->module->name->to_str(this) << "#";

        SYMBOL name = try_as<Symbol>(ctx->name);
        if(name) {
          std::cout << *name->to_str(this);
        } else {
          std::cout << *ctx->cm->name->to_str(this);
        }
      }

      std::cout << ":" << ctx->line() << " in " << *ctx->cm->file->to_str(this);

      std::cout << "\n";
      ctx = ctx->sender;
    }
  }

  Task* VM::new_task() {
    Task* task = Task::create(this);
    globals.current_task.set(task);
    return task;
  }

  /* For debugging. */
  extern "C" {
    void __printbt__(STATE) {
      state->print_backtrace();
    }
  }
};
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009-2011, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#include <climits>
#include <fstream>
#include <ios>
#include <string>

#include <libport/bind.hh>

#include <libport/export.hh>
#include <libport/hierarchy.hh>
#include <libport/unit-test.hh>

#include <serialize/serialize.hh>

using libport::test_suite;
using namespace libport::serialize;

#define BASE "tests/serialize/"

#define SERIALIZE(Type, Value)                                  \
    BOOST_CHECK_NO_THROW(ser.serialize<Type>("test", Value))

#define UNSERIALIZE(Type, Value)                                \
    BOOST_CHECK_EQUAL(ser.unserialize<Type>("test"), Value);

GD_INIT();

void binary_pod()
{
  {
    std::ofstream f(BASE "binary_pod");
    BinaryOSerializer ser(f);

    SERIALIZE(int, 42);
    SERIALIZE(bool, true);
    SERIALIZE(bool, false);
    SERIALIZE(std::string, "string ");
    int* p1 = new int(51);
    int* p2 = new int(69);
    SERIALIZE(int*, p1);
    SERIALIZE(int*, p2);
    SERIALIZE(int*, p2);
    SERIALIZE(int*, p1);
    SERIALIZE(int*, NULL);
  }
  {
    std::ifstream f(BASE "binary_pod");
    BOOST_CHECK(f.good());
    BinaryISerializer ser(f);

    UNSERIALIZE(int, 42);
    UNSERIALIZE(bool, true);
    UNSERIALIZE(bool, false);
    UNSERIALIZE(std::string, "string ");
    int* p1 = ser.unserialize<int*>("test");
    int* p2 = ser.unserialize<int*>("test");
    int* p3 = ser.unserialize<int*>("test");
    int* p4 = ser.unserialize<int*>("test");
    int* p5 = ser.unserialize<int*>("test");
    BOOST_CHECK_EQUAL(*p1, 51);
    BOOST_CHECK_EQUAL(*p2, 69);
    BOOST_CHECK_EQUAL(p1, p4);
    BOOST_CHECK_EQUAL(p2, p3);
    BOOST_CHECK_EQUAL(p5, reinterpret_cast<int*>(NULL));
  }
}

void binary_integers_size()
{
  {
    std::ofstream f(BASE "binary_integers_size");
    BinaryOSerializer ser(f);

    SERIALIZE(unsigned short, USHRT_MAX / 2);
    SERIALIZE(unsigned int, UINT_MAX / 2);
    SERIALIZE(unsigned long, ULONG_MAX / 2);
    SERIALIZE(unsigned long long, ULONG_LONG_MAX / 2);
  }
  {
    std::ifstream f(BASE "binary_integers_size");
    BOOST_CHECK(f.good());
    BinaryISerializer ser(f);
    UNSERIALIZE(unsigned short, USHRT_MAX / 2);
    UNSERIALIZE(unsigned int, UINT_MAX / 2);
    UNSERIALIZE(unsigned long, ULONG_MAX / 2);
    UNSERIALIZE(unsigned long long, ULONG_LONG_MAX / 2);
  }
}

void binary_integers_size_portability()
{
  // Simulate fancy short size.
  {
    std::ofstream f(BASE "binary_integers_size");
    BinaryOSerializer ser(f);

    // Change integers size.
    char sizes[] = {0x4, 0x4, 0x4, 0x8,};
    f.flush();
    f.seekp(std::ios_base::beg);
    f.write(sizes, sizeof(sizes));
    f.flush();

    SERIALIZE(uint32_t, 0);
    SERIALIZE(uint32_t, 42);
    SERIALIZE(uint32_t, USHRT_MAX + 1);
    SERIALIZE(uint32_t, USHRT_MAX);
    f.flush();
    f.close();
  }
  {
    std::ifstream f(BASE "binary_integers_size");
    BOOST_CHECK(f.good());
    BinaryISerializer ser(f);
    UNSERIALIZE(unsigned short, 0);
    UNSERIALIZE(unsigned short, 42);
    BOOST_CHECK_THROW(ser.unserialize<unsigned short>(),
                      libport::serialize::Exception);
    UNSERIALIZE(unsigned short, USHRT_MAX);
  }
}

struct Person
{
  Person(const std::string& name, const std::string& surname)
    : name_(name)
    , surname_(surname)
  {}

  template <typename S>
  Person(ISerializer<S>& input)
    : name_(input.template unserialize<std::string>("name"))
    , surname_(input.template unserialize<std::string>("surname"))
  {

  }

  template <typename S>
  void serialize(OSerializer<S>& output) const
  {
    output.serialize<std::string>("name", name_);
    output.serialize<std::string>("surname", surname_);
  }

  std::string name_, surname_;
};

void binary_class()
{
  {
    std::ofstream f(BASE "binary_class");
    BinaryOSerializer ser(f);

    Person ed("Draven", "Eric");
    Person cs("Slade", "Cutter");
    ser.serialize<Person>("test", ed);
    ser.serialize<Person>("test", cs);
  }
  {
    std::ifstream f(BASE "binary_class");
    BinaryISerializer ser(f);

    Person ed = ser.unserialize<Person>("test");
    Person cs = ser.unserialize<Person>("test");
    BOOST_CHECK_EQUAL(ed.name_, "Draven");
    BOOST_CHECK_EQUAL(ed.surname_, "Eric");
    BOOST_CHECK_EQUAL(cs.name_, "Slade");
    BOOST_CHECK_EQUAL(cs.surname_, "Cutter");
  }
}

class Unix;
class Linux;
class Gentoo;
class Debian;

class Unix: public libport::meta::Hierarchy<Unix, TYPELIST_2(Gentoo, Debian)>
{

};

struct Linux: public Unix
{
  Linux(const std::string& k)
    : kernel(k)
  {}

  template <typename T>
  Linux(ISerializer<T>& ser)
  {
    kernel = ser.template unserialize<std::string>("kernel");
  }

  template <typename T>
  void serialize(OSerializer<T>& ser) const
  {
    ser.template serialize<std::string>("kernel", kernel);
  }

  std::string kernel;
};

struct Debian: public Linux
{
  Debian(const std::string& kernel, const std::string& v)
    : Linux(kernel)
    , version(v)
  {}

  template <typename T>
  Debian(ISerializer<T>& ser)
    : Linux(ser)
  {
    version = ser.template unserialize<std::string>("version");
  }

  template <typename T>
  void serialize(OSerializer<T>& ser) const
  {
    Linux::serialize(ser);
    ser.serialize<std::string>("version", version);
  }

  std::string version;
};

struct Gentoo: public Linux
{
  Gentoo(const std::string& kernel, int v)
    : Linux(kernel)
    , version(v)
  {}

  template <typename T>
  Gentoo(ISerializer<T>& ser)
    : Linux(ser)
  {
    version = ser.template unserialize<int>("version");
  }

  template <typename T>
  void serialize(OSerializer<T>& ser) const
  {
    Linux::serialize(ser);
    ser.serialize<int>("version", version);
  }

  int version;
};

void binary_hierarchy()
{
  {
    std::ofstream f(BASE "binary_hier");
    BinaryOSerializer ser(f);

    Debian d("2.4", "sarge");
    Gentoo g("2.6", 2008);
    ser.serialize<Debian>("test", d);
    ser.serialize<Gentoo>("test", g);
  }
  {
    std::ifstream f(BASE "binary_hier");
    BinaryISerializer ser(f);

    Unix* d_ = ser.unserialize<Unix>("test");
    Unix* g_ = ser.unserialize<Unix>("test");
    Debian* d = dynamic_cast<Debian*>(d_ );
    Gentoo* g = dynamic_cast<Gentoo*>(g_) ;
    BOOST_CHECK(d);
    BOOST_CHECK(g);
    BOOST_CHECK_EQUAL(d->kernel, "2.4");
    BOOST_CHECK_EQUAL(d->version, "sarge");
    BOOST_CHECK_EQUAL(g->kernel, "2.6");
    BOOST_CHECK_EQUAL(g->version, 2008);
  }
}

test_suite*
init_test_suite()
{
  test_suite* suite = BOOST_TEST_SUITE("Serialization test suite");
  suite->add(BOOST_TEST_CASE(binary_pod));
  suite->add(BOOST_TEST_CASE(binary_integers_size));
  suite->add(BOOST_TEST_CASE(binary_integers_size_portability));
  suite->add(BOOST_TEST_CASE(binary_class));
  suite->add(BOOST_TEST_CASE(binary_hierarchy));
  return suite;
}
<commit_msg>serialize: better tests.<commit_after>/*
 * Copyright (C) 2009-2011, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#include <climits>
#include <fstream>
#include <ios>
#include <string>

#include <libport/debug.hh>
#include <libport/bind.hh>

#include <libport/export.hh>
#include <libport/hierarchy.hh>
#include <libport/unit-test.hh>

#include <serialize/serialize.hh>

using libport::test_suite;
using namespace libport::serialize;

#define BASE "tests/serialize/"

#define SERIALIZE(Type, Value)                                  \
    BOOST_CHECK_NO_THROW(ser.serialize<Type>("test", Value))

#define UNSERIALIZE(Type, Value)                                \
    BOOST_CHECK_EQUAL(ser.unserialize<Type>("test"), Value);

GD_INIT();

void binary_pod()
{
  {
    std::ofstream f(BASE "binary_pod");
    BinaryOSerializer ser(f);

    SERIALIZE(int, 42);
    SERIALIZE(bool, true);
    SERIALIZE(bool, false);
    SERIALIZE(std::string, "string ");
    int* p1 = new int(51);
    int* p2 = new int(69);
    SERIALIZE(int*, p1);
    SERIALIZE(int*, p2);
    SERIALIZE(int*, p2);
    SERIALIZE(int*, p1);
    SERIALIZE(int*, NULL);
  }
  {
    std::ifstream f(BASE "binary_pod");
    BOOST_CHECK(f.good());
    BinaryISerializer ser(f);

    UNSERIALIZE(int, 42);
    UNSERIALIZE(bool, true);
    UNSERIALIZE(bool, false);
    UNSERIALIZE(std::string, "string ");
    int* p1 = ser.unserialize<int*>("test");
    int* p2 = ser.unserialize<int*>("test");
    int* p3 = ser.unserialize<int*>("test");
    int* p4 = ser.unserialize<int*>("test");
    int* p5 = ser.unserialize<int*>("test");
    BOOST_CHECK_EQUAL(*p1, 51);
    BOOST_CHECK_EQUAL(*p2, 69);
    BOOST_CHECK_EQUAL(p1, p4);
    BOOST_CHECK_EQUAL(p2, p3);
    BOOST_CHECK_EQUAL(p5, reinterpret_cast<int*>(NULL));
  }
}

void binary_integers_size()
{
  const char *fn = BASE "binary_integers_size";

#define CHECK(Type)                                                     \
  do {                                                                  \
    {                                                                   \
      std::ofstream f(fn);                                              \
      BinaryOSerializer ser(f);                                         \
      SERIALIZE(Type, (Type) (std::numeric_limits<Type>::max() / 2));   \
    }                                                                   \
    {                                                                   \
      std::ifstream f(fn);                                              \
      BOOST_CHECK(f.good());                                            \
      BinaryISerializer ser(f);                                         \
      UNSERIALIZE(Type, (Type) (std::numeric_limits<Type>::max() / 2)); \
      f.peek();                                                         \
      BOOST_CHECK(f.eof());                                             \
    }                                                                   \
  } while (false)

  CHECK(unsigned short);
  CHECK(unsigned int);
  CHECK(unsigned long);
  CHECK(unsigned long long);
#undef CHECK
}

void binary_integers_size_portability()
{
  // Simulate fancy short size.
  {
    std::ofstream f(BASE "binary_integers_size");
    BinaryOSerializer ser(f);

    // Change integers size.
    char sizes[] = {0x4, 0x4, 0x4, 0x8,};
    f.flush();
    f.seekp(std::ios_base::beg);
    f.write(sizes, sizeof(sizes));
    f.flush();

    SERIALIZE(uint32_t, 0);
    SERIALIZE(uint32_t, 42);
    SERIALIZE(uint32_t, USHRT_MAX + 1);
    SERIALIZE(uint32_t, USHRT_MAX);
    f.flush();
    f.close();
  }
  {
    std::ifstream f(BASE "binary_integers_size");
    BOOST_CHECK(f.good());
    BinaryISerializer ser(f);
    UNSERIALIZE(unsigned short, 0);
    UNSERIALIZE(unsigned short, 42);
    BOOST_CHECK_THROW(ser.unserialize<unsigned short>(),
                      libport::serialize::Exception);
    UNSERIALIZE(unsigned short, USHRT_MAX);
  }
}

struct Person
{
  Person(const std::string& name, const std::string& surname)
    : name_(name)
    , surname_(surname)
  {}

  template <typename S>
  Person(ISerializer<S>& input)
    : name_(input.template unserialize<std::string>("name"))
    , surname_(input.template unserialize<std::string>("surname"))
  {

  }

  template <typename S>
  void serialize(OSerializer<S>& output) const
  {
    output.serialize<std::string>("name", name_);
    output.serialize<std::string>("surname", surname_);
  }

  std::string name_, surname_;
};

void binary_class()
{
  {
    std::ofstream f(BASE "binary_class");
    BinaryOSerializer ser(f);

    Person ed("Draven", "Eric");
    Person cs("Slade", "Cutter");
    ser.serialize<Person>("test", ed);
    ser.serialize<Person>("test", cs);
  }
  {
    std::ifstream f(BASE "binary_class");
    BinaryISerializer ser(f);

    Person ed = ser.unserialize<Person>("test");
    Person cs = ser.unserialize<Person>("test");
    BOOST_CHECK_EQUAL(ed.name_, "Draven");
    BOOST_CHECK_EQUAL(ed.surname_, "Eric");
    BOOST_CHECK_EQUAL(cs.name_, "Slade");
    BOOST_CHECK_EQUAL(cs.surname_, "Cutter");
  }
}

class Unix;
class Linux;
class Gentoo;
class Debian;

class Unix: public libport::meta::Hierarchy<Unix, TYPELIST_2(Gentoo, Debian)>
{

};

struct Linux: public Unix
{
  Linux(const std::string& k)
    : kernel(k)
  {}

  template <typename T>
  Linux(ISerializer<T>& ser)
  {
    kernel = ser.template unserialize<std::string>("kernel");
  }

  template <typename T>
  void serialize(OSerializer<T>& ser) const
  {
    ser.template serialize<std::string>("kernel", kernel);
  }

  std::string kernel;
};

struct Debian: public Linux
{
  Debian(const std::string& kernel, const std::string& v)
    : Linux(kernel)
    , version(v)
  {}

  template <typename T>
  Debian(ISerializer<T>& ser)
    : Linux(ser)
  {
    version = ser.template unserialize<std::string>("version");
  }

  template <typename T>
  void serialize(OSerializer<T>& ser) const
  {
    Linux::serialize(ser);
    ser.serialize<std::string>("version", version);
  }

  std::string version;
};

struct Gentoo: public Linux
{
  Gentoo(const std::string& kernel, int v)
    : Linux(kernel)
    , version(v)
  {}

  template <typename T>
  Gentoo(ISerializer<T>& ser)
    : Linux(ser)
  {
    version = ser.template unserialize<int>("version");
  }

  template <typename T>
  void serialize(OSerializer<T>& ser) const
  {
    Linux::serialize(ser);
    ser.serialize<int>("version", version);
  }

  int version;
};

void binary_hierarchy()
{
  {
    std::ofstream f(BASE "binary_hier");
    BinaryOSerializer ser(f);

    Debian d("2.4", "sarge");
    Gentoo g("2.6", 2008);
    ser.serialize<Debian>("test", d);
    ser.serialize<Gentoo>("test", g);
  }
  {
    std::ifstream f(BASE "binary_hier");
    BinaryISerializer ser(f);

    Unix* d_ = ser.unserialize<Unix>("test");
    Unix* g_ = ser.unserialize<Unix>("test");
    Debian* d = dynamic_cast<Debian*>(d_ );
    Gentoo* g = dynamic_cast<Gentoo*>(g_) ;
    BOOST_CHECK(d);
    BOOST_CHECK(g);
    BOOST_CHECK_EQUAL(d->kernel, "2.4");
    BOOST_CHECK_EQUAL(d->version, "sarge");
    BOOST_CHECK_EQUAL(g->kernel, "2.6");
    BOOST_CHECK_EQUAL(g->version, 2008);
  }
}

test_suite*
init_test_suite()
{
  test_suite* suite = BOOST_TEST_SUITE("Serialization test suite");
  suite->add(BOOST_TEST_CASE(binary_pod));
  suite->add(BOOST_TEST_CASE(binary_integers_size));
  suite->add(BOOST_TEST_CASE(binary_integers_size_portability));
  suite->add(BOOST_TEST_CASE(binary_class));
  suite->add(BOOST_TEST_CASE(binary_hierarchy));
  return suite;
}
<|endoftext|>


<commit_before>#include <utils/logger.h>
#include <algorithm>
#include "DaedalusDialogManager.h"
#include "DaedalusVM.h"
#include "DaedalusStdlib.h"

using namespace Daedalus;
using namespace GameState;
using namespace ZenLoad;

DaedalusDialogManager::DaedalusDialogManager(Daedalus::DaedalusVM& vm,const std::string& ou_bin)
    : m_VM(vm),
      m_MessageLib(ou_bin)
{
    gatherNpcInformation();
}

void DaedalusDialogManager::registerExternals(
        std::function<void(NpcHandle, NpcHandle, const ZenLoad::oCMsgConversationData&)> onAIOutput,
        std::function<void(NpcHandle, std::vector<InfoHandle>)> onStartConversation)
{
    m_OnAIOutput = onAIOutput;
	m_OnStartConversation = onStartConversation;

    m_VM.registerExternalFunction("ai_output", [&](Daedalus::DaedalusVM& vm){
        std::string outputname = vm.popString();
        uint32_t target = vm.popVar();
        uint32_t self = vm.popVar();

        auto& message = m_MessageLib.getMessageByName(outputname);

        NpcHandle hself = ZMemory::handleCast<NpcHandle>(m_VM.getDATFile().getSymbolByIndex(self).instanceDataHandle);
        NpcHandle htarget = ZMemory::handleCast<NpcHandle>(m_VM.getDATFile().getSymbolByIndex(target).instanceDataHandle);

        // Notify user
        m_OnAIOutput(hself, htarget, message);
    });

    m_VM.registerExternalFunction("AI_ProcessInfos", [&](Daedalus::DaedalusVM& vm){
        uint32_t self = vm.popVar();

        NpcHandle hself = ZMemory::handleCast<NpcHandle>(m_VM.getDATFile().getSymbolByIndex(self).instanceDataHandle);
        Daedalus::GEngineClasses::C_Npc& npc = m_VM.getGameState().getNpc(hself);

		auto& info = m_NpcInfosByNpcSymbols[npc.instanceSymbol];

        // Notify user
		m_OnStartConversation(hself, info);
    });

    m_VM.registerExternalFunction("InfoManager_HasFinished", [](Daedalus::DaedalusVM& vm){

        // TODO: Implement this
        vm.setReturn(1);
    });

    m_VM.registerExternalFunction("npc_knowsinfo", [&](Daedalus::DaedalusVM& vm){
        int32_t infoinstance = vm.popDataValue();
        int32_t self = vm.popVar();

        NpcHandle hself = ZMemory::handleCast<NpcHandle>(m_VM.getDATFile().getSymbolByIndex(self).instanceDataHandle);
        Daedalus::GEngineClasses::C_Npc& npc = m_VM.getGameState().getNpc(hself);

        auto& l = m_KnownNpcInfoSymbolsByNpcSymbols[npc.instanceSymbol];
        int32_t knows = l.find(infoinstance) != l.end() ? 1 : 0;

        //LogInfo() << "Does he kow? (" << vm.getDATFile().getSymbolByIndex(npc.instanceSymbol).name << " -> " << vm.getDATFile().getSymbolByIndex(infoinstance).name << "): " << knows;

        vm.setReturn(knows);
    });
}

void DaedalusDialogManager::gatherNpcInformation()
{
    m_VM.getDATFile().iterateSymbolsOfClass("C_Info", [&](size_t i, Daedalus::PARSymbol& s){

        // Create new info-object
        InfoHandle h = m_VM.getGameState().createInfo();
        Daedalus::GEngineClasses::C_Info& info = m_VM.getGameState().getInfo(h);
        m_VM.initializeInstance(ZMemory::toBigHandle(h), i, Daedalus::IC_Info);

        // Add to map
        m_NpcInfosByNpcSymbols[info.npc].push_back(h);
    });

    // Messages are in wrong order. Fix this.
    for(auto& v : m_NpcInfosByNpcSymbols)
    {
        std::reverse(v.second.begin(),v.second.end());
    }
}

void DaedalusDialogManager::setNpcInfoKnown(size_t npcInstance, size_t infoInstance)
{
    //LogInfo() << "He knows! (" << m_VM.getDATFile().getSymbolByIndex(npcInstance).name << " -> " << m_VM.getDATFile().getSymbolByIndex(infoInstance).name << ")!";
    m_KnownNpcInfoSymbolsByNpcSymbols[npcInstance].insert(infoInstance);
}

void DaedalusDialogManager::processInfosFor(NpcHandle hnpc)
{
    Daedalus::GEngineClasses::C_Npc& npc = m_VM.getGameState().getNpc(hnpc);
    auto& info = m_NpcInfosByNpcSymbols[npc.instanceSymbol];

    // Notify user
    m_OnStartConversation(hnpc, info);
}

bool DaedalusDialogManager::doesNpcKnowInfo(size_t npcInstance, size_t infoInstance)
{
    const auto& m = m_KnownNpcInfoSymbolsByNpcSymbols[npcInstance];
    return m.find(infoInstance) != m.end();
}

<commit_msg>Not registering InfoManager_HasFinished anymore<commit_after>#include <utils/logger.h>
#include <algorithm>
#include "DaedalusDialogManager.h"
#include "DaedalusVM.h"
#include "DaedalusStdlib.h"

using namespace Daedalus;
using namespace GameState;
using namespace ZenLoad;

DaedalusDialogManager::DaedalusDialogManager(Daedalus::DaedalusVM& vm,const std::string& ou_bin)
    : m_VM(vm),
      m_MessageLib(ou_bin)
{
    gatherNpcInformation();
}

void DaedalusDialogManager::registerExternals(
        std::function<void(NpcHandle, NpcHandle, const ZenLoad::oCMsgConversationData&)> onAIOutput,
        std::function<void(NpcHandle, std::vector<InfoHandle>)> onStartConversation)
{
    m_OnAIOutput = onAIOutput;
	m_OnStartConversation = onStartConversation;

    m_VM.registerExternalFunction("ai_output", [&](Daedalus::DaedalusVM& vm){
        std::string outputname = vm.popString();
        uint32_t target = vm.popVar();
        uint32_t self = vm.popVar();

        auto& message = m_MessageLib.getMessageByName(outputname);

        NpcHandle hself = ZMemory::handleCast<NpcHandle>(m_VM.getDATFile().getSymbolByIndex(self).instanceDataHandle);
        NpcHandle htarget = ZMemory::handleCast<NpcHandle>(m_VM.getDATFile().getSymbolByIndex(target).instanceDataHandle);

        // Notify user
        m_OnAIOutput(hself, htarget, message);
    });

    m_VM.registerExternalFunction("AI_ProcessInfos", [&](Daedalus::DaedalusVM& vm){
        uint32_t self = vm.popVar();

        NpcHandle hself = ZMemory::handleCast<NpcHandle>(m_VM.getDATFile().getSymbolByIndex(self).instanceDataHandle);
        Daedalus::GEngineClasses::C_Npc& npc = m_VM.getGameState().getNpc(hself);

		auto& info = m_NpcInfosByNpcSymbols[npc.instanceSymbol];

        // Notify user
		m_OnStartConversation(hself, info);
    });

    m_VM.registerExternalFunction("npc_knowsinfo", [&](Daedalus::DaedalusVM& vm){
        int32_t infoinstance = vm.popDataValue();
        int32_t self = vm.popVar();

        NpcHandle hself = ZMemory::handleCast<NpcHandle>(m_VM.getDATFile().getSymbolByIndex(self).instanceDataHandle);
        Daedalus::GEngineClasses::C_Npc& npc = m_VM.getGameState().getNpc(hself);

        auto& l = m_KnownNpcInfoSymbolsByNpcSymbols[npc.instanceSymbol];
        int32_t knows = l.find(infoinstance) != l.end() ? 1 : 0;

        //LogInfo() << "Does he kow? (" << vm.getDATFile().getSymbolByIndex(npc.instanceSymbol).name << " -> " << vm.getDATFile().getSymbolByIndex(infoinstance).name << "): " << knows;

        vm.setReturn(knows);
    });
}

void DaedalusDialogManager::gatherNpcInformation()
{
    m_VM.getDATFile().iterateSymbolsOfClass("C_Info", [&](size_t i, Daedalus::PARSymbol& s){

        // Create new info-object
        InfoHandle h = m_VM.getGameState().createInfo();
        Daedalus::GEngineClasses::C_Info& info = m_VM.getGameState().getInfo(h);
        m_VM.initializeInstance(ZMemory::toBigHandle(h), i, Daedalus::IC_Info);

        // Add to map
        m_NpcInfosByNpcSymbols[info.npc].push_back(h);
    });

    // Messages are in wrong order. Fix this.
    for(auto& v : m_NpcInfosByNpcSymbols)
    {
        std::reverse(v.second.begin(),v.second.end());
    }
}

void DaedalusDialogManager::setNpcInfoKnown(size_t npcInstance, size_t infoInstance)
{
    //LogInfo() << "He knows! (" << m_VM.getDATFile().getSymbolByIndex(npcInstance).name << " -> " << m_VM.getDATFile().getSymbolByIndex(infoInstance).name << ")!";
    m_KnownNpcInfoSymbolsByNpcSymbols[npcInstance].insert(infoInstance);
}

void DaedalusDialogManager::processInfosFor(NpcHandle hnpc)
{
    Daedalus::GEngineClasses::C_Npc& npc = m_VM.getGameState().getNpc(hnpc);
    auto& info = m_NpcInfosByNpcSymbols[npc.instanceSymbol];

    // Notify user
    m_OnStartConversation(hnpc, info);
}

bool DaedalusDialogManager::doesNpcKnowInfo(size_t npcInstance, size_t infoInstance)
{
    const auto& m = m_KnownNpcInfoSymbolsByNpcSymbols[npcInstance];
    return m.find(infoInstance) != m.end();
}

<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdint.h>
#include <chrono>

#ifdef LOWSTAR
#include "Low_GCMencrypt.h"
#endif // LOWSTAR

typedef unsigned char byte;

struct args
{
    byte *plain_ptr;
    uint64_t plain_num_bytes;
    byte *auth_ptr;
    uint64_t auth_num_bytes;
    byte *iv_ptr;
    byte *expanded_key_ptr;
    byte *out_ptr;
    byte *tag_ptr;
};

extern "C" void aes128_key_expansion(byte *key_ptr, byte *key_expansion_ptr);
extern "C" void gcm128_encrypt(args *a);
extern "C" int gcm128_decrypt(args *a);

extern "C" void aes256_key_expansion(byte *key_ptr, byte *key_expansion_ptr);
extern "C" void gcm256_encrypt(args *a);
extern "C" int gcm256_decrypt(args *a);

byte key[32] =
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
     16,17,18,19,20,21,22,23,24,25, 26, 27, 28, 29, 30, 31 };
byte key_expansion[15 * (128/8)];

byte plain[32] =
    { 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
      216, 217, 218, 99,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
    };
byte auth[1]; // actually size 0
byte iv[16] =
    { 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 0, 0, 0, 0 };
byte out[32];
byte tag[16];

void printbytes(char *label, byte *b, int len)
{
    printf("%s:", label);
    for (int i = 0; i < len; i++) printf(" %2x", unsigned(b[i]));
    printf("\n");
}

void test(void (*aes_key_expansion) (byte*, byte*),
          void (*gcm_encrypt) (args*),
          int  (*gcm_decrypt) (args*),
          int num_rounds)
{
    args a;
    a.plain_ptr = plain;
    a.plain_num_bytes = 19;
    a.auth_ptr = auth;
    a.auth_num_bytes = 0;
    a.iv_ptr = iv;
    a.expanded_key_ptr = key_expansion;
    a.out_ptr = out;
    a.tag_ptr = tag;
    printbytes((char*)"original plaintext", plain, 19);
    printbytes((char*)"key", key, 16);
    aes_key_expansion(key, key_expansion);
    printbytes((char*)"key_expansion", key_expansion, (num_rounds + 1) * 16);
    gcm_encrypt(&a);
    printbytes((char*)"cipher", out, 19);
    printbytes((char*)"tag", tag, 16);

    a.out_ptr = plain;
    a.plain_ptr = out;
    int ret = gcm_decrypt(&a);
    printf("gcm_decrypt returned %d\n", ret);
    printbytes((char*)"plaintext", plain, 19);

    int nblocks = 256;
    byte *plain2 = new byte[nblocks * 16];
    byte *out2 = new byte[nblocks * 16];
    for (int i = 0; i < nblocks * 16; i++)
    {
        plain2[i] = i % 256;
    }
    a.plain_ptr = plain2;
    a.plain_num_bytes = nblocks * 16;
    a.out_ptr = out2;
    for (int i = 0; i < 10; i++)
    {
        auto time1 = std::chrono::high_resolution_clock::now();
        int n = 10000;
        for (int j = 0; j < n; j++)
        {
            gcm_encrypt(&a);
        }
        auto time2 = std::chrono::high_resolution_clock::now();
        int dt = std::chrono::duration_cast<std::chrono::microseconds>(time2 - time1).count();
        printf("time = %d microseconds for %d iterations (%lf MB/s)\n", dt, n, double(n) * (nblocks * 16) / dt);
    }
    printbytes((char*)"cipher", out2, 16);
    printbytes((char*)"tag", tag, 16);
}

#ifdef LOWSTAR

void test_lowstar() {
    byte iv_backup[16];

    // Save a copy of iv, since Low* version modifies it
    memcpy(iv_backup, iv, 16);

    int auth_num_bytes = 0;
    int plain_num_bytes = 19;
    int num_rounds = 10;
    args a;
    a.plain_ptr = plain;
    a.plain_num_bytes = plain_num_bytes;
    a.auth_ptr = auth;
    a.auth_num_bytes = auth_num_bytes;
    a.iv_ptr = iv;
    a.expanded_key_ptr = key_expansion;
    a.out_ptr = out;
    a.tag_ptr = tag;
    printbytes((char*)"original plaintext", plain, 19);
    printbytes((char*)"key", key, 16);
    aes128_key_expansion(key, key_expansion);
    printbytes((char*)"key_expansion", key_expansion, (num_rounds + 1) * 16);

    // Encrypt using Low* version
    Low_GCMencrypt_gcm_core(plain, plain_num_bytes, auth, auth_num_bytes, iv, key_expansion, out, tag);
    //gcm_encrypt(&a);

    printbytes((char*)"cipher", out, 19);
    printbytes((char*)"tag", tag, 16);

    // Restore iv
    memcpy(iv, iv_backup, 16);
    a.out_ptr = plain;
    a.plain_ptr = out;

    // Decrypt using Vale version
    int ret = gcm128_decrypt(&a);
    printf("gcm_decrypt returned %d\n", ret);
    printbytes((char*)"decrypted plaintext", plain, 19);

    int nblocks = 256;
    byte *plain2 = new byte[nblocks * 16];
    byte *out2 = new byte[nblocks * 16];
    for (int i = 0; i < nblocks * 16; i++)
    {
        plain2[i] = i % 256;
    }

    for (int i = 0; i < 10; i++)
    {
        auto time1 = std::chrono::high_resolution_clock::now();
        int n = 10000;
        for (int j = 0; j < n; j++)
        {
          Low_GCMencrypt_gcm_core(plain2, nblocks * 16, auth, auth_num_bytes, iv, key_expansion, out2, tag);
        }
        auto time2 = std::chrono::high_resolution_clock::now();
        int dt = std::chrono::duration_cast<std::chrono::microseconds>(time2 - time1).count();
        printf("time = %d microseconds for %d iterations (%lf MB/s)\n", dt, n, double(n) * (nblocks * 16) / dt);
    }
    printbytes((char*)"cipher", out2, 16);
    printbytes((char*)"tag", tag, 16);
}

#endif // LOWSTAR

int main()
{
    printf("hello\n");

#ifdef LOWSTAR
    test_lowstar();
#else // !LOWSTAR
    printf("\nBeginning 128-bit test...\n");
    test(aes128_key_expansion,
         gcm128_encrypt,
         gcm128_decrypt,
         10);

    printf("\nBeginning 256-bit test...\n");
    test(aes256_key_expansion,
         gcm256_encrypt,
         gcm256_decrypt,
         14);
#endif // LOWSTAR

    printf("goodbye\n");
    return 0;
}
<commit_msg>Add additional alignment directives and profiling support<commit_after>#include <stdio.h>
#include <stdint.h>
#include <chrono>
#include <math.h>

#ifdef LOWSTAR
#include "Low_GCMencrypt.h"
#endif // LOWSTAR

typedef unsigned char byte;
double cpuFreq;
struct args
{
    byte *plain_ptr;
    uint64_t plain_num_bytes;
    byte *auth_ptr;
    uint64_t auth_num_bytes;
    byte *iv_ptr;
    byte *expanded_key_ptr;
    byte *out_ptr;
    byte *tag_ptr;
};

extern "C" void aes128_key_expansion(byte *key_ptr, byte *key_expansion_ptr);
extern "C" void gcm128_encrypt(args *a);
extern "C" int gcm128_decrypt(args *a);

extern "C" void aes256_key_expansion(byte *key_ptr, byte *key_expansion_ptr);
extern "C" void gcm256_encrypt(args *a);
extern "C" int gcm256_decrypt(args *a);

#ifdef _WIN32
#include <intrin.h>
#include <Windows.h>
#pragma intrinsic(__rdtsc)
#else
#include <unistd.h> /* For sleep() */
#define Sleep(x) usleep(x*1000)
#endif

alignas(128) byte key[32] =
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
     16,17,18,19,20,21,22,23,24,25, 26, 27, 28, 29, 30, 31 };
alignas(128) byte key_expansion[15 * (128/8)];

alignas(128) byte plain[32] =
    { 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
      216, 217, 218, 99,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
    };
alignas(128) byte auth[1]; // actually size 0
alignas(128) byte iv[16] =
    { 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 0, 0, 0, 0 };
alignas(128) byte out[32] ;
alignas(128) byte tag[16] ;

void printbytes(char *label, byte *b, int len)
{
    printf("%s:", label);
    for (int i = 0; i < len; i++) printf(" %2x", unsigned(b[i]));
    printf("\n");
}

uint64_t GetRDTSC() {
        //VS on x64 doesn't support inline assembly
   //__asm {
   //   ; Flush the pipeline
   //   XOR eax, eax
   //   CPUID
   //   ; Get RDTSC counter in edx:eax
   //   RDTSC
   //}
#ifdef _WIN32
        int CPUInfo[4];
        int InfoType = 0;
   __cpuid(CPUInfo, InfoType); // Serialize the pipeline
   return (unsigned __int64)__rdtsc();
#else
//        uint64_t rv;
//        __asm__ (
//                "push           %%rbx;"
//                "cpuid;"
//                "pop            %%rbx;"
//                :::"%rax","%rcx","%rdx");
//        __asm__ __volatile__ ("rdtsc" : "=A" (rv));
//        return (rv);
        unsigned int tickl, tickh;
        __asm__ __volatile__("rdtsc":"=a"(tickl),"=d"(tickh));
        return ((unsigned long long)tickh << 32)|tickl;
#endif // _WIN32
}

void test(void (*aes_key_expansion) (byte*, byte*),
          void (*gcm_encrypt) (args*),
          int  (*gcm_decrypt) (args*),
          int num_rounds)
{
    args a;
    a.plain_ptr = plain;
    a.plain_num_bytes = 19;
    a.auth_ptr = auth;
    a.auth_num_bytes = 0;
    a.iv_ptr = iv;
    a.expanded_key_ptr = key_expansion;
    a.out_ptr = out;
    a.tag_ptr = tag;
    printbytes((char*)"original plaintext", plain, 19);
    printbytes((char*)"key", key, 16);
    aes_key_expansion(key, key_expansion);
    printbytes((char*)"key_expansion", key_expansion, (num_rounds + 1) * 16);
    gcm_encrypt(&a);
    printbytes((char*)"cipher", out, 19);
    printbytes((char*)"tag", tag, 16);

    a.out_ptr = plain;
    a.plain_ptr = out;
    int ret = gcm_decrypt(&a);
    printf("gcm_decrypt returned %d\n", ret);
    printbytes((char*)"plaintext", plain, 19);

    int nblocks = 256;
    byte *plain2 = new byte[nblocks * 16+128];
    byte *out2 = new byte[nblocks * 16+128];
    // Make sure the buffers are 128-bit aligned
    int byte_offset = 128 - (((unsigned long long) plain2) % 128);
    plain2 = (byte*) (((unsigned long long) plain2) + byte_offset);
    byte_offset = 128 - (((unsigned long long) out2) % 128);
    out2 = (byte*) (((unsigned long long) out2) + byte_offset);
    printf("\nout2 pointer: %llx\n", (unsigned long long)out2);
    printf("\nplain2 pointer: %llx\n", (unsigned long long)plain2);
    printf("\nkey_expansion pointer: %llx\n", (unsigned long long)key_expansion);
    for (int i = 0; i < nblocks * 16; i++)
    {
        plain2[i] = i % 256;
    }
    a.plain_ptr = plain2;
    a.plain_num_bytes = nblocks * 16;
    a.out_ptr = out2;
    for (int i = 0; i < 10; i++)
    {
        auto time1 = std::chrono::high_resolution_clock::now();
        uint64_t start = GetRDTSC();
        int n = 10000;
        for (int j = 0; j < n; j++)
        {
            gcm_encrypt(&a);
        }
        uint64_t end = GetRDTSC();
        auto time2 = std::chrono::high_resolution_clock::now();
        int dt = std::chrono::duration_cast<std::chrono::microseconds>(time2 - time1).count();
        printf("time = %d microseconds for %d iterations (%lf MB/s)\n", dt, n, double(n) * (nblocks * 16) / dt);
        printf("cycle diff = %llu, time = %fs\n", end - start, (end - start) / cpuFreq);
    }
    printbytes((char*)"cipher", out2, 16);
    printbytes((char*)"tag", tag, 16);
}

#ifdef LOWSTAR

void test_lowstar() {
    byte iv_backup[16];

    // Save a copy of iv, since Low* version modifies it
    memcpy(iv_backup, iv, 16);

    int auth_num_bytes = 0;
    int plain_num_bytes = 19;
    int num_rounds = 10;
    args a;
    a.plain_ptr = plain;
    a.plain_num_bytes = plain_num_bytes;
    a.auth_ptr = auth;
    a.auth_num_bytes = auth_num_bytes;
    a.iv_ptr = iv;
    a.expanded_key_ptr = key_expansion;
    a.out_ptr = out;
    a.tag_ptr = tag;
    printbytes((char*)"original plaintext", plain, 19);
    printbytes((char*)"key", key, 16);
    aes128_key_expansion(key, key_expansion);
    printbytes((char*)"key_expansion", key_expansion, (num_rounds + 1) * 16);

    // Encrypt using Low* version
    Low_GCMencrypt_gcm_core(plain, plain_num_bytes, auth, auth_num_bytes, iv, key_expansion, out, tag);
    //gcm_encrypt(&a);

    printbytes((char*)"cipher", out, 19);
    printbytes((char*)"tag", tag, 16);

    // Restore iv
    memcpy(iv, iv_backup, 16);
    a.out_ptr = plain;
    a.plain_ptr = out;

    // Decrypt using Vale version
    int ret = gcm128_decrypt(&a);
    printf("gcm_decrypt returned %d\n", ret);
    printbytes((char*)"decrypted plaintext", plain, 19);

    int nblocks = 256;
    byte *plain2 = new byte[nblocks * 16];
    byte *out2 = new byte[nblocks * 16];
    for (int i = 0; i < nblocks * 16; i++)
    {
        plain2[i] = i % 256;
    }

    for (int i = 0; i < 10; i++)
    {
        auto time1 = std::chrono::high_resolution_clock::now();
        int n = 10000;
        for (int j = 0; j < n; j++)
        {
          Low_GCMencrypt_gcm_core(plain2, nblocks * 16, auth, auth_num_bytes, iv, key_expansion, out2, tag);
        }
        auto time2 = std::chrono::high_resolution_clock::now();
        int dt = std::chrono::duration_cast<std::chrono::microseconds>(time2 - time1).count();
        printf("time = %d microseconds for %d iterations (%lf MB/s)\n", dt, n, double(n) * (nblocks * 16) / dt);
    }
    printbytes((char*)"cipher", out2, 16);
    printbytes((char*)"tag", tag, 16);
}

#endif // LOWSTAR

int main()
{
    printf("hello\n");

                // Calibrate frequency
                uint64_t startTime = GetRDTSC();
                Sleep(200);  // Sleep for 200ms
                uint64_t stopTime = GetRDTSC();

                cpuFreq = (stopTime - startTime) / (200 / 1000.0);

                printf("Measured CPU at %f GHz\n", cpuFreq/pow(10.0, 9));

#ifdef LOWSTAR
    test_lowstar();
#else // !LOWSTAR
    printf("\nBeginning 128-bit test...\n");
    test(aes128_key_expansion,
         gcm128_encrypt,
         gcm128_decrypt,
         10);

    printf("\nBeginning 256-bit test...\n");
    test(aes256_key_expansion,
         gcm256_encrypt,
         gcm256_decrypt,
         14);
#endif // LOWSTAR

    printf("goodbye\n");
    return 0;
}
<|endoftext|>