<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS 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
// COPYRIGHT HOLDER OR 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.
#include <unordered_map>
#include <Lex/Token.hh>

namespace Tadpole::Lex {

static constexpr const char* kNames[] = {
#undef TOKDEF
#define TOKDEF(k, s) s,
#include <Lex/KindsDef.hh>
#undef TOKDEF

  nullptr
};

static const std::unordered_map<str_t, TokenKind> kKWs = {
#undef KEYWORD
#define KEYWORD(k, s) {s, TokenKind::KW_##k},
#include <Lex/KindsDef.hh>
#undef KEYWORD
};

const char* get_kind_name(TokenKind kind) noexcept {
  return nullptr;
}

TokenKind get_keyword_kind(const str_t& key) noexcept {
  return TokenKind::TK_IDENTIFIER;
}

}
<commit_msg>:construction: chore(token): updated the implementation of token<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS 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
// COPYRIGHT HOLDER OR 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.
#include <unordered_map>
#include <Lex/Token.hh>

namespace Tadpole::Lex {

static constexpr const char* kNames[] = {
#undef TOKDEF
#define TOKDEF(k, s) s,
#include <Lex/KindsDef.hh>
#undef TOKDEF

  nullptr
};

static const std::unordered_map<str_t, TokenKind> kKWs = {
#undef KEYWORD
#define KEYWORD(k, s) {s, TokenKind::KW_##k},
#include <Lex/KindsDef.hh>
#undef KEYWORD
};

const char* get_kind_name(TokenKind kind) noexcept {
  if (kind > TokenKind::KINDS_BEG && kind < TokenKind::KINDS_END)
    return kNames[Common::as_type<int>(kind)];
  return nullptr;
}

TokenKind get_keyword_kind(const str_t& key) noexcept {
  if (auto it = kKWs.find(key); it != kKWs.end())
    return it->second;
  return TokenKind::TK_IDENTIFIER;
}

}
<|endoftext|>


<commit_before>// AliEmcalCorrectionComponent
//

#include "AliEmcalCorrectionComponent.h"

#include <TFile.h>
#include <TH1.h>

#include <AliAnalysisManager.h>
#include <AliVEvent.h>
#include <AliEMCALRecoUtils.h>
#include <AliOADBContainer.h>
#include "AliEmcalList.h"
#include "AliClusterContainer.h"
#include "AliTrackContainer.h"
#include "AliParticleContainer.h"
#include "AliMCParticleContainer.h"
#include "AliDataFile.h"

/// \cond CLASSIMP
ClassImp(AliEmcalCorrectionComponent);
/// \endcond

// Must create an instance of the map, since it is static
AliEmcalCorrectionComponentFactory::map_type * AliEmcalCorrectionComponentFactory::componentMap = new AliEmcalCorrectionComponentFactory::map_type;

/**
 * Default constructor
 */
AliEmcalCorrectionComponent::AliEmcalCorrectionComponent() :
  TNamed("AliEmcalCorrectionComponent", "AliEmcalCorrectionComponent"),
  fYAMLConfig(),
  fCreateHisto(kTRUE),
  fLoad1DBadChMap(kFALSE),
  fRun(-1),
  fFilepass(""),
  fGetPassFromFileName(kTRUE),
  fEventManager(),
  fEsdMode(0),
  fMCEvent(0),
  fCent(0),
  fNcentBins(4),
  fCentBin(0),
  fNbins(250),
  fMinBinPt(0),
  fMaxBinPt(250),
  fGeom(0),
  fMinMCLabel(0),
  fClusterCollArray(),
  fParticleCollArray(),
  fCaloCells(0),
  fRecoUtils(0),
  fOutput(0),
  fBasePath(""),
  fCustomBadChannelFilePath("")

{
  fVertex[0] = 0;
  fVertex[1] = 0;
  fVertex[2] = 0;
}

/**
 * Standard constructor
 */
AliEmcalCorrectionComponent::AliEmcalCorrectionComponent(const char * name) :
  TNamed(name, name),
  fYAMLConfig(),
  fCreateHisto(kTRUE),
  fLoad1DBadChMap(kFALSE),
  fRun(-1),
  fFilepass(""),
  fGetPassFromFileName(kTRUE),
  fEventManager(),
  fEsdMode(0),
  fMCEvent(0),
  fCent(0),
  fNcentBins(4),
  fCentBin(0),
  fNbins(250),
  fMinBinPt(0),
  fMaxBinPt(250),
  fGeom(0),
  fMinMCLabel(0),
  fClusterCollArray(),
  fParticleCollArray(),
  fCaloCells(0),
  fRecoUtils(0),
  fOutput(0),
  fBasePath(""),
  fCustomBadChannelFilePath("")
{
  fVertex[0] = 0;
  fVertex[1] = 0;
  fVertex[2] = 0;
}

/**
 * Destructor
 */
AliEmcalCorrectionComponent::~AliEmcalCorrectionComponent()
{
}

/**
 * Initialize basic variables in the correction component from the configuration file.
 */
Bool_t AliEmcalCorrectionComponent::Initialize()
{
  // Read in pass. If it is empty, set flag to automatically find the pass from the filename.
  std::string tempString = "";
  // Cannot use usual helper function because "pass" is not inside of a component, but rather at the top level.
  fYAMLConfig.GetProperty("pass", tempString, true);
  fFilepass = tempString.c_str();
  if (fFilepass != "") {
    fGetPassFromFileName = kFALSE;
    // Handle the "default" value used in MC
    if (fFilepass == "default" || fFilepass == "usedefault") {
      AliError("Received \"default\" as pass value. Defaulting to \"pass1\"! In the case of MC, the user should set the proper pass value in their configuration file! For data, empty quotes should be set so that the pass is automatically set.");
      fFilepass = "pass1";
    }
  }

  // Handle create histos, as this is universal for every component
  GetProperty("createHistos", fCreateHisto);

  return kTRUE;
}

/**
 * Create output objects for the analysis. Similar to UserCreateOutputObjects() in
 * AliAnalysisTaskSE
 */
void AliEmcalCorrectionComponent::UserCreateOutputObjects()
{
  // Setup Output
  fOutput = new AliEmcalList();
  fOutput->SetOwner();
}

/**
 * Execute once for the first event to initialize the analysis. Similar to ExecOnce() in
 * AliAnalysisTaskEmcal
 */
void AliEmcalCorrectionComponent::ExecOnce()
{
}

/**
 * Run every event, where the user implements their main analysis. Similar to Run() in
 * AliAnalysisTaskEmcal
 */
Bool_t AliEmcalCorrectionComponent::Run()
{
  AliDebugStream(3) << ": fEventManager.UseEmbeddingEvent(): " << fEventManager.UseEmbeddingEvent() << ", "
           << "fEventManager.InputEvent(): " << fEventManager.InputEvent() << ", "
           << "fEventManager address: " << &fEventManager << "\n";
  if(fGetPassFromFileName)
    GetPass();

  return kTRUE;
}

/**
 * Notifying the user that the input data file has
 * changed and performing steps needed to be done.
 */
Bool_t AliEmcalCorrectionComponent::UserNotify()
{
  return kTRUE;
}

/**
 * Calculate \f$\phi\f$ and \f$\eta\f$ difference between a track (t) and a cluster (c). The
 * position of the track is obtained on the EMCAL surface
 * @param[in] t Track to check
 * @param[in] v Cluster to check
 * @param[out] phidiff Distance in \f$\phi\f$ between cluster and track
 * @param[out] etadiff Distance in \f$\eta\f$ between cluster and track
 */
void AliEmcalCorrectionComponent::GetEtaPhiDiff(const AliVTrack *t, const AliVCluster *v, Double_t &phidiff, Double_t &etadiff)
{
  phidiff = 999;
  etadiff = 999;

  if (!t||!v) return;

  Double_t veta = t->GetTrackEtaOnEMCal();
  Double_t vphi = t->GetTrackPhiOnEMCal();

  Float_t pos[3] = {0};
  v->GetPosition(pos);
  TVector3 cpos(pos);
  Double_t ceta     = cpos.Eta();
  Double_t cphi     = cpos.Phi();
  etadiff=veta-ceta;
  phidiff=TVector2::Phi_mpi_pi(vphi-cphi);
}

/**
 * Remove bad cells from the cell list
 * Recalibrate energy and time cells
 */
void AliEmcalCorrectionComponent::UpdateCells()
{

  if (!fEventManager.InputEvent()) return ;

  Int_t bunchCrossNo = fEventManager.InputEvent()->GetBunchCrossNumber();

  if (fRecoUtils){
    //In case of PAR run check global event ID
    Short_t currentParIndex = 0;
    if(fRecoUtils->IsParRun()){
      ULong64_t globalEventID = (ULong64_t)bunchCrossNo + (ULong64_t)fEventManager.InputEvent()->GetOrbitNumber() * (ULong64_t)3564 + (ULong64_t)fEventManager.InputEvent()->GetPeriodNumber() * (ULong64_t)59793994260;
      for(Short_t ipar=0;ipar<fRecoUtils->GetNPars();ipar++){
	if(globalEventID >= fRecoUtils->GetGlobalIDPar(ipar)) {
	  currentParIndex++;
	}
      }
    }
    fRecoUtils->SetCurrentParNumber(currentParIndex);
    //end of PAR run settings

    fRecoUtils->RecalibrateCells(fCaloCells, bunchCrossNo);
  }
  fCaloCells->Sort();
}

/**
 * Check whether the run changed.
 */
Bool_t AliEmcalCorrectionComponent::CheckIfRunChanged()
{
  // Get run number.
  Bool_t runChanged = fRun != fEventManager.InputEvent()->GetRunNumber();

  if (runChanged) {
    fRun = fEventManager.InputEvent()->GetRunNumber();
    AliWarning(Form("Run changed, initializing parameters for %d", fRun));

    // init geometry if not already done
    fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(fRun);
    if (!fGeom)
    {
      AliFatal("Can not create geometry");
      return kFALSE;
    }
  }
  return runChanged;
}

/**
 * Get pass from filename. Sets pass in fFilepass.
 */
void AliEmcalCorrectionComponent::GetPass()
{
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  TTree *inputTree = mgr->GetTree();

  if (!inputTree)
  {
    AliError("Pointer to tree = 0, returning");
    return;
  }

  TFile *inputFile = inputTree->GetCurrentFile();
  if (!inputFile) {
    AliError("Null pointer input file, returning");
    return;
  }

  TString fname(inputFile->GetName());
  if      (fname.Contains("pass1_pidfix"))                fFilepass = TString("pass1_pidfix");
  else if (fname.Contains("pass3_lowIR_pidfix"))          fFilepass = TString("pass3_lowIR_pidfix");
  else if (fname.Contains("pass4_lowIR_pidfix_cookdedx")) fFilepass = TString("pass4_lowIR_pidfix_cookdedx");
  else if (fname.Contains("pass1")) fFilepass = TString("pass1");
  else if (fname.Contains("pass2")) fFilepass = TString("pass2");
  else if (fname.Contains("pass3")) fFilepass = TString("pass3");
  else if (fname.Contains("pass4")) fFilepass = TString("pass4");
  else if (fname.Contains("pass5")) fFilepass = TString("pass5");
  else if (fname.Contains("LHC11c") && fname.Contains("spc_calo")) fFilepass = TString("spc_calo");
  else if (fname.Contains("calo") || fname.Contains("high_lumi"))
  {
    Printf("%s: Path contains <calo> or <high-lumi>, set as <pass1>", GetName());
    fFilepass = TString("pass1");
  }
  else if (fname.Contains("LHC14a1a"))
  {
    AliInfo("Energy calibration activated for this MC production!");
    fFilepass = TString("LHC14a1a");
  }
  else
  {
    AliFatal(Form("Pass number string not found: %s. Please set the pass number in the configuration!", fname.Data()));
    return;
  }
}

/**
 * Fills the Cell QA histograms
 */
void AliEmcalCorrectionComponent::FillCellQA(TH1F* h){
  TString name = h->GetName();

  Short_t  absId  =-1;
  Double_t ecell = 0;
  Double_t tcell = 0;
  Double_t efrac = 0;
  Int_t  mclabel = -1;

  for (Int_t iCell = 0; iCell < fCaloCells->GetNumberOfCells(); iCell++){

    fCaloCells->GetCell(iCell, absId, ecell, tcell, mclabel, efrac);
    if(name.Contains("Energy")){
      h->Fill(ecell);
    }
    else if(name.Contains("Time")){
      h->Fill(tcell);
    }

  }

}

/**
 * Initialize the bad channel map.
 */
Int_t AliEmcalCorrectionComponent::InitBadChannels()
{
  if (!fEventManager.InputEvent())
    return 0;

  AliInfo("Initialising Bad channel map");

  // init default maps first
  if (!fRecoUtils->GetEMCALBadChannelStatusMapArray())
    fRecoUtils->InitEMCALBadChannelStatusMap() ;

  Int_t runBC = fEventManager.InputEvent()->GetRunNumber();

  std::unique_ptr<AliOADBContainer> contBC(nullptr);
  std::unique_ptr<TFile> fbad;
  if (fBasePath!="")
  { //if fBasePath specified in the ->SetBasePath()
    AliInfo(Form("Loading Bad Channels OADB from given path %s",fBasePath.Data()));

    fbad = std::unique_ptr<TFile>(TFile::Open(Form("%s/EMCALBadChannels%s.root",fBasePath.Data(), fLoad1DBadChMap ? "_1D" : ""),"read"));
    if (!fbad || fbad->IsZombie())
    {
      AliFatal(Form("EMCALBadChannels%s.root was not found in the path provided: %s", fLoad1DBadChMap ? "_1D" : "", fBasePath.Data()));
      return 0;
    }

    contBC = std::unique_ptr<AliOADBContainer>(static_cast<AliOADBContainer *>(fbad->Get("AliEMCALBadChannels")));
  }
  else if (fCustomBadChannelFilePath!="")
  { //if fCustomBadChannelFilePath specified in the configuration for custom bad channel maps
    AliInfo(Form("Loading custom Bad Channels OADB from given path %s",fCustomBadChannelFilePath.Data()));

    fbad = std::unique_ptr<TFile>(TFile::Open(Form("%s",fCustomBadChannelFilePath.Data()),"read"));
    if (!fbad || fbad->IsZombie())
    {
      AliFatal(Form("No valid Bad channel OADB object was not found in the path provided: %s",fCustomBadChannelFilePath.Data()));
      return 0;
    }

    contBC = std::unique_ptr<AliOADBContainer>(static_cast<AliOADBContainer *>(fbad->Get("AliEMCALBadChannels")));
  }
  else
  { // Else choose the one in the $ALICE_PHYSICS directory
    AliInfo("Loading Bad Channels OADB from $ALICE_PHYSICS/OADB/EMCAL");

    fbad = std::unique_ptr<TFile>(TFile::Open(AliDataFile::GetFileNameOADB(Form("EMCAL/EMCALBadChannels%s.root", fLoad1DBadChMap ? "_1D" : "")).data(),"read"));
    if (!fbad || fbad->IsZombie())
    {
      AliFatal(Form("OADB/EMCAL/EMCALBadChannels%s.root was not found", fLoad1DBadChMap ? "_1D" : ""));
      return 0;
    }

    contBC = std::unique_ptr<AliOADBContainer>(static_cast<AliOADBContainer *>(fbad->Get("AliEMCALBadChannels")));
  }
  if(!contBC){
    AliError("No OADB container found");
    return 0;
  }
  contBC->SetOwner(true);

  TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
  if (!arrayBC)
  {
    AliError(Form("No external hot channel set for run number: %d", runBC));
    return 2;
  }

  if(fLoad1DBadChMap){
    TH1C *h = fRecoUtils->GetEMCALChannelStatusMap1D();
    if (h)
      delete h;
    h=(TH1C*)arrayBC->FindObject("EMCALBadChannelMap");

    if (!h)
    {
      AliError("Can not get EMCALBadChannelMap");
    }
    h->SetDirectory(0);
    fRecoUtils->SetEMCALChannelStatusMap1D(h);
  }else{
    Int_t sms = fGeom->GetEMCGeometry()->GetNumberOfSuperModules();
    for (Int_t i=0; i<sms; ++i)
    {
      TH2I *h = fRecoUtils->GetEMCALChannelStatusMap(i);
      if (h)
        delete h;
      h=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i));

      if (!h)
      {
        AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
        continue;
      }
      h->SetDirectory(0);
      fRecoUtils->SetEMCALChannelStatusMap(i,h);
    }
  }

  return 1;
}

<commit_msg>Move the PARindex setting into an if condition statement<commit_after>// AliEmcalCorrectionComponent
//

#include "AliEmcalCorrectionComponent.h"

#include <TFile.h>
#include <TH1.h>

#include <AliAnalysisManager.h>
#include <AliVEvent.h>
#include <AliEMCALRecoUtils.h>
#include <AliOADBContainer.h>
#include "AliEmcalList.h"
#include "AliClusterContainer.h"
#include "AliTrackContainer.h"
#include "AliParticleContainer.h"
#include "AliMCParticleContainer.h"
#include "AliDataFile.h"

/// \cond CLASSIMP
ClassImp(AliEmcalCorrectionComponent);
/// \endcond

// Must create an instance of the map, since it is static
AliEmcalCorrectionComponentFactory::map_type * AliEmcalCorrectionComponentFactory::componentMap = new AliEmcalCorrectionComponentFactory::map_type;

/**
 * Default constructor
 */
AliEmcalCorrectionComponent::AliEmcalCorrectionComponent() :
  TNamed("AliEmcalCorrectionComponent", "AliEmcalCorrectionComponent"),
  fYAMLConfig(),
  fCreateHisto(kTRUE),
  fLoad1DBadChMap(kFALSE),
  fRun(-1),
  fFilepass(""),
  fGetPassFromFileName(kTRUE),
  fEventManager(),
  fEsdMode(0),
  fMCEvent(0),
  fCent(0),
  fNcentBins(4),
  fCentBin(0),
  fNbins(250),
  fMinBinPt(0),
  fMaxBinPt(250),
  fGeom(0),
  fMinMCLabel(0),
  fClusterCollArray(),
  fParticleCollArray(),
  fCaloCells(0),
  fRecoUtils(0),
  fOutput(0),
  fBasePath(""),
  fCustomBadChannelFilePath("")

{
  fVertex[0] = 0;
  fVertex[1] = 0;
  fVertex[2] = 0;
}

/**
 * Standard constructor
 */
AliEmcalCorrectionComponent::AliEmcalCorrectionComponent(const char * name) :
  TNamed(name, name),
  fYAMLConfig(),
  fCreateHisto(kTRUE),
  fLoad1DBadChMap(kFALSE),
  fRun(-1),
  fFilepass(""),
  fGetPassFromFileName(kTRUE),
  fEventManager(),
  fEsdMode(0),
  fMCEvent(0),
  fCent(0),
  fNcentBins(4),
  fCentBin(0),
  fNbins(250),
  fMinBinPt(0),
  fMaxBinPt(250),
  fGeom(0),
  fMinMCLabel(0),
  fClusterCollArray(),
  fParticleCollArray(),
  fCaloCells(0),
  fRecoUtils(0),
  fOutput(0),
  fBasePath(""),
  fCustomBadChannelFilePath("")
{
  fVertex[0] = 0;
  fVertex[1] = 0;
  fVertex[2] = 0;
}

/**
 * Destructor
 */
AliEmcalCorrectionComponent::~AliEmcalCorrectionComponent()
{
}

/**
 * Initialize basic variables in the correction component from the configuration file.
 */
Bool_t AliEmcalCorrectionComponent::Initialize()
{
  // Read in pass. If it is empty, set flag to automatically find the pass from the filename.
  std::string tempString = "";
  // Cannot use usual helper function because "pass" is not inside of a component, but rather at the top level.
  fYAMLConfig.GetProperty("pass", tempString, true);
  fFilepass = tempString.c_str();
  if (fFilepass != "") {
    fGetPassFromFileName = kFALSE;
    // Handle the "default" value used in MC
    if (fFilepass == "default" || fFilepass == "usedefault") {
      AliError("Received \"default\" as pass value. Defaulting to \"pass1\"! In the case of MC, the user should set the proper pass value in their configuration file! For data, empty quotes should be set so that the pass is automatically set.");
      fFilepass = "pass1";
    }
  }

  // Handle create histos, as this is universal for every component
  GetProperty("createHistos", fCreateHisto);

  return kTRUE;
}

/**
 * Create output objects for the analysis. Similar to UserCreateOutputObjects() in
 * AliAnalysisTaskSE
 */
void AliEmcalCorrectionComponent::UserCreateOutputObjects()
{
  // Setup Output
  fOutput = new AliEmcalList();
  fOutput->SetOwner();
}

/**
 * Execute once for the first event to initialize the analysis. Similar to ExecOnce() in
 * AliAnalysisTaskEmcal
 */
void AliEmcalCorrectionComponent::ExecOnce()
{
}

/**
 * Run every event, where the user implements their main analysis. Similar to Run() in
 * AliAnalysisTaskEmcal
 */
Bool_t AliEmcalCorrectionComponent::Run()
{
  AliDebugStream(3) << ": fEventManager.UseEmbeddingEvent(): " << fEventManager.UseEmbeddingEvent() << ", "
           << "fEventManager.InputEvent(): " << fEventManager.InputEvent() << ", "
           << "fEventManager address: " << &fEventManager << "\n";
  if(fGetPassFromFileName)
    GetPass();

  return kTRUE;
}

/**
 * Notifying the user that the input data file has
 * changed and performing steps needed to be done.
 */
Bool_t AliEmcalCorrectionComponent::UserNotify()
{
  return kTRUE;
}

/**
 * Calculate \f$\phi\f$ and \f$\eta\f$ difference between a track (t) and a cluster (c). The
 * position of the track is obtained on the EMCAL surface
 * @param[in] t Track to check
 * @param[in] v Cluster to check
 * @param[out] phidiff Distance in \f$\phi\f$ between cluster and track
 * @param[out] etadiff Distance in \f$\eta\f$ between cluster and track
 */
void AliEmcalCorrectionComponent::GetEtaPhiDiff(const AliVTrack *t, const AliVCluster *v, Double_t &phidiff, Double_t &etadiff)
{
  phidiff = 999;
  etadiff = 999;

  if (!t||!v) return;

  Double_t veta = t->GetTrackEtaOnEMCal();
  Double_t vphi = t->GetTrackPhiOnEMCal();

  Float_t pos[3] = {0};
  v->GetPosition(pos);
  TVector3 cpos(pos);
  Double_t ceta     = cpos.Eta();
  Double_t cphi     = cpos.Phi();
  etadiff=veta-ceta;
  phidiff=TVector2::Phi_mpi_pi(vphi-cphi);
}

/**
 * Remove bad cells from the cell list
 * Recalibrate energy and time cells
 */
void AliEmcalCorrectionComponent::UpdateCells()
{

  if (!fEventManager.InputEvent()) return ;

  Int_t bunchCrossNo = fEventManager.InputEvent()->GetBunchCrossNumber();

  if (fRecoUtils){
    //In case of PAR run check global event ID
    if(fRecoUtils->IsParRun()){
      Short_t currentParIndex = 0;
      ULong64_t globalEventID = (ULong64_t)bunchCrossNo + (ULong64_t)fEventManager.InputEvent()->GetOrbitNumber() * (ULong64_t)3564 + (ULong64_t)fEventManager.InputEvent()->GetPeriodNumber() * (ULong64_t)59793994260;
      for(Short_t ipar=0;ipar<fRecoUtils->GetNPars();ipar++){
	if(globalEventID >= fRecoUtils->GetGlobalIDPar(ipar)) {
	  currentParIndex++;
	}
      }
      fRecoUtils->SetCurrentParNumber(currentParIndex);
    }
    //end of PAR run settings

    fRecoUtils->RecalibrateCells(fCaloCells, bunchCrossNo);
  }
  fCaloCells->Sort();
}

/**
 * Check whether the run changed.
 */
Bool_t AliEmcalCorrectionComponent::CheckIfRunChanged()
{
  // Get run number.
  Bool_t runChanged = fRun != fEventManager.InputEvent()->GetRunNumber();

  if (runChanged) {
    fRun = fEventManager.InputEvent()->GetRunNumber();
    AliWarning(Form("Run changed, initializing parameters for %d", fRun));

    // init geometry if not already done
    fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(fRun);
    if (!fGeom)
    {
      AliFatal("Can not create geometry");
      return kFALSE;
    }
  }
  return runChanged;
}

/**
 * Get pass from filename. Sets pass in fFilepass.
 */
void AliEmcalCorrectionComponent::GetPass()
{
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  TTree *inputTree = mgr->GetTree();

  if (!inputTree)
  {
    AliError("Pointer to tree = 0, returning");
    return;
  }

  TFile *inputFile = inputTree->GetCurrentFile();
  if (!inputFile) {
    AliError("Null pointer input file, returning");
    return;
  }

  TString fname(inputFile->GetName());
  if      (fname.Contains("pass1_pidfix"))                fFilepass = TString("pass1_pidfix");
  else if (fname.Contains("pass3_lowIR_pidfix"))          fFilepass = TString("pass3_lowIR_pidfix");
  else if (fname.Contains("pass4_lowIR_pidfix_cookdedx")) fFilepass = TString("pass4_lowIR_pidfix_cookdedx");
  else if (fname.Contains("pass1")) fFilepass = TString("pass1");
  else if (fname.Contains("pass2")) fFilepass = TString("pass2");
  else if (fname.Contains("pass3")) fFilepass = TString("pass3");
  else if (fname.Contains("pass4")) fFilepass = TString("pass4");
  else if (fname.Contains("pass5")) fFilepass = TString("pass5");
  else if (fname.Contains("LHC11c") && fname.Contains("spc_calo")) fFilepass = TString("spc_calo");
  else if (fname.Contains("calo") || fname.Contains("high_lumi"))
  {
    Printf("%s: Path contains <calo> or <high-lumi>, set as <pass1>", GetName());
    fFilepass = TString("pass1");
  }
  else if (fname.Contains("LHC14a1a"))
  {
    AliInfo("Energy calibration activated for this MC production!");
    fFilepass = TString("LHC14a1a");
  }
  else
  {
    AliFatal(Form("Pass number string not found: %s. Please set the pass number in the configuration!", fname.Data()));
    return;
  }
}

/**
 * Fills the Cell QA histograms
 */
void AliEmcalCorrectionComponent::FillCellQA(TH1F* h){
  TString name = h->GetName();

  Short_t  absId  =-1;
  Double_t ecell = 0;
  Double_t tcell = 0;
  Double_t efrac = 0;
  Int_t  mclabel = -1;

  for (Int_t iCell = 0; iCell < fCaloCells->GetNumberOfCells(); iCell++){

    fCaloCells->GetCell(iCell, absId, ecell, tcell, mclabel, efrac);
    if(name.Contains("Energy")){
      h->Fill(ecell);
    }
    else if(name.Contains("Time")){
      h->Fill(tcell);
    }

  }

}

/**
 * Initialize the bad channel map.
 */
Int_t AliEmcalCorrectionComponent::InitBadChannels()
{
  if (!fEventManager.InputEvent())
    return 0;

  AliInfo("Initialising Bad channel map");

  // init default maps first
  if (!fRecoUtils->GetEMCALBadChannelStatusMapArray())
    fRecoUtils->InitEMCALBadChannelStatusMap() ;

  Int_t runBC = fEventManager.InputEvent()->GetRunNumber();

  std::unique_ptr<AliOADBContainer> contBC(nullptr);
  std::unique_ptr<TFile> fbad;
  if (fBasePath!="")
  { //if fBasePath specified in the ->SetBasePath()
    AliInfo(Form("Loading Bad Channels OADB from given path %s",fBasePath.Data()));

    fbad = std::unique_ptr<TFile>(TFile::Open(Form("%s/EMCALBadChannels%s.root",fBasePath.Data(), fLoad1DBadChMap ? "_1D" : ""),"read"));
    if (!fbad || fbad->IsZombie())
    {
      AliFatal(Form("EMCALBadChannels%s.root was not found in the path provided: %s", fLoad1DBadChMap ? "_1D" : "", fBasePath.Data()));
      return 0;
    }

    contBC = std::unique_ptr<AliOADBContainer>(static_cast<AliOADBContainer *>(fbad->Get("AliEMCALBadChannels")));
  }
  else if (fCustomBadChannelFilePath!="")
  { //if fCustomBadChannelFilePath specified in the configuration for custom bad channel maps
    AliInfo(Form("Loading custom Bad Channels OADB from given path %s",fCustomBadChannelFilePath.Data()));

    fbad = std::unique_ptr<TFile>(TFile::Open(Form("%s",fCustomBadChannelFilePath.Data()),"read"));
    if (!fbad || fbad->IsZombie())
    {
      AliFatal(Form("No valid Bad channel OADB object was not found in the path provided: %s",fCustomBadChannelFilePath.Data()));
      return 0;
    }

    contBC = std::unique_ptr<AliOADBContainer>(static_cast<AliOADBContainer *>(fbad->Get("AliEMCALBadChannels")));
  }
  else
  { // Else choose the one in the $ALICE_PHYSICS directory
    AliInfo("Loading Bad Channels OADB from $ALICE_PHYSICS/OADB/EMCAL");

    fbad = std::unique_ptr<TFile>(TFile::Open(AliDataFile::GetFileNameOADB(Form("EMCAL/EMCALBadChannels%s.root", fLoad1DBadChMap ? "_1D" : "")).data(),"read"));
    if (!fbad || fbad->IsZombie())
    {
      AliFatal(Form("OADB/EMCAL/EMCALBadChannels%s.root was not found", fLoad1DBadChMap ? "_1D" : ""));
      return 0;
    }

    contBC = std::unique_ptr<AliOADBContainer>(static_cast<AliOADBContainer *>(fbad->Get("AliEMCALBadChannels")));
  }
  if(!contBC){
    AliError("No OADB container found");
    return 0;
  }
  contBC->SetOwner(true);

  TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
  if (!arrayBC)
  {
    AliError(Form("No external hot channel set for run number: %d", runBC));
    return 2;
  }

  if(fLoad1DBadChMap){
    TH1C *h = fRecoUtils->GetEMCALChannelStatusMap1D();
    if (h)
      delete h;
    h=(TH1C*)arrayBC->FindObject("EMCALBadChannelMap");

    if (!h)
    {
      AliError("Can not get EMCALBadChannelMap");
    }
    h->SetDirectory(0);
    fRecoUtils->SetEMCALChannelStatusMap1D(h);
  }else{
    Int_t sms = fGeom->GetEMCGeometry()->GetNumberOfSuperModules();
    for (Int_t i=0; i<sms; ++i)
    {
      TH2I *h = fRecoUtils->GetEMCALChannelStatusMap(i);
      if (h)
        delete h;
      h=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i));

      if (!h)
      {
        AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
        continue;
      }
      h->SetDirectory(0);
      fRecoUtils->SetEMCALChannelStatusMap(i,h);
    }
  }

  return 1;
}

<|endoftext|>


<commit_before>/****************************************************
 * This is a test that will test condition variables*
 ****************************************************/

#include <iostream>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include "capi.h"
#include "mcp_api.h"
#include "sync_api.h"

using namespace std;

carbon_mutex_t my_mux;
carbon_cond_t my_cond;

#ifdef DEBUG
   pthread_mutex_t lock;
#endif

// Functions executed by threads
void* test_wait_cond(void * threadid);
void* test_broadcast_cond(void * threadid);

int main(int argc, char* argv[]){ // main begins

   initMCP();

   // Read in the command line arguments
   const unsigned int numThreads = 5;

   // Declare threads and related variables
   pthread_t threads[numThreads];
   pthread_attr_t attr;

#ifdef DEBUG
   cout << "This is the function main()" << endl;
#endif

   // Initialize threads and related variables
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

#ifdef DEBUG
   cout << "Spawning threads" << endl;
#endif

   for (int i = 0; i < numThreads - 1; i++)
     pthread_create(&threads[i], &attr, test_wait_cond, (void *) i);
   pthread_create(&threads[numThreads-1], &attr, test_broadcast_cond, (void *) NULL);

   // Wait for all threads to complete
   for(unsigned int i = 0; i < numThreads; i++)
      pthread_join(threads[i], NULL);

   cout << "quitting syscall server!" << endl;
   quitMCP();

#ifdef DEBUG
   cout << "This is the function main ending" << endl;
#endif
   pthread_exit(NULL);

} // main ends

void* test_broadcast_cond(void *threadid)
{
   usleep(500000);
  // Declare local variables
  int tid;
  CAPI_return_t rtnVal;

  rtnVal = CAPI_Initialize(&tid);

  // Initialize local variables
  CAPI_rank(&tid);

  // Thread starts here
  cerr << "UserBroadcast: Cond broadcasting." << endl;
  condBroadcast(&my_cond);
  cerr << "UserBroadcast: Cond broadcasted." << endl;
  mutexLock(&my_mux);
  cerr << "UserBroadcast: Mutex locked after broadcast." << endl;
  mutexUnlock(&my_mux);
  cerr << "UserBroadcast: Broadcast thread done." << endl;

  pthread_exit(NULL);
}

void* test_wait_cond(void *threadid)
{
  // Declare local variables
  int tid;
  CAPI_return_t rtnVal;

  rtnVal = CAPI_Initialize(&tid);

  // Initialize local variables
  CAPI_rank(&tid);

  // Thread starts here

  // FIXME: This should be in the main thread or something.
  if ((int)threadid == 0)
    {
      cerr << "UserWait: Initting mutex." << endl;
      mutexInit(&my_mux);
      cerr << "UserWait: Initting cond." << endl;
      condInit(&my_cond);
    }

  sleep(1);

  cerr << "UserWait: Locking mux." << endl;
  mutexLock(&my_mux);
  cerr << "UserWait: Cond wait." << endl;
  condWait(&my_cond, &my_mux);
  cerr << "UserWait: Cond done." << endl;

  mutexUnlock(&my_mux);
  cerr << "UserWait: test_wait_cond mutex unlock done." << endl;

  pthread_exit(NULL);
}

<commit_msg>[sync] Update broadcast test.<commit_after>/****************************************************
 * This is a test that will test condition variables*
 ****************************************************/

#include <iostream>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include "capi.h"
#include "mcp_api.h"
#include "sync_api.h"
#include <stdio.h>

using namespace std;

carbon_mutex_t my_mux;
carbon_cond_t my_cond;

#ifdef DEBUG
   pthread_mutex_t lock;
#endif

// Functions executed by threads
void* test_wait_cond(void * threadid);
void* test_broadcast_cond(void * threadid);

int main(int argc, char* argv[]){ // main begins

   initMCP();

   // Read in the command line arguments
   const unsigned int numThreads = 5;

   // Declare threads and related variables
   pthread_t threads[numThreads];
   pthread_attr_t attr;

#ifdef DEBUG
   cout << "This is the function main()" << endl;
#endif

   // Initialize threads and related variables
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

#ifdef DEBUG
   cout << "Spawning threads" << endl;
#endif

   for (int i = 0; i < numThreads - 1; i++)
     pthread_create(&threads[i], &attr, test_wait_cond, (void *) i);
   pthread_create(&threads[numThreads-1], &attr, test_broadcast_cond, (void *) NULL);

   // Wait for all threads to complete
   for(unsigned int i = 0; i < numThreads; i++)
      pthread_join(threads[i], NULL);

   cout << "quitting syscall server!" << endl;
   quitMCP();

#ifdef DEBUG
   cout << "This is the function main ending" << endl;
#endif
   pthread_exit(NULL);

} // main ends

void* test_broadcast_cond(void *threadid)
{
  sleep(3);
  // Declare local variables
  int tid;
  CAPI_return_t rtnVal;

  rtnVal = CAPI_Initialize(&tid);

  // Initialize local variables
  CAPI_rank(&tid);

  // Thread starts here
  fprintf(stderr, "UserBroadcast: Cond broadcasting.\n");
  condBroadcast(&my_cond);
  fprintf(stderr, "UserBroadcast: Cond broadcasted.\n");
  mutexLock(&my_mux);
  fprintf(stderr, "UserBroadcast: Mutex locked after broadcast.\n");
  mutexUnlock(&my_mux);
  fprintf(stderr, "UserBroadcast: Broadcast thread done.\n");

  pthread_exit(NULL);
}

void* test_wait_cond(void *threadid)
{
  // Declare local variables
  int tid;
  CAPI_return_t rtnVal;

  rtnVal = CAPI_Initialize(&tid);

  // Initialize local variables
  CAPI_rank(&tid);

  // Thread starts here

  // FIXME: This should be in the main thread or something.
  if ((int)threadid == 0)
    {
      fprintf(stderr, "UserWait: Initting mutex.\n");
      mutexInit(&my_mux);
      fprintf(stderr, "UserWait: Initting cond.\n");
      condInit(&my_cond);
    }

  sleep(1);

  fprintf(stderr, "UserWait: Locking mux.\n");
  mutexLock(&my_mux);
  fprintf(stderr, "UserWait: Cond wait.\n");
  condWait(&my_cond, &my_mux);
  fprintf(stderr, "UserWait: Cond done.\n");

  mutexUnlock(&my_mux);
  fprintf(stderr, "UserWait: test_wait_cond mutex unlock done.\n");

  pthread_exit(NULL);
}

<|endoftext|>


<commit_before>#include <csignal>

#include "util.hpp"
#include "tls-epoll-server.hpp"

/**
 * /implements EpollServer
 *
 * @brief This class has the same characteristics of EpollServer, yet uses OpenSSL private-public key encryption.
 *
 * @param certificate The path to the certificate chain file needed by OpenSSL.
 * @param private_key The path to the private key file needed by OpenSSL.
 * @param port See EpollServer::EpollServer.
 * @param max_connections See EpollServer::EpollServer.
 *
 * Disables OpenSSL SSLv3.
 * Users the cipher list: "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS"
 */
TlsEpollServer::TlsEpollServer(std::string certificate, std::string private_key, uint16_t port, size_t max_connections, std::string name)
:EpollServer(port, max_connections, name){
	SSL_library_init();
	SSL_load_error_strings();

	if((this->ctx = SSL_CTX_new(SSLv23_server_method())) == 0){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_new");
	}

	if(SSL_CTX_set_ecdh_auto(this->ctx, 1) == 0){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_set_ecdh_auto");
	}

	if(SSL_CTX_use_certificate_chain_file(this->ctx, certificate.c_str()) != 1){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_use_certificate_file");
	}

	if(SSL_CTX_use_PrivateKey_file(this->ctx, private_key.c_str(), SSL_FILETYPE_PEM) != 1){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_use_PrivateKey_file");
	}

	std::signal(SIGPIPE, SIG_IGN);

	// Hell yeah, use ECDH.
	if(!SSL_CTX_set_ecdh_auto(this->ctx, 1)){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_set_ecdh_auto");
	}

	// SSLv3 is insecure via poodles.
	SSL_CTX_set_options(this->ctx, SSL_OP_NO_SSLv3);

	// "Good" cipher list from the interweb.
	if(!SSL_CTX_set_cipher_list(this->ctx, "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS")){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_set_cipher_list");
	}

//	PRINT("SSL Mode: " << SSL_CTX_set_mode(this->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE))
}

/**
 * @brief Does an SSL_free before closing the socket.
 *
 * See EpollServer::close_client
 */
void TlsEpollServer::close_client(int* fd, std::function<void(int*)> callback){
	PRINT("SSL_free'd " << *fd)
	SSL_free(this->client_ssl[*fd]);
	callback(fd);
}

/**
 * @brief Uses SSL_write instead of a regular write.
 *
 * See EpollServer::send
 */
bool TlsEpollServer::send(int fd, const char* data, size_t data_length){
	int len = 0, err = SSL_ERROR_WANT_WRITE, count = 0;
	//TODO: A malicious SSL client could continously request the same bytes (keep ACKing received bytes).
	while(err == SSL_ERROR_WANT_WRITE){
		len = SSL_write(this->client_ssl[fd], data, static_cast<int>(data_length));
		err = SSL_get_error(this->client_ssl[fd], len);
		count++;
	}
	if(err != SSL_ERROR_NONE){
		ERROR("SSL_write: " << err)
		return true;
	}
	if(count != 1){
		PRINT("SSL_write: " << count)
	}
	if(len != static_cast<int>(data_length)){
		ERROR("Invalid number of bytes written...")
	}
	this->write_counter[fd]++;
	return false;
}

ssize_t TlsEpollServer::recv(int fd, char* data, size_t data_length){
	return this->recv(fd, data, data_length, this->on_read);
}

/**
 * @brief This is useful for HTTPS multi-part requests.
 * Google chrome requires this funtionality to piece together POST headers and body.
 *
 * See EpollServer::recv
 */
ssize_t TlsEpollServer::recv(int fd, char* data, size_t data_length,
std::function<ssize_t(int, char*, size_t)> callback){
	int len = SSL_read(this->client_ssl[fd], data, static_cast<int>(data_length));
	int err = SSL_get_error(this->client_ssl[fd], len);
	switch(err){
	case SSL_ERROR_NONE:
		break;
	case SSL_ERROR_WANT_READ:
		PRINT("WANT READ" << fd)
		// Nothing to read, nonblocking mode.
		return 0;
	case SSL_ERROR_ZERO_RETURN:
		ERROR("server read zero " << fd)
		return -2;
	case SSL_ERROR_SYSCALL:
		perror("SSL_ERROR_SYSCALL");
		ERR_print_errors_fp(stdout);
		return -3;
	default:
		ERROR("other SSL_read " << err << " from " << fd)
		ERR_print_errors_fp(stdout);
		return -1;
	}
	data[len] = 0;
	return callback(fd, data, static_cast<size_t>(len));
}

/**
 * @brief Importantly implements @see EpollServer::accept_continuation.
 *
 * See EpollServer::accept_continuation
 *
 * Completed the SSL handshake as defined by the SSL context.
 * If the SSL handshake fails, the the client did *not* successfully connect and is dumped.
 */
bool TlsEpollServer::accept_continuation(int* new_client_fd){
	if((this->client_ssl[*new_client_fd] = SSL_new(this->ctx)) == 0){
		ERROR("SSL_new " << *new_client_fd)
		ERR_print_errors_fp(stdout);
		return true;
	}

	SSL_set_fd(this->client_ssl[*new_client_fd], *new_client_fd);

//	SSL_accept fails if socket is non_blocking.
	if(SSL_accept(this->client_ssl[*new_client_fd]) <= 0){
		ERROR("SSL_accept " << *new_client_fd)
		ERR_print_errors_fp(stdout);
		return true;
	}

	return false;
}

/// Simply cleans up the OpenSSL context.
TlsEpollServer::~TlsEpollServer(){
	SSL_CTX_free(this->ctx);
	EVP_cleanup();
}
<commit_msg>Resolved a TODO with a quick timeout. Should not change code flow in production. I actually experienced the bug for the first time yesterday with a broken pipe on the client side.<commit_after>#include <csignal>

#include "util.hpp"
#include "tls-epoll-server.hpp"

/**
 * /implements EpollServer
 *
 * @brief This class has the same characteristics of EpollServer, yet uses OpenSSL private-public key encryption.
 *
 * @param certificate The path to the certificate chain file needed by OpenSSL.
 * @param private_key The path to the private key file needed by OpenSSL.
 * @param port See EpollServer::EpollServer.
 * @param max_connections See EpollServer::EpollServer.
 *
 * Disables OpenSSL SSLv3.
 * Users the cipher list: "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS"
 */
TlsEpollServer::TlsEpollServer(std::string certificate, std::string private_key, uint16_t port, size_t max_connections, std::string name)
:EpollServer(port, max_connections, name){
	SSL_library_init();
	SSL_load_error_strings();

	if((this->ctx = SSL_CTX_new(SSLv23_server_method())) == 0){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_new");
	}

	if(SSL_CTX_set_ecdh_auto(this->ctx, 1) == 0){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_set_ecdh_auto");
	}

	if(SSL_CTX_use_certificate_chain_file(this->ctx, certificate.c_str()) != 1){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_use_certificate_file");
	}

	if(SSL_CTX_use_PrivateKey_file(this->ctx, private_key.c_str(), SSL_FILETYPE_PEM) != 1){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_use_PrivateKey_file");
	}

	std::signal(SIGPIPE, SIG_IGN);

	// Hell yeah, use ECDH.
	if(!SSL_CTX_set_ecdh_auto(this->ctx, 1)){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_set_ecdh_auto");
	}

	// SSLv3 is insecure via poodles.
	SSL_CTX_set_options(this->ctx, SSL_OP_NO_SSLv3);

	// "Good" cipher list from the interweb.
	if(!SSL_CTX_set_cipher_list(this->ctx, "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS")){
		ERR_print_errors_fp(stdout);
		throw std::runtime_error(this->name + "SSL_CTX_set_cipher_list");
	}

//	PRINT("SSL Mode: " << SSL_CTX_set_mode(this->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE))
}

/**
 * @brief Does an SSL_free before closing the socket.
 *
 * See EpollServer::close_client
 */
void TlsEpollServer::close_client(int* fd, std::function<void(int*)> callback){
	PRINT("SSL_free'd " << *fd)
	SSL_free(this->client_ssl[*fd]);
	callback(fd);
}

/**
 * @brief Uses SSL_write instead of a regular write.
 *
 * See EpollServer::send
 */
bool TlsEpollServer::send(int fd, const char* data, size_t data_length){
	int len = 0, err = SSL_ERROR_WANT_WRITE;
	std::chrono::milliseconds send_start = std::chrono::duration_cast<std::chrono::milliseconds>(
		std::chrono::system_clock::now().time_since_epoch());
	std::chrono::milliseconds diff = std::chrono::milliseconds(0);
	std::chrono::milliseconds timeout = std::chrono::milliseconds(10000);

	while(err == SSL_ERROR_WANT_WRITE){
		if(diff > timeout){
			PRINT("SSL_write timeout...")
			return true;
		}

		len = SSL_write(this->client_ssl[fd], data, static_cast<int>(data_length));
		err = SSL_get_error(this->client_ssl[fd], len);

		diff = std::chrono::duration_cast<std::chrono::milliseconds>(
			std::chrono::system_clock::now().time_since_epoch()) - send_start;
	}
	if(err != SSL_ERROR_NONE){
		ERROR("SSL_write: " << err)
		return true;
	}
	DEBUG("SSL_write took milliseconds: " << diff.count())
	if(len != static_cast<int>(data_length)){
		ERROR("Invalid number of bytes written...")
	}
	this->write_counter[fd]++;
	return false;
}

ssize_t TlsEpollServer::recv(int fd, char* data, size_t data_length){
	return this->recv(fd, data, data_length, this->on_read);
}

/**
 * @brief This is useful for HTTPS multi-part requests.
 * Google chrome requires this funtionality to piece together POST headers and body.
 *
 * See EpollServer::recv
 */
ssize_t TlsEpollServer::recv(int fd, char* data, size_t data_length,
std::function<ssize_t(int, char*, size_t)> callback){
	int len = SSL_read(this->client_ssl[fd], data, static_cast<int>(data_length));
	int err = SSL_get_error(this->client_ssl[fd], len);
	switch(err){
	case SSL_ERROR_NONE:
		break;
	case SSL_ERROR_WANT_READ:
		PRINT("WANT READ" << fd)
		// Nothing to read, nonblocking mode.
		return 0;
	case SSL_ERROR_ZERO_RETURN:
		ERROR("server read zero " << fd)
		return -2;
	case SSL_ERROR_SYSCALL:
		perror("SSL_ERROR_SYSCALL");
		ERR_print_errors_fp(stdout);
		return -3;
	default:
		ERROR("other SSL_read " << err << " from " << fd)
		ERR_print_errors_fp(stdout);
		return -1;
	}
	data[len] = 0;
	return callback(fd, data, static_cast<size_t>(len));
}

/**
 * @brief Importantly implements @see EpollServer::accept_continuation.
 *
 * See EpollServer::accept_continuation
 *
 * Completed the SSL handshake as defined by the SSL context.
 * If the SSL handshake fails, the the client did *not* successfully connect and is dumped.
 */
bool TlsEpollServer::accept_continuation(int* new_client_fd){
	if((this->client_ssl[*new_client_fd] = SSL_new(this->ctx)) == 0){
		ERROR("SSL_new " << *new_client_fd)
		ERR_print_errors_fp(stdout);
		return true;
	}

	SSL_set_fd(this->client_ssl[*new_client_fd], *new_client_fd);

//	SSL_accept fails if socket is non_blocking.
	if(SSL_accept(this->client_ssl[*new_client_fd]) <= 0){
		ERROR("SSL_accept " << *new_client_fd)
		ERR_print_errors_fp(stdout);
		return true;
	}

	return false;
}

/// Simply cleans up the OpenSSL context.
TlsEpollServer::~TlsEpollServer(){
	SSL_CTX_free(this->ctx);
	EVP_cleanup();
}
<|endoftext|>


<commit_before>/***************************************************************************
            adash@cern.ch - last modified on 05/09/2016
//
// General macro to configure the RSN analysis task.
// It calls all configs desired by the user, by means
// of the boolean switches defined in the first lines.
// ---
// Inputs:
//  1) flag to know if running on MC or data
//  2) path where all configs are stored
// ---
// Returns:
//  kTRUE  --> initialization successful
//  kFALSE --> initialization failed (some config gave errors)
//
****************************************************************************/

AliRsnMiniAnalysisTask * AddTaskKStarPbPbRunII(
						Bool_t      isMC                = kFALSE,
						Bool_t      isPP                = kFALSE,
						Int_t       Strcut              = 2011,
						Int_t       customQualityCutsID = AliRsnCutSetDaughterParticle::kDisableCustom,
						AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutKaCandidate=AliRsnCutSetDaughterParticle::kTPCpidTOFveto3s,
						Float_t     nsigmaPi            = 2.0,
						Float_t     nsigmaK             = 2.0,
						Bool_t      enableMonitor       = kTRUE,
						Int_t       nmix                = 5,
						Float_t     maxDiffVzMix        = 1.0,
						Float_t     maxDiffMultMix      = 5.0,
						TString     outNameSuffix       = "PbPb"
						)
{
  Bool_t      rejectPileUp = kTRUE;
  //if(!isPP || isMC) rejectPileUp = kFALSE;

  //
  // -- INITIALIZATION ----------------------------------------------------------------------------
  // retrieve analysis manager
  //
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
      ::Error("AddTaskKStarPbPbRunTwo", "No analysis manager to connect to.");
      return NULL;
   }

   // create the task and configure
   TString taskName = Form("KStar%s%s", (isPP? "pp" : "PbPb"), (isMC ? "MC" : "Data"));

   AliRsnMiniAnalysisTask *task = new AliRsnMiniAnalysisTask(taskName.Data(), isMC);
   task->UseESDTriggerMask(AliVEvent::kINT7);
   if (isPP)
     task->UseMultiplicity("QUALITY");
   else
     task->UseMultiplicity("AliMultSelection_V0M");//Only for RunII
   // set event mixing options
   task->UseContinuousMix();
   //task->UseBinnedMix();
   task->SetNMix(nmix);
   task->SetMaxDiffVz(maxDiffVzMix);
   task->SetMaxDiffMult(maxDiffMultMix);
   task->UseMC(isMC);
   ::Info("AddTaskKStarPbPbRunTwo", Form("Event mixing configuration: \n events to mix = %i \n max diff. vtxZ = cm %5.3f \n max diff multi = %5.3f \n", nmix, maxDiffVzMix, maxDiffMultMix));

   mgr->AddTask(task);

   AliRsnCutEventUtils* cutEventUtils=new AliRsnCutEventUtils("cutEventUtils",kTRUE,rejectPileUp);
   cutEventUtils->SetCheckAcceptedMultSelection();
   AliRsnCutSet *eventCuts = new AliRsnCutSet("eventCuts", AliRsnTarget::kEvent);
   eventCuts->AddCut(cutEventUtils);
   eventCuts->SetCutScheme(Form("%s",cutEventUtils->GetName()));
   task->SetEventCuts(eventCuts);

   //
   // -- EVENT-ONLY COMPUTATIONS -------------------------------------------------------------------
   //
   //vertex
   Int_t vtxID = task->CreateValue(AliRsnMiniValue::kVz, kFALSE);
   AliRsnMiniOutput *outVtx = task->CreateOutput("eventVtx", "HIST", "EVENT");
   outVtx->AddAxis(vtxID, 400, -20.0, 20.0);

   //multiplicity or centrality
   Int_t multID = task->CreateValue(AliRsnMiniValue::kMult, kFALSE);
   AliRsnMiniOutput *outMult = task->CreateOutput("eventMult", "HIST", "EVENT");
   if (isPP)
     outMult->AddAxis(multID, 400, 0.0, 400.0);
   else
     outMult->AddAxis(multID, 100, 0.0, 100.0);

   //
   // -- PAIR CUTS (common to all resonances) ------------------------------------------------------
   //
   AliRsnCutMiniPair *cutY = new AliRsnCutMiniPair("cutRapidity", AliRsnCutMiniPair::kRapidityRange);
   cutY->SetRangeD(-0.5, 0.5);
   AliRsnCutSet *cutsPair = new AliRsnCutSet("pairCuts", AliRsnTarget::kMother);
   cutsPair->AddCut(cutY);
   cutsPair->SetCutScheme(cutY->GetName());

   //
   // -- CONFIG ANALYSIS --------------------------------------------------------------------------
   //
   //gROOT->LoadMacro("$ALICE_PHYSICS/PWGLF/RESONANCES/macros/mini/ConfigKStarPbPbRunII.C");
   gROOT->LoadMacro("ConfigKStarPbPbRunII.C");
   if (!ConfigKStarPbPbRunII(task, isMC, isPP, cutsPair,Strcut, customQualityCutsID,cutKaCandidate,nsigmaPi,nsigmaK, enableMonitor)) return 0x0;

   //
   // -- CONTAINERS --------------------------------------------------------------------------------
   //
   TString outputFileName = AliAnalysisManager::GetCommonFileName();
   //outputFileName += ":Rsn";
   Printf("AddTaskKStarPbPbRunTwo - Set OutputFileName : \n %s\n", outputFileName.Data() );

   AliAnalysisDataContainer *output = mgr->CreateContainer(Form("RsnOut_%s",outNameSuffix.Data()),
							   TList::Class(),
							   AliAnalysisManager::kOutputContainer,
							   outputFileName);
   mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput(task, 1, output);

   return task;
}
<commit_msg>Change the directory of LoadMacro for K*0 analysis in Pb-Pb (Run2)<commit_after>/***************************************************************************
            adash@cern.ch - last modified on 05/09/2016
//
// General macro to configure the RSN analysis task.
// It calls all configs desired by the user, by means
// of the boolean switches defined in the first lines.
// ---
// Inputs:
//  1) flag to know if running on MC or data
//  2) path where all configs are stored
// ---
// Returns:
//  kTRUE  --> initialization successful
//  kFALSE --> initialization failed (some config gave errors)
//
****************************************************************************/

AliRsnMiniAnalysisTask * AddTaskKStarPbPbRunII(
						Bool_t      isMC                = kFALSE,
						Bool_t      isPP                = kFALSE,
						Int_t       Strcut              = 2011,
						Int_t       customQualityCutsID = AliRsnCutSetDaughterParticle::kDisableCustom,
						AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutKaCandidate=AliRsnCutSetDaughterParticle::kTPCpidTOFveto3s,
						Float_t     nsigmaPi            = 2.0,
						Float_t     nsigmaK             = 2.0,
						Bool_t      enableMonitor       = kTRUE,
						Int_t       nmix                = 5,
						Float_t     maxDiffVzMix        = 1.0,
						Float_t     maxDiffMultMix      = 5.0,
						TString     outNameSuffix       = "PbPb"
						)
{
  Bool_t      rejectPileUp = kTRUE;
  //if(!isPP || isMC) rejectPileUp = kFALSE;

  //
  // -- INITIALIZATION ----------------------------------------------------------------------------
  // retrieve analysis manager
  //
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
      ::Error("AddTaskKStarPbPbRunTwo", "No analysis manager to connect to.");
      return NULL;
   }

   // create the task and configure
   TString taskName = Form("KStar%s%s", (isPP? "pp" : "PbPb"), (isMC ? "MC" : "Data"));

   AliRsnMiniAnalysisTask *task = new AliRsnMiniAnalysisTask(taskName.Data(), isMC);
   task->UseESDTriggerMask(AliVEvent::kINT7);
   if (isPP)
     task->UseMultiplicity("QUALITY");
   else
     task->UseMultiplicity("AliMultSelection_V0M");//Only for RunII
   // set event mixing options
   task->UseContinuousMix();
   //task->UseBinnedMix();
   task->SetNMix(nmix);
   task->SetMaxDiffVz(maxDiffVzMix);
   task->SetMaxDiffMult(maxDiffMultMix);
   task->UseMC(isMC);
   ::Info("AddTaskKStarPbPbRunTwo", Form("Event mixing configuration: \n events to mix = %i \n max diff. vtxZ = cm %5.3f \n max diff multi = %5.3f \n", nmix, maxDiffVzMix, maxDiffMultMix));

   mgr->AddTask(task);

   AliRsnCutEventUtils* cutEventUtils=new AliRsnCutEventUtils("cutEventUtils",kTRUE,rejectPileUp);
   cutEventUtils->SetCheckAcceptedMultSelection();
   AliRsnCutSet *eventCuts = new AliRsnCutSet("eventCuts", AliRsnTarget::kEvent);
   eventCuts->AddCut(cutEventUtils);
   eventCuts->SetCutScheme(Form("%s",cutEventUtils->GetName()));
   task->SetEventCuts(eventCuts);

   //
   // -- EVENT-ONLY COMPUTATIONS -------------------------------------------------------------------
   //
   //vertex
   Int_t vtxID = task->CreateValue(AliRsnMiniValue::kVz, kFALSE);
   AliRsnMiniOutput *outVtx = task->CreateOutput("eventVtx", "HIST", "EVENT");
   outVtx->AddAxis(vtxID, 400, -20.0, 20.0);

   //multiplicity or centrality
   Int_t multID = task->CreateValue(AliRsnMiniValue::kMult, kFALSE);
   AliRsnMiniOutput *outMult = task->CreateOutput("eventMult", "HIST", "EVENT");
   if (isPP)
     outMult->AddAxis(multID, 400, 0.0, 400.0);
   else
     outMult->AddAxis(multID, 100, 0.0, 100.0);

   //
   // -- PAIR CUTS (common to all resonances) ------------------------------------------------------
   //
   AliRsnCutMiniPair *cutY = new AliRsnCutMiniPair("cutRapidity", AliRsnCutMiniPair::kRapidityRange);
   cutY->SetRangeD(-0.5, 0.5);
   AliRsnCutSet *cutsPair = new AliRsnCutSet("pairCuts", AliRsnTarget::kMother);
   cutsPair->AddCut(cutY);
   cutsPair->SetCutScheme(cutY->GetName());

   //
   // -- CONFIG ANALYSIS --------------------------------------------------------------------------
   //
   gROOT->LoadMacro("$ALICE_PHYSICS/PWGLF/RESONANCES/macros/mini/ConfigKStarPbPbRunII.C");
   //gROOT->LoadMacro("ConfigKStarPbPbRunII.C");
   if (!ConfigKStarPbPbRunII(task, isMC, isPP, cutsPair,Strcut, customQualityCutsID,cutKaCandidate,nsigmaPi,nsigmaK, enableMonitor)) return 0x0;

   //
   // -- CONTAINERS --------------------------------------------------------------------------------
   //
   TString outputFileName = AliAnalysisManager::GetCommonFileName();
   //outputFileName += ":Rsn";
   Printf("AddTaskKStarPbPbRunTwo - Set OutputFileName : \n %s\n", outputFileName.Data() );

   AliAnalysisDataContainer *output = mgr->CreateContainer(Form("RsnOut_%s",outNameSuffix.Data()),
							   TList::Class(),
							   AliAnalysisManager::kOutputContainer,
							   outputFileName);
   mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput(task, 1, output);

   return task;
}
<|endoftext|>


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

// NOTE: This file is intended to be customised by the end user, and includes only local node policy logic

#include <policy/policy.h>

#include <consensus/validation.h>
#include <coins.h>
CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
{
    // "Dust" is defined in terms of dustRelayFee,
    // which has units satoshis-per-kilobyte.
    // If you'd pay more in fees than the value of the output
    // to spend something, then we consider it dust.
    // A typical spendable non-segwit txout is 34 bytes big, and will
    // need a CTxIn of at least 148 bytes to spend:
    // so dust is a spendable txout less than
    // 182*dustRelayFee/1000 (in satoshis).
    // 546 satoshis at the default rate of 3000 sat/kB.
    // A typical spendable segwit txout is 31 bytes big, and will
    // need a CTxIn of at least 67 bytes to spend:
    // so dust is a spendable txout less than
    // 98*dustRelayFee/1000 (in satoshis).
    // 294 satoshis at the default rate of 3000 sat/kB.
    if (txout.scriptPubKey.IsUnspendable())
        return 0;

    size_t nSize = GetSerializeSize(txout);
    int witnessversion = 0;
    std::vector<unsigned char> witnessprogram;

    if (txout.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
        // sum the sizes of the parts of a transaction input
        // with 75% segwit discount applied to the script size.
        nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
    } else {
        nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above
    }

    return dustRelayFeeIn.GetFee(nSize);
}

bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
{
    return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
}

bool IsStandard(const CScript& scriptPubKey, TxoutType& whichType)
{
    std::vector<std::vector<unsigned char> > vSolutions;
    whichType = Solver(scriptPubKey, vSolutions);

    if (whichType == TxoutType::NONSTANDARD) {
        return false;
    } else if (whichType == TxoutType::MULTISIG) {
        unsigned char m = vSolutions.front()[0];
        unsigned char n = vSolutions.back()[0];
        // Support up to x-of-3 multisig txns as standard
        if (n < 1 || n > 3)
            return false;
        if (m < 1 || m > n)
            return false;
    } else if (whichType == TxoutType::NULL_DATA &&
               (!fAcceptDatacarrier || scriptPubKey.size() > MAX_SCRIPT_SIZE )) {
          return false;
    }

    return true;
}

bool IsStandardTx(const CTransaction& tx, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason)
{
    const bool &isSysTx = tx.HasAssets();
    const bool &IsMnTx = tx.IsMnTx();
    if(!isSysTx && !IsMnTx){
        if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) {
            reason = "version";
            return false;
        }
    }
    else if (tx.nVersion > CTransaction::MAX_SYSCOIN_STANDARD_VERSION || tx.nVersion < 1) {
        reason = "version";
        return false;
    }
    // Extremely large transactions with lots of inputs can cost the network
    // almost as much to process as they cost the sender in fees, because
    // computing signature hashes is O(ninputs*txsize). Limiting transactions
    // to MAX_STANDARD_TX_WEIGHT mitigates CPU exhaustion attacks.
    unsigned int sz = GetTransactionWeight(tx);
    if (sz > MAX_STANDARD_TX_WEIGHT) {
        reason = "tx-size";
        return false;
    }
    for (const CTxIn& txin : tx.vin)
    {
        // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
        // keys (remember the 520 byte limit on redeemScript size). That works
        // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
        // bytes of scriptSig, which we round off to 1650 bytes for some minor
        // future-proofing. That's also enough to spend a 20-of-20
        // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
        // considered standard.
        if (txin.scriptSig.size() > 1650) {
            reason = "scriptsig-size";
            return false;
        }
        if (!txin.scriptSig.IsPushOnly()) {
            reason = "scriptsig-not-pushonly";
            return false;
        }
    }
    unsigned int nDataOut = 0;
    TxoutType whichType;
    for (const CTxOut& txout : tx.vout) {
        if (!::IsStandard(txout.scriptPubKey, whichType)) {
            reason = "scriptpubkey";
            return false;
        }

        if (whichType == TxoutType::NULL_DATA){
            // SYSCOIN if not syscoin tx and opreturn size is bigger than maxcarrier bytes, return false
            // we need this because if it is a sys tx then we allow MAX_SCRIPT_SIZE bytes.
            if (!isSysTx && !IsMnTx && txout.scriptPubKey.size() > nMaxDatacarrierBytes)
            {
                reason = "scriptpubkey";
                return false;
            }
            nDataOut++;
        }
        else if ((whichType == TxoutType::MULTISIG) && (!permit_bare_multisig)) {
            reason = "bare-multisig";
            return false;
        } else if (IsDust(txout, dust_relay_fee)) {
            reason = "dust";
            return false;
        }
    }

    if (nDataOut > 1) {
        reason = "multi-op-return";
        return false;
    }

    return true;
}

/**
 * Check transaction inputs to mitigate two
 * potential denial-of-service attacks:
 *
 * 1. scriptSigs with extra data stuffed into them,
 *    not consumed by scriptPubKey (or P2SH script)
 * 2. P2SH scripts with a crazy number of expensive
 *    CHECKSIG/CHECKMULTISIG operations
 *
 * Why bother? To avoid denial-of-service attacks; an attacker
 * can submit a standard HASH... OP_EQUAL transaction,
 * which will get accepted into blocks. The redemption
 * script can be anything; an attacker could use a very
 * expensive-to-check-upon-redemption script like:
 *   DUP CHECKSIG DROP ... repeated 100 times... OP_1
 *
 * Note that only the non-witness portion of the transaction is checked here.
 */
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
    if (tx.IsCoinBase())
        return true; // Coinbases don't use vin normally

    for (unsigned int i = 0; i < tx.vin.size(); i++)
    {
        const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;

        std::vector<std::vector<unsigned char> > vSolutions;
        TxoutType whichType = Solver(prev.scriptPubKey, vSolutions);
        if (whichType == TxoutType::NONSTANDARD || whichType == TxoutType::WITNESS_UNKNOWN) {
            // WITNESS_UNKNOWN failures are typically also caught with a policy
            // flag in the script interpreter, but it can be helpful to catch
            // this type of NONSTANDARD transaction earlier in transaction
            // validation.
            return false;
        } else if (whichType == TxoutType::SCRIPTHASH) {
            std::vector<std::vector<unsigned char> > stack;
            // convert the scriptSig into a stack, so we can inspect the redeemScript
            if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE))
                return false;
            if (stack.empty())
                return false;
            CScript subscript(stack.back().begin(), stack.back().end());
            if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
                return false;
            }
        }
    }

    return true;
}

bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
    if (tx.IsCoinBase())
        return true; // Coinbases are skipped

    for (unsigned int i = 0; i < tx.vin.size(); i++)
    {
        // We don't care if witness for this input is empty, since it must not be bloated.
        // If the script is invalid without witness, it would be caught sooner or later during validation.
        if (tx.vin[i].scriptWitness.IsNull())
            continue;

        const CTxOut &prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;

        // get the scriptPubKey corresponding to this input:
        CScript prevScript = prev.scriptPubKey;

        if (prevScript.IsPayToScriptHash()) {
            std::vector <std::vector<unsigned char> > stack;
            // If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig
            // into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway.
            // If the check fails at this stage, we know that this txid must be a bad one.
            if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE))
                return false;
            if (stack.empty())
                return false;
            prevScript = CScript(stack.back().begin(), stack.back().end());
        }

        int witnessversion = 0;
        std::vector<unsigned char> witnessprogram;

        // Non-witness program must not be associated with any witness
        if (!prevScript.IsWitnessProgram(witnessversion, witnessprogram))
            return false;

        // Check P2WSH standard limits
        if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
            if (tx.vin[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE)
                return false;
            size_t sizeWitnessStack = tx.vin[i].scriptWitness.stack.size() - 1;
            if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS)
                return false;
            for (unsigned int j = 0; j < sizeWitnessStack; j++) {
                if (tx.vin[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE)
                    return false;
            }
        }
    }
    return true;
}

int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
{
    return (std::max(nWeight, nSigOpCost * bytes_per_sigop) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
}

int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost, unsigned int bytes_per_sigop)
{
    return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost, bytes_per_sigop);
}

int64_t GetVirtualTransactionInputSize(const CTxIn& txin, int64_t nSigOpCost, unsigned int bytes_per_sigop)
{
    return GetVirtualTransactionSize(GetTransactionInputWeight(txin), nSigOpCost, bytes_per_sigop);
}
<commit_msg>ref sys header around max script size<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

// NOTE: This file is intended to be customised by the end user, and includes only local node policy logic

#include <policy/policy.h>

#include <consensus/validation.h>
#include <coins.h>
CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
{
    // "Dust" is defined in terms of dustRelayFee,
    // which has units satoshis-per-kilobyte.
    // If you'd pay more in fees than the value of the output
    // to spend something, then we consider it dust.
    // A typical spendable non-segwit txout is 34 bytes big, and will
    // need a CTxIn of at least 148 bytes to spend:
    // so dust is a spendable txout less than
    // 182*dustRelayFee/1000 (in satoshis).
    // 546 satoshis at the default rate of 3000 sat/kB.
    // A typical spendable segwit txout is 31 bytes big, and will
    // need a CTxIn of at least 67 bytes to spend:
    // so dust is a spendable txout less than
    // 98*dustRelayFee/1000 (in satoshis).
    // 294 satoshis at the default rate of 3000 sat/kB.
    if (txout.scriptPubKey.IsUnspendable())
        return 0;

    size_t nSize = GetSerializeSize(txout);
    int witnessversion = 0;
    std::vector<unsigned char> witnessprogram;

    if (txout.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
        // sum the sizes of the parts of a transaction input
        // with 75% segwit discount applied to the script size.
        nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
    } else {
        nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above
    }

    return dustRelayFeeIn.GetFee(nSize);
}

bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
{
    return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
}

bool IsStandard(const CScript& scriptPubKey, TxoutType& whichType)
{
    std::vector<std::vector<unsigned char> > vSolutions;
    whichType = Solver(scriptPubKey, vSolutions);

    if (whichType == TxoutType::NONSTANDARD) {
        return false;
    } else if (whichType == TxoutType::MULTISIG) {
        unsigned char m = vSolutions.front()[0];
        unsigned char n = vSolutions.back()[0];
        // Support up to x-of-3 multisig txns as standard
        if (n < 1 || n > 3)
            return false;
        if (m < 1 || m > n)
            return false;
    // SYSCOIN MAX_SCRIPT_SIZE vs nMaxDatacarrierBytes
    } else if (whichType == TxoutType::NULL_DATA &&
               (!fAcceptDatacarrier || scriptPubKey.size() > MAX_SCRIPT_SIZE )) {
          return false;
    }

    return true;
}

bool IsStandardTx(const CTransaction& tx, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason)
{
    const bool &isSysTx = tx.HasAssets();
    const bool &IsMnTx = tx.IsMnTx();
    if(!isSysTx && !IsMnTx){
        if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) {
            reason = "version";
            return false;
        }
    }
    else if (tx.nVersion > CTransaction::MAX_SYSCOIN_STANDARD_VERSION || tx.nVersion < 1) {
        reason = "version";
        return false;
    }
    // Extremely large transactions with lots of inputs can cost the network
    // almost as much to process as they cost the sender in fees, because
    // computing signature hashes is O(ninputs*txsize). Limiting transactions
    // to MAX_STANDARD_TX_WEIGHT mitigates CPU exhaustion attacks.
    unsigned int sz = GetTransactionWeight(tx);
    if (sz > MAX_STANDARD_TX_WEIGHT) {
        reason = "tx-size";
        return false;
    }
    for (const CTxIn& txin : tx.vin)
    {
        // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
        // keys (remember the 520 byte limit on redeemScript size). That works
        // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
        // bytes of scriptSig, which we round off to 1650 bytes for some minor
        // future-proofing. That's also enough to spend a 20-of-20
        // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
        // considered standard.
        if (txin.scriptSig.size() > 1650) {
            reason = "scriptsig-size";
            return false;
        }
        if (!txin.scriptSig.IsPushOnly()) {
            reason = "scriptsig-not-pushonly";
            return false;
        }
    }
    unsigned int nDataOut = 0;
    TxoutType whichType;
    for (const CTxOut& txout : tx.vout) {
        if (!::IsStandard(txout.scriptPubKey, whichType)) {
            reason = "scriptpubkey";
            return false;
        }

        if (whichType == TxoutType::NULL_DATA){
            // SYSCOIN if not syscoin tx and opreturn size is bigger than maxcarrier bytes, return false
            // we need this because if it is a sys tx then we allow MAX_SCRIPT_SIZE bytes.
            if (!isSysTx && !IsMnTx && txout.scriptPubKey.size() > nMaxDatacarrierBytes)
            {
                reason = "scriptpubkey";
                return false;
            }
            nDataOut++;
        }
        else if ((whichType == TxoutType::MULTISIG) && (!permit_bare_multisig)) {
            reason = "bare-multisig";
            return false;
        } else if (IsDust(txout, dust_relay_fee)) {
            reason = "dust";
            return false;
        }
    }

    if (nDataOut > 1) {
        reason = "multi-op-return";
        return false;
    }

    return true;
}

/**
 * Check transaction inputs to mitigate two
 * potential denial-of-service attacks:
 *
 * 1. scriptSigs with extra data stuffed into them,
 *    not consumed by scriptPubKey (or P2SH script)
 * 2. P2SH scripts with a crazy number of expensive
 *    CHECKSIG/CHECKMULTISIG operations
 *
 * Why bother? To avoid denial-of-service attacks; an attacker
 * can submit a standard HASH... OP_EQUAL transaction,
 * which will get accepted into blocks. The redemption
 * script can be anything; an attacker could use a very
 * expensive-to-check-upon-redemption script like:
 *   DUP CHECKSIG DROP ... repeated 100 times... OP_1
 *
 * Note that only the non-witness portion of the transaction is checked here.
 */
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
    if (tx.IsCoinBase())
        return true; // Coinbases don't use vin normally

    for (unsigned int i = 0; i < tx.vin.size(); i++)
    {
        const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;

        std::vector<std::vector<unsigned char> > vSolutions;
        TxoutType whichType = Solver(prev.scriptPubKey, vSolutions);
        if (whichType == TxoutType::NONSTANDARD || whichType == TxoutType::WITNESS_UNKNOWN) {
            // WITNESS_UNKNOWN failures are typically also caught with a policy
            // flag in the script interpreter, but it can be helpful to catch
            // this type of NONSTANDARD transaction earlier in transaction
            // validation.
            return false;
        } else if (whichType == TxoutType::SCRIPTHASH) {
            std::vector<std::vector<unsigned char> > stack;
            // convert the scriptSig into a stack, so we can inspect the redeemScript
            if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE))
                return false;
            if (stack.empty())
                return false;
            CScript subscript(stack.back().begin(), stack.back().end());
            if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
                return false;
            }
        }
    }

    return true;
}

bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
    if (tx.IsCoinBase())
        return true; // Coinbases are skipped

    for (unsigned int i = 0; i < tx.vin.size(); i++)
    {
        // We don't care if witness for this input is empty, since it must not be bloated.
        // If the script is invalid without witness, it would be caught sooner or later during validation.
        if (tx.vin[i].scriptWitness.IsNull())
            continue;

        const CTxOut &prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;

        // get the scriptPubKey corresponding to this input:
        CScript prevScript = prev.scriptPubKey;

        if (prevScript.IsPayToScriptHash()) {
            std::vector <std::vector<unsigned char> > stack;
            // If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig
            // into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway.
            // If the check fails at this stage, we know that this txid must be a bad one.
            if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE))
                return false;
            if (stack.empty())
                return false;
            prevScript = CScript(stack.back().begin(), stack.back().end());
        }

        int witnessversion = 0;
        std::vector<unsigned char> witnessprogram;

        // Non-witness program must not be associated with any witness
        if (!prevScript.IsWitnessProgram(witnessversion, witnessprogram))
            return false;

        // Check P2WSH standard limits
        if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
            if (tx.vin[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE)
                return false;
            size_t sizeWitnessStack = tx.vin[i].scriptWitness.stack.size() - 1;
            if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS)
                return false;
            for (unsigned int j = 0; j < sizeWitnessStack; j++) {
                if (tx.vin[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE)
                    return false;
            }
        }
    }
    return true;
}

int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
{
    return (std::max(nWeight, nSigOpCost * bytes_per_sigop) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
}

int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost, unsigned int bytes_per_sigop)
{
    return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost, bytes_per_sigop);
}

int64_t GetVirtualTransactionInputSize(const CTxIn& txin, int64_t nSigOpCost, unsigned int bytes_per_sigop)
{
    return GetVirtualTransactionSize(GetTransactionInputWeight(txin), nSigOpCost, bytes_per_sigop);
}
<|endoftext|>


<commit_before>#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/callback.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app-common/zap-generated/command-id.h>

// Include door lock callbacks only when the server is enabled
#ifdef EMBER_AF_PLUGIN_DOOR_LOCK_SERVER
#include <app/clusters/door-lock-server/door-lock-server.h>

bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const chip::Optional<chip::ByteSpan> & pinCode,
                                            chip::app::Clusters::DoorLock::DlOperationError & err)
{
    err = DlOperationError::kUnspecified;
    return true;
}

bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const chip::Optional<chip::ByteSpan> & pinCode,
                                              chip::app::Clusters::DoorLock::DlOperationError & err)
{
    err = DlOperationError::kUnspecified;
    return true;
}
#endif /* EMBER_AF_PLUGIN_DOOR_LOCK_SERVER */
<commit_msg>Fix chef lock state not changed when lock / unlock (#22153)<commit_after>#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/callback.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app-common/zap-generated/command-id.h>

// Include door lock callbacks only when the server is enabled
#ifdef EMBER_AF_PLUGIN_DOOR_LOCK_SERVER
#include <app/clusters/door-lock-server/door-lock-server.h>

bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const chip::Optional<chip::ByteSpan> & pinCode,
                                            chip::app::Clusters::DoorLock::DlOperationError & err)
{
    err = DlOperationError::kUnspecified;
    // TBD: LockManager, check pinCode, ...
    return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kLocked);
}

bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const chip::Optional<chip::ByteSpan> & pinCode,
                                              chip::app::Clusters::DoorLock::DlOperationError & err)
{
    err = DlOperationError::kUnspecified;
    // TBD: LockManager, check pinCode, ...
    return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kUnlocked);
}
#endif /* EMBER_AF_PLUGIN_DOOR_LOCK_SERVER */
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "LimitBox.hxx"
#include "dbu_qry.hrc"
#include "moduledbu.hxx"

#define ALL_STRING ModuleRes(STR_QUERY_LIMIT_ALL).toString()
#define ALL_INT -1

////////////////
///LimitBox
////////////////

namespace global{

/// Default values
sal_Int64 aDefLimitAry[] =
{
    5,
    10,
    20,
    50
};

}

namespace dbaui
{

LimitBox::LimitBox( Window* pParent, WinBits nStyle )
    : NumericBox( pParent, nStyle )
{
    SetShowTrailingZeros( sal_False );
    SetDecimalDigits( 0 );
    SetMin( -1 );

    ///Use the maximum value of Int32
    SetMax( 2147483647 );
    LoadDefaultLimits();

    Size aSize(
        GetSizePixel().Width(),
        CalcWindowSizePixel(GetEntryCount() + 1) );
    SetSizePixel(aSize);
}

LimitBox::~LimitBox()
{
}

OUString LimitBox::CreateFieldText( sal_Int64 nValue ) const
{
    if( nValue == ALL_INT )
        return ALL_STRING;
    else
        return NumericBox::CreateFieldText( nValue );
}

void LimitBox::Reformat()
{

    if( GetText() == ALL_STRING )
    {
        SetValue( ALL_INT );
    }
    ///Reformat only when text is not All
    else
    {
        ///Not allow user to type in -1
        if( GetText() == "-1" )
        {
            Undo();
        }
        else
            NumericBox::Reformat();
    }
}

void LimitBox::ReformatAll()
{
    ///First entry is All, which do not need numeric reformat
    if ( GetEntryCount() > 0 )
    {
        RemoveEntry( 0 );
        NumericBox::ReformatAll();
        InsertEntry( ALL_STRING, 0);
    }
    else
    {
        NumericBox::ReformatAll();
    }
}

Size LimitBox::GetOptimalSize() const
{
    return CalcSize(10,1);
}

///Initialize entries
void LimitBox::LoadDefaultLimits()
{
    SetValue( ALL_INT );
    InsertEntry( ALL_STRING );

    const unsigned nSize =
        sizeof(global::aDefLimitAry)/sizeof(global::aDefLimitAry[0]);
    for( unsigned nIndex = 0; nIndex< nSize; ++nIndex)
    {
        InsertValue( global::aDefLimitAry[nIndex] );
    }
}

extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeLimitBox( Window *pParent )
{
    LimitBox* pBox = new LimitBox( pParent, WB_DROPDOWN | WB_VSCROLL );
    return pBox;
}

} ///dbaui namespace

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>LimitBox.cxx: Delete useless comment block<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "LimitBox.hxx"
#include "dbu_qry.hrc"
#include "moduledbu.hxx"

#define ALL_STRING ModuleRes(STR_QUERY_LIMIT_ALL).toString()
#define ALL_INT -1

namespace global{

/// Default values
sal_Int64 aDefLimitAry[] =
{
    5,
    10,
    20,
    50
};

}

namespace dbaui
{

LimitBox::LimitBox( Window* pParent, WinBits nStyle )
    : NumericBox( pParent, nStyle )
{
    SetShowTrailingZeros( sal_False );
    SetDecimalDigits( 0 );
    SetMin( -1 );

    ///Use the maximum value of Int32
    SetMax( 2147483647 );
    LoadDefaultLimits();

    Size aSize(
        GetSizePixel().Width(),
        CalcWindowSizePixel(GetEntryCount() + 1) );
    SetSizePixel(aSize);
}

LimitBox::~LimitBox()
{
}

OUString LimitBox::CreateFieldText( sal_Int64 nValue ) const
{
    if( nValue == ALL_INT )
        return ALL_STRING;
    else
        return NumericBox::CreateFieldText( nValue );
}

void LimitBox::Reformat()
{

    if( GetText() == ALL_STRING )
    {
        SetValue( ALL_INT );
    }
    ///Reformat only when text is not All
    else
    {
        ///Not allow user to type in -1
        if( GetText() == "-1" )
        {
            Undo();
        }
        else
            NumericBox::Reformat();
    }
}

void LimitBox::ReformatAll()
{
    ///First entry is All, which do not need numeric reformat
    if ( GetEntryCount() > 0 )
    {
        RemoveEntry( 0 );
        NumericBox::ReformatAll();
        InsertEntry( ALL_STRING, 0);
    }
    else
    {
        NumericBox::ReformatAll();
    }
}

Size LimitBox::GetOptimalSize() const
{
    return CalcSize(10,1);
}

///Initialize entries
void LimitBox::LoadDefaultLimits()
{
    SetValue( ALL_INT );
    InsertEntry( ALL_STRING );

    const unsigned nSize =
        sizeof(global::aDefLimitAry)/sizeof(global::aDefLimitAry[0]);
    for( unsigned nIndex = 0; nIndex< nSize; ++nIndex)
    {
        InsertValue( global::aDefLimitAry[nIndex] );
    }
}

extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeLimitBox( Window *pParent )
{
    LimitBox* pBox = new LimitBox( pParent, WB_DROPDOWN | WB_VSCROLL );
    return pBox;
}

} ///dbaui namespace

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include "path/ASPC.h"

using namespace std;

namespace chr
{
  namespace path
  {
    array<float, 256> ASPC::random;

    bool ASPC::randomGenerated = false;

    void ASPC::begin()
    {
      polyline.clear();

      if (!randomGenerated)
      {
        srand(1);

        for (int i = 0; i < random.size(); i++)
        {
          random[i] = rand() / float(RAND_MAX);
        }

        randomGenerated = true;
      }

      randomIndex = 0;
    }

    float ASPC::nextRandom()
    {
      return random[(randomIndex++) % random.size()];
    }

    void ASPC::segment(const glm::vec2 &p0, const glm::vec2 &p1, const glm::vec2 &p2)
    {
      in[0] = p0;
      in[1] = p1;
      in[2] = p2;

      float pt = 0;
      auto p = gamma(pt, in.data());

      float qt = 1;
      auto q = gamma(qt, in.data());

      sample(pt, p, qt, q);
    }

    void ASPC::segment(const glm::vec2 &p0, const glm::vec2 &p1, const glm::vec2 &p2, const glm::vec2 &p3)
    {
      in[0] = p0;
      in[1] = p1;
      in[2] = p2;
      in[3] = p3;

      float pt = 0;
      auto p = gamma(pt, in.data());

      float qt = 1;
      auto q = gamma(qt, in.data());

      sample(pt, p, qt, q);
    }

    void ASPC::sample(float t0, const glm::vec2 &p0, float t1, const glm::vec2 &p1)
    {
      float t = 0.45f + 0.1f * nextRandom();
      float rt = t0 + t * (t1 - t0);
      auto r = gamma(rt, in.data());

      float cross = (p0.x - r.x) * (p1.y - r.y) - (p0.y - r.y) * (p1.x - r.x);

      if (cross * cross < samplingTolerance) // XXX
      {
        polyline.push_back(p0);
      }
      else
      {
        sample(t0, p0, rt, r);
        sample(rt, r, t1, p1);
      }
    }
  }
}
<commit_msg>COSMETICS<commit_after>#include "path/ASPC.h"

using namespace std;

namespace chr
{
  namespace path
  {
    array<float, 256> ASPC::random;

    bool ASPC::randomGenerated = false;

    void ASPC::begin()
    {
      polyline.clear();

      if (!randomGenerated)
      {
        srand(1);

        for (int i = 0; i < random.size(); i++)
        {
          random[i] = rand() / float(RAND_MAX);
        }

        randomGenerated = true;
      }

      randomIndex = 0;
    }

    float ASPC::nextRandom()
    {
      return random[(randomIndex++) % random.size()];
    }

    void ASPC::segment(const glm::vec2 &p0, const glm::vec2 &p1, const glm::vec2 &p2)
    {
      in[0] = p0;
      in[1] = p1;
      in[2] = p2;

      float pt = 0;
      auto p = gamma(pt, in.data());

      float qt = 1;
      auto q = gamma(qt, in.data());

      sample(pt, p, qt, q);
    }

    void ASPC::segment(const glm::vec2 &p0, const glm::vec2 &p1, const glm::vec2 &p2, const glm::vec2 &p3)
    {
      in[0] = p0;
      in[1] = p1;
      in[2] = p2;
      in[3] = p3;

      float pt = 0;
      auto p = gamma(pt, in.data());

      float qt = 1;
      auto q = gamma(qt, in.data());

      sample(pt, p, qt, q);
    }

    void ASPC::sample(float t0, const glm::vec2 &p0, float t1, const glm::vec2 &p1)
    {
      float t = 0.45f + 0.1f * nextRandom();
      float rt = t0 + t * (t1 - t0);
      auto r = gamma(rt, in.data());

      float cross = (p0.x - r.x) * (p1.y - r.y) - (p1.x - r.x) * (p0.y - r.y);

      if (cross * cross < samplingTolerance)
      {
        polyline.push_back(p0);
      }
      else
      {
        sample(t0, p0, rt, r);
        sample(rt, r, t1, p1);
      }
    }
  }
}
<|endoftext|>