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

/* $Id: AliPIDResponse.cxx 46193 2010-12-21 09:00:14Z wiechula $ */

//-----------------------------------------------------------------
//        Base class for handling the pid response               //
//        functions of all detectors                             //
//        and give access to the nsigmas                         //
//                                                               //
//   Origin: Jens Wiechula, Uni Tuebingen, jens.wiechula@cern.ch //
//-----------------------------------------------------------------

#include <TList.h>
#include <TObjArray.h>
#include <TPRegexp.h>
#include <TF1.h>
#include <TSpline.h>
#include <TFile.h>

#include <AliVEvent.h>
#include <AliLog.h>
#include <AliPID.h>

#include "AliPIDResponse.h"

ClassImp(AliPIDResponse);

AliPIDResponse::AliPIDResponse(Bool_t isMC/*=kFALSE*/) :
TNamed("PIDResponse","PIDResponse"),
fITSResponse(isMC),
fTPCResponse(),
fTRDResponse(),
fTOFResponse(),
fIsMC(isMC),
fOADBPath(),
fBeamType("PP"),
fLHCperiod(),
fMCperiodTPC(),
fRecoPass(0),
fRun(0),
fOldRun(0),
fArrPidResponseMaster(0x0),
fResolutionCorrection(0x0),
fTOFTimeZeroType(kBest_T0),
fTOFres(100.)
{
  //
  // default ctor
  //
  AliLog::SetClassDebugLevel("AliPIDResponse",10);
  AliLog::SetClassDebugLevel("AliESDpid",10);
  AliLog::SetClassDebugLevel("AliAODpidUtil",10);
}

//______________________________________________________________________________
AliPIDResponse::~AliPIDResponse()
{
  //
  // dtor
  //
  delete fArrPidResponseMaster;
}

//______________________________________________________________________________
AliPIDResponse::AliPIDResponse(const AliPIDResponse &other) :
TNamed(other),
fITSResponse(other.fITSResponse),
fTPCResponse(other.fTPCResponse),
fTRDResponse(other.fTRDResponse),
fTOFResponse(other.fTOFResponse),
fIsMC(other.fIsMC),
fOADBPath(other.fOADBPath),
fBeamType("PP"),
fLHCperiod(),
fMCperiodTPC(),
fRecoPass(0),
fRun(0),
fOldRun(0),
fArrPidResponseMaster(0x0),
fResolutionCorrection(0x0),
fTOFTimeZeroType(AliPIDResponse::kBest_T0),
fTOFres(100.)
{
  //
  // copy ctor
  //
}

//______________________________________________________________________________
AliPIDResponse& AliPIDResponse::operator=(const AliPIDResponse &other)
{
  //
  // copy ctor
  //
  if(this!=&other) {
    delete fArrPidResponseMaster;
    TNamed::operator=(other);
    fITSResponse=other.fITSResponse;
    fTPCResponse=other.fTPCResponse;
    fTRDResponse=other.fTRDResponse;
    fTOFResponse=other.fTOFResponse;
    fOADBPath=other.fOADBPath;
    fIsMC=other.fIsMC;
    fBeamType="PP";
    fLHCperiod="";
    fMCperiodTPC="";
    fRecoPass=0;
    fRun=0;
    fOldRun=0;
    fArrPidResponseMaster=0x0;
    fResolutionCorrection=0x0;
    fTOFTimeZeroType=AliPIDResponse::kBest_T0;
    fTOFres=100.;
  }
  return *this;
}

//______________________________________________________________________________
void AliPIDResponse::InitialiseEvent(AliVEvent *event, Int_t pass)
{
  //
  // Apply settings for the current event
  //
  fRecoPass=pass;

  if (!event) return;
  fRun=event->GetRunNumber();

  if (fRun!=fOldRun){
    ExecNewRun();
    fOldRun=fRun;
  }

  //TPC resolution parametrisation PbPb
  if ( fResolutionCorrection ){
    Double_t corrSigma=fResolutionCorrection->Eval(GetTPCMultiplicityBin(event));
    fTPCResponse.SetSigma(3.79301e-03*corrSigma, 2.21280e+04);
  }

  //TOF resolution
  SetTOFResponse(event, (AliPIDResponse::EStartTimeType_t)fTOFTimeZeroType);

}

//______________________________________________________________________________
void AliPIDResponse::ExecNewRun()
{
  //
  // Things to Execute upon a new run
  //
  SetRecoInfo();

  SetITSParametrisation();

  SetTPCPidResponseMaster();
  SetTPCParametrisation();

  fTOFResponse.SetTimeResolution(fTOFres);
}

//_____________________________________________________
Double_t AliPIDResponse::GetTPCMultiplicityBin(const AliVEvent * const event)
{
  //
  // Get TPC multiplicity in bins of 150
  //

  const AliVVertex* vertexTPC = event->GetPrimaryVertex();
  Double_t tpcMulti=0.;
  if(vertexTPC){
    Double_t vertexContribTPC=vertexTPC->GetNContributors();
    tpcMulti=vertexContribTPC/150.;
    if (tpcMulti>20.) tpcMulti=20.;
  }

  return tpcMulti;
}

//______________________________________________________________________________
void AliPIDResponse::SetRecoInfo()
{
  //
  // Set reconstruction information
  //

  //reset information
  fLHCperiod="";
  fMCperiodTPC="";

  fBeamType="";

  fBeamType="PP";

  //find the period by run number (UGLY, but not stored in ESD and AOD... )
  if (fRun>=114737&&fRun<=117223)      { fLHCperiod="LHC10B"; fMCperiodTPC="LHC10D1";  }
  else if (fRun>=118503&&fRun<=121040) { fLHCperiod="LHC10C"; fMCperiodTPC="LHC10D1";  }
  else if (fRun>=122195&&fRun<=126437) { fLHCperiod="LHC10D"; fMCperiodTPC="LHC10F6A"; }
  else if (fRun>=127719&&fRun<=130850) { fLHCperiod="LHC10E"; fMCperiodTPC="LHC10F6A"; }
  else if (fRun>=133004&&fRun<=135029) { fLHCperiod="LHC10F"; fMCperiodTPC="LHC10F6A"; }
  else if (fRun>=135654&&fRun<=136377) { fLHCperiod="LHC10G"; fMCperiodTPC="LHC10F6A"; }
  else if (fRun>=136851&&fRun<=139517) { fLHCperiod="LHC10H"; fMCperiodTPC="LHC10H8"; fBeamType="PBPB"; }
  else if (fRun>=139699) { fLHCperiod="LHC11A"; fMCperiodTPC="LHC10F6A"; }

}

//______________________________________________________________________________
void AliPIDResponse::SetITSParametrisation()
{
  //
  // Set the ITS parametrisation
  //
}

//______________________________________________________________________________
void AliPIDResponse::SetTPCPidResponseMaster()
{
  //
  // Load the TPC pid response functions from the OADB
  //

  //reset the PID response functions
  delete fArrPidResponseMaster;
  fArrPidResponseMaster=0x0;

  TString fileName(Form("%s/COMMON/PID/data/TPCPIDResponse.root", fOADBPath.Data()));

  TFile f(fileName.Data());
  if (f.IsOpen() && !f.IsZombie()){
    fArrPidResponseMaster=dynamic_cast<TObjArray*>(f.Get("TPCPIDResponse"));
    f.Close();
  }

  if (!fArrPidResponseMaster){
    AliFatal(Form("Could not retrieve the TPC pid response from: %s",fileName.Data()));
    return;
  }
  fArrPidResponseMaster->SetOwner();
}

//______________________________________________________________________________
void AliPIDResponse::SetTPCParametrisation()
{
  //
  // Change BB parametrisation for current run
  //

  if (fLHCperiod.IsNull()) {
    AliFatal("No period set, not changing parametrisation");
    return;
  }

  //
  // Set default parametrisations for data and MC
  //

  //data type
  TString datatype="DATA";
  //in case of mc fRecoPass is per default 1
  if (fIsMC) {
    datatype="MC";
    fRecoPass=1;
  }

  //
  //reset old splines
  //
  for (Int_t ispec=0; ispec<AliPID::kSPECIES; ++ispec){
    fTPCResponse.SetResponseFunction((AliPID::EParticleType)ispec,0x0);
  }

  //
  //set the new PID splines
  //
  TString period=fLHCperiod;
  if (fArrPidResponseMaster){
    TObject *grAll=0x0;
    //for MC don't use period information
//     if (fIsMC) period="[A-Z0-9]*";
    //for MC use MC period information
    if (fIsMC) period=fMCperiodTPC;
//pattern for the default entry (valid for all particles)
    TPRegexp reg(Form("TSPLINE3_%s_([A-Z]*)_%s_PASS%d_%s_MEAN",datatype.Data(),period.Data(),fRecoPass,fBeamType.Data()));

    //loop over entries and filter them
    for (Int_t iresp=0; iresp<fArrPidResponseMaster->GetEntriesFast();++iresp){
      TObject *responseFunction=fArrPidResponseMaster->At(iresp);
      if (responseFunction==0x0) continue;
      TString responseName=responseFunction->GetName();

      if (!reg.MatchB(responseName)) continue;

      TObjArray *arr=reg.MatchS(responseName);
      TString particleName=arr->At(1)->GetName();
      delete arr;
      if (particleName.IsNull()) continue;
      if (particleName=="ALL") grAll=responseFunction;
      else {
        //find particle id
        for (Int_t ispec=0; ispec<AliPID::kSPECIES; ++ispec){
          TString particle=AliPID::ParticleName(ispec);
          particle.ToUpper();
          if ( particle == particleName ){
            fTPCResponse.SetResponseFunction((AliPID::EParticleType)ispec,responseFunction);
            fTPCResponse.SetUseDatabase(kTRUE);
            AliInfo(Form("Adding graph: %d - %s",ispec,responseFunction->GetName()));
            break;
          }
        }
      }
    }

    //set default response function to all particles which don't have a specific one
    if (grAll){
      for (Int_t ispec=0; ispec<AliPID::kSPECIES; ++ispec){
        if (!fTPCResponse.GetResponseFunction((AliPID::EParticleType)ispec)){
          fTPCResponse.SetResponseFunction((AliPID::EParticleType)ispec,grAll);
          AliInfo(Form("Adding graph: %d - %s",ispec,grAll->GetName()));
        }
      }
    }
  }

  //
  // Setup resolution parametrisation
  //

  //default
  fTPCResponse.SetSigma(3.79301e-03, 2.21280e+04);

  if (fRun>=122195){
    fTPCResponse.SetSigma(2.30176e-02, 5.60422e+02);
  }

  fResolutionCorrection=(TF1*)fArrPidResponseMaster->FindObject(Form("TF1_%s_ALL_%s_PASS%d_%s_SIGMA",datatype.Data(),period.Data(),fRecoPass,fBeamType.Data()));

  if (fResolutionCorrection) AliInfo(Form("Setting multiplicity correction function: %s",fResolutionCorrection->GetName()));
}

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

/* $Id: AliPIDResponse.cxx 46193 2010-12-21 09:00:14Z wiechula $ */

//-----------------------------------------------------------------
//        Base class for handling the pid response               //
//        functions of all detectors                             //
//        and give access to the nsigmas                         //
//                                                               //
//   Origin: Jens Wiechula, Uni Tuebingen, jens.wiechula@cern.ch //
//-----------------------------------------------------------------

#include <TList.h>
#include <TObjArray.h>
#include <TPRegexp.h>
#include <TF1.h>
#include <TSpline.h>
#include <TFile.h>

#include <AliVEvent.h>
#include <AliLog.h>
#include <AliPID.h>

#include "AliPIDResponse.h"

ClassImp(AliPIDResponse);

AliPIDResponse::AliPIDResponse(Bool_t isMC/*=kFALSE*/) :
TNamed("PIDResponse","PIDResponse"),
fITSResponse(isMC),
fTPCResponse(),
fTRDResponse(),
fTOFResponse(),
fIsMC(isMC),
fOADBPath(),
fBeamType("PP"),
fLHCperiod(),
fMCperiodTPC(),
fRecoPass(0),
fRun(0),
fOldRun(0),
fArrPidResponseMaster(0x0),
fResolutionCorrection(0x0),
fTOFTimeZeroType(kBest_T0),
fTOFres(100.)
{
  //
  // default ctor
  //
  AliLog::SetClassDebugLevel("AliPIDResponse",10);
  AliLog::SetClassDebugLevel("AliESDpid",10);
  AliLog::SetClassDebugLevel("AliAODpidUtil",10);
}

//______________________________________________________________________________
AliPIDResponse::~AliPIDResponse()
{
  //
  // dtor
  //
  delete fArrPidResponseMaster;
}

//______________________________________________________________________________
AliPIDResponse::AliPIDResponse(const AliPIDResponse &other) :
TNamed(other),
fITSResponse(other.fITSResponse),
fTPCResponse(other.fTPCResponse),
fTRDResponse(other.fTRDResponse),
fTOFResponse(other.fTOFResponse),
fIsMC(other.fIsMC),
fOADBPath(other.fOADBPath),
fBeamType("PP"),
fLHCperiod(),
fMCperiodTPC(),
fRecoPass(0),
fRun(0),
fOldRun(0),
fArrPidResponseMaster(0x0),
fResolutionCorrection(0x0),
fTOFTimeZeroType(AliPIDResponse::kBest_T0),
fTOFres(100.)
{
  //
  // copy ctor
  //
}

//______________________________________________________________________________
AliPIDResponse& AliPIDResponse::operator=(const AliPIDResponse &other)
{
  //
  // copy ctor
  //
  if(this!=&other) {
    delete fArrPidResponseMaster;
    TNamed::operator=(other);
    fITSResponse=other.fITSResponse;
    fTPCResponse=other.fTPCResponse;
    fTRDResponse=other.fTRDResponse;
    fTOFResponse=other.fTOFResponse;
    fOADBPath=other.fOADBPath;
    fIsMC=other.fIsMC;
    fBeamType="PP";
    fLHCperiod="";
    fMCperiodTPC="";
    fRecoPass=0;
    fRun=0;
    fOldRun=0;
    fArrPidResponseMaster=0x0;
    fResolutionCorrection=0x0;
    fTOFTimeZeroType=AliPIDResponse::kBest_T0;
    fTOFres=100.;
  }
  return *this;
}

//______________________________________________________________________________
void AliPIDResponse::InitialiseEvent(AliVEvent *event, Int_t pass)
{
  //
  // Apply settings for the current event
  //
  fRecoPass=pass;

  if (!event) return;
  fRun=event->GetRunNumber();

  if (fRun!=fOldRun){
    ExecNewRun();
    fOldRun=fRun;
  }

  //TPC resolution parametrisation PbPb
  if ( fResolutionCorrection ){
    Double_t corrSigma=fResolutionCorrection->Eval(GetTPCMultiplicityBin(event));
    fTPCResponse.SetSigma(3.79301e-03*corrSigma, 2.21280e+04);
  }

  //TOF resolution
  SetTOFResponse(event, (AliPIDResponse::EStartTimeType_t)fTOFTimeZeroType);

}

//______________________________________________________________________________
void AliPIDResponse::ExecNewRun()
{
  //
  // Things to Execute upon a new run
  //
  SetRecoInfo();

  SetITSParametrisation();

  SetTPCPidResponseMaster();
  SetTPCParametrisation();

  fTOFResponse.SetTimeResolution(fTOFres);
}

//_____________________________________________________
Double_t AliPIDResponse::GetTPCMultiplicityBin(const AliVEvent * const event)
{
  //
  // Get TPC multiplicity in bins of 150
  //

  const AliVVertex* vertexTPC = event->GetPrimaryVertex();
  Double_t tpcMulti=0.;
  if(vertexTPC){
    Double_t vertexContribTPC=vertexTPC->GetNContributors();
    tpcMulti=vertexContribTPC/150.;
    if (tpcMulti>20.) tpcMulti=20.;
  }

  return tpcMulti;
}

//______________________________________________________________________________
void AliPIDResponse::SetRecoInfo()
{
  //
  // Set reconstruction information
  //

  //reset information
  fLHCperiod="";
  fMCperiodTPC="";

  fBeamType="";

  fBeamType="PP";

  //find the period by run number (UGLY, but not stored in ESD and AOD... )
  if (fRun>=114737&&fRun<=117223)      { fLHCperiod="LHC10B"; fMCperiodTPC="LHC10D1";  }
  else if (fRun>=118503&&fRun<=121040) { fLHCperiod="LHC10C"; fMCperiodTPC="LHC10D1";  }
  else if (fRun>=122195&&fRun<=126437) { fLHCperiod="LHC10D"; fMCperiodTPC="LHC10F6A"; }
  else if (fRun>=127719&&fRun<=130850) { fLHCperiod="LHC10E"; fMCperiodTPC="LHC10F6A"; }
  else if (fRun>=133004&&fRun<=135029) { fLHCperiod="LHC10F"; fMCperiodTPC="LHC10F6A"; }
  else if (fRun>=135654&&fRun<=136377) { fLHCperiod="LHC10G"; fMCperiodTPC="LHC10F6A"; }
  else if (fRun>=136851&&fRun<=139517) { fLHCperiod="LHC10H"; fMCperiodTPC="LHC10H8"; fBeamType="PBPB"; }
  else if (fRun>=139699) { fLHCperiod="LHC11A"; fMCperiodTPC="LHC10F6A"; }

}

//______________________________________________________________________________
void AliPIDResponse::SetITSParametrisation()
{
  //
  // Set the ITS parametrisation
  //
}

//______________________________________________________________________________
void AliPIDResponse::SetTPCPidResponseMaster()
{
  //
  // Load the TPC pid response functions from the OADB
  //
  //don't load twice for the moment
   if (fArrPidResponseMaster) return;

  //reset the PID response functions
  delete fArrPidResponseMaster;
  fArrPidResponseMaster=0x0;

  TString fileName(Form("%s/COMMON/PID/data/TPCPIDResponse.root", fOADBPath.Data()));

  TFile f(fileName.Data());
  if (f.IsOpen() && !f.IsZombie()){
    fArrPidResponseMaster=dynamic_cast<TObjArray*>(f.Get("TPCPIDResponse"));
    f.Close();
  }

  if (!fArrPidResponseMaster){
    AliFatal(Form("Could not retrieve the TPC pid response from: %s",fileName.Data()));
    return;
  }
  fArrPidResponseMaster->SetOwner();
}

//______________________________________________________________________________
void AliPIDResponse::SetTPCParametrisation()
{
  //
  // Change BB parametrisation for current run
  //

  if (fLHCperiod.IsNull()) {
    AliFatal("No period set, not changing parametrisation");
    return;
  }

  //
  // Set default parametrisations for data and MC
  //

  //data type
  TString datatype="DATA";
  //in case of mc fRecoPass is per default 1
  if (fIsMC) {
    datatype="MC";
    fRecoPass=1;
  }

  //
  //reset old splines
  //
  for (Int_t ispec=0; ispec<AliPID::kSPECIES; ++ispec){
    fTPCResponse.SetResponseFunction((AliPID::EParticleType)ispec,0x0);
  }

  //
  //set the new PID splines
  //
  TString period=fLHCperiod;
  if (fArrPidResponseMaster){
    TObject *grAll=0x0;
    //for MC don't use period information
//     if (fIsMC) period="[A-Z0-9]*";
    //for MC use MC period information
    if (fIsMC) period=fMCperiodTPC;
//pattern for the default entry (valid for all particles)
    TPRegexp reg(Form("TSPLINE3_%s_([A-Z]*)_%s_PASS%d_%s_MEAN",datatype.Data(),period.Data(),fRecoPass,fBeamType.Data()));

    //loop over entries and filter them
    for (Int_t iresp=0; iresp<fArrPidResponseMaster->GetEntriesFast();++iresp){
      TObject *responseFunction=fArrPidResponseMaster->At(iresp);
      if (responseFunction==0x0) continue;
      TString responseName=responseFunction->GetName();

      if (!reg.MatchB(responseName)) continue;

      TObjArray *arr=reg.MatchS(responseName);
      TString particleName=arr->At(1)->GetName();
      delete arr;
      if (particleName.IsNull()) continue;
      if (particleName=="ALL") grAll=responseFunction;
      else {
        //find particle id
        for (Int_t ispec=0; ispec<AliPID::kSPECIES; ++ispec){
          TString particle=AliPID::ParticleName(ispec);
          particle.ToUpper();
          if ( particle == particleName ){
            fTPCResponse.SetResponseFunction((AliPID::EParticleType)ispec,responseFunction);
            fTPCResponse.SetUseDatabase(kTRUE);
            AliInfo(Form("Adding graph: %d - %s",ispec,responseFunction->GetName()));
            break;
          }
        }
      }
    }

    //set default response function to all particles which don't have a specific one
    if (grAll){
      for (Int_t ispec=0; ispec<AliPID::kSPECIES; ++ispec){
        if (!fTPCResponse.GetResponseFunction((AliPID::EParticleType)ispec)){
          fTPCResponse.SetResponseFunction((AliPID::EParticleType)ispec,grAll);
          AliInfo(Form("Adding graph: %d - %s",ispec,grAll->GetName()));
        }
      }
    }
  }

  //
  // Setup resolution parametrisation
  //

  //default
  fTPCResponse.SetSigma(3.79301e-03, 2.21280e+04);

  if (fRun>=122195){
    fTPCResponse.SetSigma(2.30176e-02, 5.60422e+02);
  }

  fResolutionCorrection=(TF1*)fArrPidResponseMaster->FindObject(Form("TF1_%s_ALL_%s_PASS%d_%s_SIGMA",datatype.Data(),period.Data(),fRecoPass,fBeamType.Data()));

  if (fResolutionCorrection) AliInfo(Form("Setting multiplicity correction function: %s",fResolutionCorrection->GetName()));
}

<|endoftext|>


<commit_before>#include <assert.h>

#include "global.h"

#include "Level.h"
#include "blocks.h"

void begin_compound(void *context, nbt::String name) {
  if (name.compare("Level") == 0) {
    ((Level*)context)->islevel = true;
  }
}

void register_int(void *context, nbt::String name, nbt::Int i) {
  if (name.compare("xPos") == 0) {
    ((Level *)context)->xPos = i;
    return;
  }

  if (name.compare("zPos") == 0) {
    ((Level *)context)->zPos = i;
    return;
  }
}

void register_byte_array(void *context, nbt::String name, nbt::ByteArray *byte_array) {
  if (name.compare("Blocks") == 0) {
    ((Level *)context)->blocks = byte_array;
    return;
  }

  if (name.compare("SkyLight") == 0) {
    ((Level *)context)->skylight = byte_array;
    return;
  }

  if (name.compare("HeightMap") == 0) {
    ((Level *)context)->heightmap = byte_array;
    return;
  }

  if (name.compare("BlockLight") == 0) {
    ((Level *)context)->blocklight = byte_array;
    return;
  }
}

Level::~Level(){
  if (islevel) {
    delete blocks;
    delete skylight;
    delete heightmap;
    delete blocklight;
  }
}

Level::Level(const char *path) {
  xPos = 0;
  zPos = 0;
  islevel = false;

  nbt::Parser parser(this);
  parser.register_byte_array = register_byte_array;
  parser.register_int = register_int;
  parser.begin_compound = begin_compound;
  parser.parse_file(path);

  if (islevel) {
  }
}

/**
 * Blocks[ y + ( z * ChunkSizeY(=128) + ( x * ChunkSizeY(=128) * ChunkSizeZ(=16) ) ) ];
 */
nbt::Byte bget(nbt::ByteArray *blocks, int x, int y, int z) {
  assert(x >= 0 && x < mc::MapX);
  assert(y >= 0 && y < mc::MapY);
  assert(z >= 0 && z < mc::MapZ);
  int p = z + (y * mc::MapZ + (x * mc::MapZ * mc::MapY));
  assert (p >= 0 && p < blocks->length);
  return blocks->values[p];
}

nbt::Byte bsget(nbt::ByteArray *skylight, int x, int y, int z) {
  assert(x >= 0 && x < mc::MapX);
  assert(y >= 0 && y < mc::MapY);
  assert(z >= 0 && z < mc::MapZ);
  int p = z + (y * mc::MapZ + (x * mc::MapZ * mc::MapY));
  int ap = p / 2;

  assert (ap >= 0 && ap < skylight->length);

  // force unsigned
  uint8_t bp = skylight->values[ap] & 0xff;

  if (p % 2 == 0) {
    return bp >> 4;
  }
  else {
    return bp & 0xf;
  }
}

void transform_xy(settings_t *s, int &x, int &y) {
  if (s->flip) {
    int t = x;
    x = y;
    y = mc::MapY - t - 1;
  }

  if (s->invert) {
    y = mc::MapY - y - 1;
    x = mc::MapX - x - 1;
  }
}

Image *Level::get_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY);

  if (!islevel) {
    return img;
  }

  for (int y = 0; y < mc::MapY; y++) {
    for (int x = 0; x < mc::MapX; x++) {
      int _x = x, _y = y;
      transform_xy(s, _x, _y);

      Color base(255, 255, 255, 0);

      int bt = mc::Air;
      int z;

      // do incremental color fill until color is opaque
      for (z = s->top; z > s->bottom; z--) {
        bt = bget(blocks, _x, _y, z);

        if (s->excludes[bt]) {
          continue;
        }

        Color *bc = mc::MaterialColor[bt];
        base.underlay(bc);

        if (base.a == 0xff) {
          break;
        }
      }

      // check specific last block options
      switch (bt) {
        case mc::Dirt:
        case mc::Grass:
        case mc::Stone:
        case mc::Cobblestone:
          // do an color overlay for mapped height
          Color height(0, 0, 0, 0);
          height.a = (127 - z);
          base.overlay(height);
          break;
      }

      img->set_pixel(x, y, base);
    }
  }

  return img;
}

Image *Level::get_oblique_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY + mc::MapZ);

  if (!islevel) {
    return img;
  }

  // block type
  int bt;

  // block skylight
  int sl;

  // skylight modifier
  // alpha channel is calculated depending on skylight value
  Color slmod(255, 255, 255, 0);

  // height modifier
  // alpha channel is calculated depending on height
  Color heightmod(0, 0, 0, 0);

  for (int y = 0; y < mc::MapY; y++) {
    for (int x = 0; x < mc::MapX; x++) {
      for (int z = s->bottom; z < s->top; z++) {
        int _x = x, _y = y;
        transform_xy(s, _x, _y);
        bt = bget(blocks, _x, _y, z);

        if (s->excludes[bt]) {
          continue;
        }

        sl = bsget(skylight, _x, _y, z);

        heightmod.a = (127 - z);
        slmod.a = (sl * 0x2);

        Color top(mc::MaterialColor[bt]);
        top.overlay(heightmod);
        top.overlay(slmod);
        img->set_pixel(x, y + (mc::MapZ - z) - 1, top);

        Color side(mc::MaterialSideColor[bt]);
        side.overlay(slmod);
        img->set_pixel(x, y + (mc::MapZ - z), side);
      }
    }
  }

  return img;
}

Image *Level::get_obliqueangle_image(settings_t *s) {
  Image *img = new Image(mc::MapX * 2 + 1, mc::MapX + mc::MapZ + mc::MapY);

  if (!islevel) {
    return img;
  }

  // block type
  int bt;

  // block skylight
  int sl;

  // skylight modifier
  // alpha channel is calculated depending on skylight value
  Color slmod(255, 255, 255, 0);

  // height modifier
  // alpha channel is calculated depending on height
  Color heightmod(0, 0, 0, 0);

  for (int y = 0; y < mc::MapY; y++) {
    for (int z = s->bottom; z < s->top; z++) {
      for (int x = 0; x < mc::MapX; x++) {
        int _x = x, _y = y;
        transform_xy(s, _x, _y);

        bt = bget(blocks, _x, _y, z);

        if (s->excludes[bt]) {
          continue;
        }

        sl = bsget(skylight, _x, _y, z);

        heightmod.a = (127 - z);
        slmod.a = (sl * 0x2);

        Color top(mc::MaterialColor[bt]);
        top.overlay(heightmod);
        top.overlay(slmod);

        int _px = mc::MapX + x - y;
        int _py = mc::MapZ + x - z + y;

        img->set_pixel(_px, _py - 1, top);
        img->set_pixel(_px + 1, _py - 1, top);

        Color side(mc::MaterialSideColor[bt]);
        side.overlay(heightmod);
        side.overlay(slmod);
        img->set_pixel(_px, _py, side);
        img->set_pixel(_px + 1, _py, side);
      }
    }
  }

  return img;
}
<commit_msg>Fixed flat rendering<commit_after>#include <assert.h>

#include "global.h"

#include "Level.h"
#include "blocks.h"

void begin_compound(void *context, nbt::String name) {
  if (name.compare("Level") == 0) {
    ((Level*)context)->islevel = true;
  }
}

void register_int(void *context, nbt::String name, nbt::Int i) {
  if (name.compare("xPos") == 0) {
    ((Level *)context)->xPos = i;
    return;
  }

  if (name.compare("zPos") == 0) {
    ((Level *)context)->zPos = i;
    return;
  }
}

void register_byte_array(void *context, nbt::String name, nbt::ByteArray *byte_array) {
  if (name.compare("Blocks") == 0) {
    ((Level *)context)->blocks = byte_array;
    return;
  }

  if (name.compare("SkyLight") == 0) {
    ((Level *)context)->skylight = byte_array;
    return;
  }

  if (name.compare("HeightMap") == 0) {
    ((Level *)context)->heightmap = byte_array;
    return;
  }

  if (name.compare("BlockLight") == 0) {
    ((Level *)context)->blocklight = byte_array;
    return;
  }
}

Level::~Level(){
  if (islevel) {
    delete blocks;
    delete skylight;
    delete heightmap;
    delete blocklight;
  }
}

Level::Level(const char *path) {
  xPos = 0;
  zPos = 0;
  islevel = false;

  nbt::Parser parser(this);
  parser.register_byte_array = register_byte_array;
  parser.register_int = register_int;
  parser.begin_compound = begin_compound;
  parser.parse_file(path);

  if (islevel) {
  }
}

/**
 * Blocks[ y + ( z * ChunkSizeY(=128) + ( x * ChunkSizeY(=128) * ChunkSizeZ(=16) ) ) ];
 */
nbt::Byte bget(nbt::ByteArray *blocks, int x, int y, int z) {
  assert(x >= 0 && x < mc::MapX);
  assert(y >= 0 && y < mc::MapY);
  assert(z >= 0 && z < mc::MapZ);
  int p = z + (y * mc::MapZ + (x * mc::MapZ * mc::MapY));
  assert (p >= 0 && p < blocks->length);
  return blocks->values[p];
}

nbt::Byte bsget(nbt::ByteArray *skylight, int x, int y, int z) {
  assert(x >= 0 && x < mc::MapX);
  assert(y >= 0 && y < mc::MapY);
  assert(z >= 0 && z < mc::MapZ);
  int p = z + (y * mc::MapZ + (x * mc::MapZ * mc::MapY));
  int ap = p / 2;

  assert (ap >= 0 && ap < skylight->length);

  // force unsigned
  uint8_t bp = skylight->values[ap] & 0xff;

  if (p % 2 == 0) {
    return bp >> 4;
  }
  else {
    return bp & 0xf;
  }
}

void transform_xy(settings_t *s, int &x, int &y) {
  if (s->flip) {
    int t = x;
    x = y;
    y = mc::MapY - t - 1;
  }

  if (s->invert) {
    y = mc::MapY - y - 1;
    x = mc::MapX - x - 1;
  }
}

Image *Level::get_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY);

  if (!islevel) {
    return img;
  }

  // block type
  int bt;

  // block skylight
  int sl;

  // skylight modifier
  // alpha channel is calculated depending on skylight value
  Color slmod(255, 255, 255, 0);

  // height modifier
  // alpha channel is calculated depending on height
  Color heightmod(0, 0, 0, 0);

  for (int y = 0; y < mc::MapY; y++) {
    for (int x = 0; x < mc::MapX; x++) {
      int _x = x, _y = y;
      transform_xy(s, _x, _y);

      Color base(255, 255, 255, 0);

      bt = mc::Air;

      int z;

      // do incremental color fill until color is opaque
      for (z = s->top; z > s->bottom; z--) {
        bt = bget(blocks, _x, _y, z);

        if (s->excludes[bt]) {
          continue;
        }

        Color *bc = mc::MaterialColor[bt];
        base.underlay(bc);

        if (base.a == 0xff) {
          break;
        }
      }

      // check specific last block options
      heightmod.a = (127 - z);

      sl = bsget(skylight, _x, _y, z);
      slmod.a = (sl * 0x2);

      base.overlay(heightmod);
      base.overlay(slmod);

      img->set_pixel(x, y, base);
    }
  }

  return img;
}

Image *Level::get_oblique_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY + mc::MapZ);

  if (!islevel) {
    return img;
  }

  // block type
  int bt;

  // block skylight
  int sl;

  // skylight modifier
  // alpha channel is calculated depending on skylight value
  Color slmod(255, 255, 255, 0);

  // height modifier
  // alpha channel is calculated depending on height
  Color heightmod(0, 0, 0, 0);

  for (int y = 0; y < mc::MapY; y++) {
    for (int x = 0; x < mc::MapX; x++) {
      for (int z = s->bottom; z < s->top; z++) {
        int _x = x, _y = y;
        transform_xy(s, _x, _y);
        bt = bget(blocks, _x, _y, z);

        if (s->excludes[bt]) {
          continue;
        }

        sl = bsget(skylight, _x, _y, z);

        heightmod.a = (127 - z);
        slmod.a = (sl * 0x2);

        Color top(mc::MaterialColor[bt]);
        top.overlay(heightmod);
        top.overlay(slmod);
        img->set_pixel(x, y + (mc::MapZ - z) - 1, top);

        Color side(mc::MaterialSideColor[bt]);
        side.overlay(slmod);
        img->set_pixel(x, y + (mc::MapZ - z), side);
      }
    }
  }

  return img;
}

Image *Level::get_obliqueangle_image(settings_t *s) {
  Image *img = new Image(mc::MapX * 2 + 1, mc::MapX + mc::MapZ + mc::MapY);

  if (!islevel) {
    return img;
  }

  // block type
  int bt;

  // block skylight
  int sl;

  // skylight modifier
  // alpha channel is calculated depending on skylight value
  Color slmod(255, 255, 255, 0);

  // height modifier
  // alpha channel is calculated depending on height
  Color heightmod(0, 0, 0, 0);

  for (int y = 0; y < mc::MapY; y++) {
    for (int z = s->bottom; z < s->top; z++) {
      for (int x = 0; x < mc::MapX; x++) {
        int _x = x, _y = y;
        transform_xy(s, _x, _y);

        bt = bget(blocks, _x, _y, z);

        if (s->excludes[bt]) {
          continue;
        }

        sl = bsget(skylight, _x, _y, z);

        heightmod.a = (127 - z);
        slmod.a = (sl * 0x2);

        Color top(mc::MaterialColor[bt]);
        top.overlay(heightmod);
        top.overlay(slmod);

        int _px = mc::MapX + x - y;
        int _py = mc::MapZ + x - z + y;

        img->set_pixel(_px, _py - 1, top);
        img->set_pixel(_px + 1, _py - 1, top);

        Color side(mc::MaterialSideColor[bt]);
        side.overlay(heightmod);
        side.overlay(slmod);
        img->set_pixel(_px, _py, side);
        img->set_pixel(_px + 1, _py, side);
      }
    }
  }

  return img;
}
<|endoftext|>


<commit_before>#include <assert.h>

#include "global.h"

#include "Level.h"
#include "blocks.h"

void begin_compound(void *context, nbt::String name) {
  if (name.compare("Level") == 0) {
    ((Level*)context)->islevel = true;
  }
}

void register_int(void *context, nbt::String name, nbt::Int i) {
  if (name.compare("xPos") == 0) {
    ((Level *)context)->xPos = i;
    return;
  }

  if (name.compare("zPos") == 0) {
    ((Level *)context)->zPos = i;
    return;
  }
}

void register_byte_array(void *context, nbt::String name, nbt::ByteArray *byte_array) {
  if (name.compare("Blocks") == 0) {
    ((Level *)context)->blocks = byte_array;
    return;
  }

  if (name.compare("SkyLight") == 0) {
    ((Level *)context)->skylight = byte_array;
    return;
  }

  if (name.compare("HeightMap") == 0) {
    ((Level *)context)->heightmap = byte_array;
    return;
  }

  if (name.compare("BlockLight") == 0) {
    ((Level *)context)->blocklight = byte_array;
    return;
  }
}

Level::~Level(){
  if (islevel) {
    delete blocks;
    delete skylight;
    delete heightmap;
    delete blocklight;
  }
}

Level::Level(const char *path) {
  xPos = 0;
  zPos = 0;
  islevel = false;

  nbt::Parser parser(this);
  parser.register_byte_array = register_byte_array;
  parser.register_int = register_int;
  parser.begin_compound = begin_compound;
  parser.parse_file(path);

  if (islevel) {
  }
}

/**
 * Blocks[ y + ( z * ChunkSizeY(=128) + ( x * ChunkSizeY(=128) * ChunkSizeZ(=16) ) ) ];
 */
nbt::Byte bget(nbt::ByteArray *blocks, int x, int y, int z) {
  assert(x >= 0 && x < mc::MapX);
  assert(y >= 0 && y < mc::MapY);
  assert(z >= 0 && z < mc::MapZ);
  int p = z + (y * mc::MapZ + (x * mc::MapZ * mc::MapY));
  assert (p >= 0 && p < blocks->length);
  return blocks->values[p];
}

Image *Level::get_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY);

  if (!islevel) {
    return img;
  }

  for (int x = 0; x < mc::MapX; x++) {
    for (int y = 0; y < mc::MapY; y++) {
      Color *base = new Color(255, 255, 255, 0);

      int blocktype;
      int z;

      // do incremental color fill until color is opaque
      for (z = s->top; z > s->bottom; z--) {
        blocktype = bget(blocks, x, y, z);

        if (s->excludes[blocktype]) {
          continue;
        }

        Color *bc = mc::MaterialColor[blocktype];
        base->underlay(bc);

        if (base->a == 0xff) {
          break;
        }
      }

      // check specific last block options
      switch (blocktype) {
        case mc::Dirt:
        case mc::Grass:
        case mc::Stone:
        case mc::Cobblestone:
          // do an color overlay for mapped height
          Color height(0, 0, 0, 0);
          height.a = (127 - z);
          base->overlay(&height);
          break;
      }

      img->set_pixel(x, y, base);
    }
  }

  return img;
}

Image *Level::get_oblique_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY + mc::MapZ);

  if (!islevel) {
    return img;
  }

  int blocktype;

  for (int y = 0; y < mc::MapY; y++) {
    for (int x = 0; x < mc::MapX; x++) {
      for (int z = mc::MapZ - 1; z > 0; z--) {
        blocktype = bget(blocks, x, y, z);

        if (s->excludes[blocktype]) {
          continue;
        }

        Color *bc = mc::MaterialColor[blocktype];

        Color height(0, 0, 0, 0);
        height.a = (127 - z);
        Color p(bc);
        p.overlay(&height);
        img->set_pixel(x, y + (mc::MapZ - z), &p);
      }
    }
  }

  return img;
}

Image *Level::get_obliqueangle_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY + mc::MapZ);
  return img;
}
<commit_msg>Better oblique rendering<commit_after>#include <assert.h>

#include "global.h"

#include "Level.h"
#include "blocks.h"

void begin_compound(void *context, nbt::String name) {
  if (name.compare("Level") == 0) {
    ((Level*)context)->islevel = true;
  }
}

void register_int(void *context, nbt::String name, nbt::Int i) {
  if (name.compare("xPos") == 0) {
    ((Level *)context)->xPos = i;
    return;
  }

  if (name.compare("zPos") == 0) {
    ((Level *)context)->zPos = i;
    return;
  }
}

void register_byte_array(void *context, nbt::String name, nbt::ByteArray *byte_array) {
  if (name.compare("Blocks") == 0) {
    ((Level *)context)->blocks = byte_array;
    return;
  }

  if (name.compare("SkyLight") == 0) {
    ((Level *)context)->skylight = byte_array;
    return;
  }

  if (name.compare("HeightMap") == 0) {
    ((Level *)context)->heightmap = byte_array;
    return;
  }

  if (name.compare("BlockLight") == 0) {
    ((Level *)context)->blocklight = byte_array;
    return;
  }
}

Level::~Level(){
  if (islevel) {
    delete blocks;
    delete skylight;
    delete heightmap;
    delete blocklight;
  }
}

Level::Level(const char *path) {
  xPos = 0;
  zPos = 0;
  islevel = false;

  nbt::Parser parser(this);
  parser.register_byte_array = register_byte_array;
  parser.register_int = register_int;
  parser.begin_compound = begin_compound;
  parser.parse_file(path);

  if (islevel) {
  }
}

/**
 * Blocks[ y + ( z * ChunkSizeY(=128) + ( x * ChunkSizeY(=128) * ChunkSizeZ(=16) ) ) ];
 */
nbt::Byte bget(nbt::ByteArray *blocks, int x, int y, int z) {
  assert(x >= 0 && x < mc::MapX);
  assert(y >= 0 && y < mc::MapY);
  assert(z >= 0 && z < mc::MapZ);
  int p = z + (y * mc::MapZ + (x * mc::MapZ * mc::MapY));
  assert (p >= 0 && p < blocks->length);
  return blocks->values[p];
}

Image *Level::get_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY);

  if (!islevel) {
    return img;
  }

  for (int x = 0; x < mc::MapX; x++) {
    for (int y = 0; y < mc::MapY; y++) {
      Color *base = new Color(255, 255, 255, 0);

      int blocktype;
      int z;

      // do incremental color fill until color is opaque
      for (z = s->top; z > s->bottom; z--) {
        blocktype = bget(blocks, x, y, z);

        if (s->excludes[blocktype]) {
          continue;
        }

        Color *bc = mc::MaterialColor[blocktype];
        base->underlay(bc);

        if (base->a == 0xff) {
          break;
        }
      }

      // check specific last block options
      switch (blocktype) {
        case mc::Dirt:
        case mc::Grass:
        case mc::Stone:
        case mc::Cobblestone:
          // do an color overlay for mapped height
          Color height(0, 0, 0, 0);
          height.a = (127 - z);
          base->overlay(&height);
          break;
      }

      img->set_pixel(x, y, base);
    }
  }

  return img;
}

Image *Level::get_oblique_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY + mc::MapZ);

  if (!islevel) {
    return img;
  }

  int blocktype;

  Color light(0, 0, 0, 64);

  for (int y = 0; y < mc::MapY; y++) {
    for (int x = 0; x < mc::MapX; x++) {
      for (int z = s->bottom; z < s->top; z++) {
        blocktype = bget(blocks, x, y, z);

        if (s->excludes[blocktype]) {
          continue;
        }

        Color *bc = mc::MaterialColor[blocktype];

        Color height(0, 0, 0, 0);
        height.a = (127 - z);
        Color p(bc);
        p.overlay(&height);
        img->set_pixel(x, y + (mc::MapZ - z) - 1, &p);

        switch (blocktype) {
          case mc::Grass:
            {
              Color side(mc::MaterialColor[mc::Dirt]);
              side.overlay(&light);
              img->set_pixel(x, y + (mc::MapZ - z), &side);
            }
            break;
          default:
            Color side(&p);
            side.overlay(&light);
            img->set_pixel(x, y + (mc::MapZ - z), &side);
            break;
        }
      }
    }
  }

  return img;
}

Image *Level::get_obliqueangle_image(settings_t *s) {
  Image *img = new Image(mc::MapX, mc::MapY + mc::MapZ);
  return img;
}
<|endoftext|>


<commit_before>/*********************************************************************/
/* Copyright (c) 2011 - 2012, The University of Texas at Austin.     */
/* All rights reserved.                                              */
/*                                                                   */
/* Redistribution and use in source and binary forms, with or        */
/* without modification, are permitted provided that the following   */
/* conditions are met:                                               */
/*                                                                   */
/*   1. Redistributions of source code must retain the above         */
/*      copyright notice, this list of conditions and the following  */
/*      disclaimer.                                                  */
/*                                                                   */
/*   2. Redistributions in binary form must reproduce the above      */
/*      copyright notice, this list of conditions and the following  */
/*      disclaimer in the documentation and/or other materials       */
/*      provided with the distribution.                              */
/*                                                                   */
/*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
/*    AUSTIN  ``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 UNIVERSITY  OF TEXAS AT    */
/*    AUSTIN 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.                                    */
/*                                                                   */
/* The views and conclusions contained in the software and           */
/* documentation are those of the authors and should not be          */
/* interpreted as representing official policies, either expressed   */
/* or implied, of The University of Texas at Austin.                 */
/*********************************************************************/

#include "Content.h"
#include "ContentWindowManager.h"
#include "TextureContent.h"
#include "DynamicTextureContent.h"
#include "MovieContent.h"
#include "main.h"
#include "GLWindow.h"
#include <QGLWidget>

Content::Content(std::string uri)
{
    uri_ = uri;
    width_ = 0;
    height_ = 0;
}

std::string Content::getURI()
{
    return uri_;
}

void Content::getDimensions(int &width, int &height)
{
    width = width_;
    height = height_;
}

void Content::setDimensions(int width, int height)
{
    width_ = width;
    height_ = height;

    emit(dimensionsChanged(width_, height_));
}

void Content::render(boost::shared_ptr<ContentWindowManager> window)
{
    // get parameters from window
    double x, y, w, h;
    window->getCoordinates(x, y, w, h);

    double centerX, centerY;
    window->getCenter(centerX, centerY);

    double zoom = window->getZoom();

    // calculate texture coordinates
    float tX = centerX - 0.5 / zoom;
    float tY = centerY - 0.5 / zoom;
    float tW = 1./zoom;
    float tH = 1./zoom;

    // transform to a normalize coordinate system so the content can be rendered at (x,y,w,h) = (0,0,1,1)
    glPushMatrix();

    glTranslatef(x, y, 0.);
    glScalef(w, h, 1.);

    // render the factory object
    renderFactoryObject(tX, tY, tW, tH);

    // render the context view
    if(g_displayGroupManager->getOptions()->getShowZoomContext() == true && zoom > 1.)
    {
        float sizeFactor = 0.25;
        float padding = 0.02;
        float deltaZ = 0.001;
        float alpha = 0.5;
        float borderPixels = 5.;

        glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LINE_BIT);
        glPushMatrix();

        // position at lower left
        glTranslatef(padding, 1. - sizeFactor - padding, deltaZ);
        glScalef(sizeFactor, sizeFactor, 1.);

        // render border rectangle
        glColor4f(1,1,1,1);

        glLineWidth(borderPixels);

        glBegin(GL_LINE_LOOP);

        glVertex2d(0., 0.);
        glVertex2d(1., 0.);
        glVertex2d(1., 1.);
        glVertex2d(0., 1.);

        glEnd();

        // render the factory object (full view)
        glTranslatef(0., 0., deltaZ);
        renderFactoryObject(0., 0., 1., 1.);

        // draw context rectangle border
        glTranslatef(0., 0., deltaZ);

        glLineWidth(borderPixels);

        glBegin(GL_LINE_LOOP);

        glVertex2d(tX, tY);
        glVertex2d(tX + tW, tY);
        glVertex2d(tX + tW, tY + tH);
        glVertex2d(tX, tY + tH);

        glEnd();

        // draw context rectangle blended
        glTranslatef(0., 0., deltaZ);

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glColor4f(1.,1.,1., alpha);
        GLWindow::drawRectangle(tX, tY, tW, tH);

        glPopMatrix();
        glPopAttrib();
    }

    glPopMatrix();
}

boost::shared_ptr<Content> Content::getContent(std::string uri)
{
    // convert to lower case for case-insensitivity in determining file type
    QString fileTypeString = QString::fromStdString(uri).toLower();

    // see if this is an image
    QImageReader imageReader(uri.c_str());

    if(imageReader.canRead() == true)
    {
        // get its size
        QSize size = imageReader.size();

        // small images will use Texture; larger images will use DynamicTexture
        boost::shared_ptr<Content> c;

        if(size.width() <= 4096 && size.height() <= 4096)
        {
            boost::shared_ptr<Content> temp(new TextureContent(uri));
            c = temp;
        }
        else
        {
            boost::shared_ptr<Content> temp(new DynamicTextureContent(uri));
            c = temp;
        }

        // set the size if valid
        if(size.isValid() == true)
        {
            c->setDimensions(size.width(), size.height());
        }

        return c;
    }
    // see if this is a movie
    // todo: need a better way to determine file type
    else if(fileTypeString.endsWith(".mov") || fileTypeString.endsWith(".avi") || fileTypeString.endsWith(".mp4") || fileTypeString.endsWith(".mkv") || fileTypeString.endsWith(".mpg") || fileTypeString.endsWith(".flv"))
    {
        boost::shared_ptr<Content> c(new MovieContent(uri));

        return c;
    }
    // see if this is an image pyramid
    else if(fileTypeString.endsWith(".pyr"))
    {
        boost::shared_ptr<Content> c(new DynamicTextureContent(uri));

        return c;
    }

    // otherwise, return NULL
    return boost::shared_ptr<Content>();
}
<commit_msg>added .wmv movie extension.<commit_after>/*********************************************************************/
/* Copyright (c) 2011 - 2012, The University of Texas at Austin.     */
/* All rights reserved.                                              */
/*                                                                   */
/* Redistribution and use in source and binary forms, with or        */
/* without modification, are permitted provided that the following   */
/* conditions are met:                                               */
/*                                                                   */
/*   1. Redistributions of source code must retain the above         */
/*      copyright notice, this list of conditions and the following  */
/*      disclaimer.                                                  */
/*                                                                   */
/*   2. Redistributions in binary form must reproduce the above      */
/*      copyright notice, this list of conditions and the following  */
/*      disclaimer in the documentation and/or other materials       */
/*      provided with the distribution.                              */
/*                                                                   */
/*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
/*    AUSTIN  ``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 UNIVERSITY  OF TEXAS AT    */
/*    AUSTIN 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.                                    */
/*                                                                   */
/* The views and conclusions contained in the software and           */
/* documentation are those of the authors and should not be          */
/* interpreted as representing official policies, either expressed   */
/* or implied, of The University of Texas at Austin.                 */
/*********************************************************************/

#include "Content.h"
#include "ContentWindowManager.h"
#include "TextureContent.h"
#include "DynamicTextureContent.h"
#include "MovieContent.h"
#include "main.h"
#include "GLWindow.h"
#include <QGLWidget>

Content::Content(std::string uri)
{
    uri_ = uri;
    width_ = 0;
    height_ = 0;
}

std::string Content::getURI()
{
    return uri_;
}

void Content::getDimensions(int &width, int &height)
{
    width = width_;
    height = height_;
}

void Content::setDimensions(int width, int height)
{
    width_ = width;
    height_ = height;

    emit(dimensionsChanged(width_, height_));
}

void Content::render(boost::shared_ptr<ContentWindowManager> window)
{
    // get parameters from window
    double x, y, w, h;
    window->getCoordinates(x, y, w, h);

    double centerX, centerY;
    window->getCenter(centerX, centerY);

    double zoom = window->getZoom();

    // calculate texture coordinates
    float tX = centerX - 0.5 / zoom;
    float tY = centerY - 0.5 / zoom;
    float tW = 1./zoom;
    float tH = 1./zoom;

    // transform to a normalize coordinate system so the content can be rendered at (x,y,w,h) = (0,0,1,1)
    glPushMatrix();

    glTranslatef(x, y, 0.);
    glScalef(w, h, 1.);

    // render the factory object
    renderFactoryObject(tX, tY, tW, tH);

    // render the context view
    if(g_displayGroupManager->getOptions()->getShowZoomContext() == true && zoom > 1.)
    {
        float sizeFactor = 0.25;
        float padding = 0.02;
        float deltaZ = 0.001;
        float alpha = 0.5;
        float borderPixels = 5.;

        glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LINE_BIT);
        glPushMatrix();

        // position at lower left
        glTranslatef(padding, 1. - sizeFactor - padding, deltaZ);
        glScalef(sizeFactor, sizeFactor, 1.);

        // render border rectangle
        glColor4f(1,1,1,1);

        glLineWidth(borderPixels);

        glBegin(GL_LINE_LOOP);

        glVertex2d(0., 0.);
        glVertex2d(1., 0.);
        glVertex2d(1., 1.);
        glVertex2d(0., 1.);

        glEnd();

        // render the factory object (full view)
        glTranslatef(0., 0., deltaZ);
        renderFactoryObject(0., 0., 1., 1.);

        // draw context rectangle border
        glTranslatef(0., 0., deltaZ);

        glLineWidth(borderPixels);

        glBegin(GL_LINE_LOOP);

        glVertex2d(tX, tY);
        glVertex2d(tX + tW, tY);
        glVertex2d(tX + tW, tY + tH);
        glVertex2d(tX, tY + tH);

        glEnd();

        // draw context rectangle blended
        glTranslatef(0., 0., deltaZ);

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glColor4f(1.,1.,1., alpha);
        GLWindow::drawRectangle(tX, tY, tW, tH);

        glPopMatrix();
        glPopAttrib();
    }

    glPopMatrix();
}

boost::shared_ptr<Content> Content::getContent(std::string uri)
{
    // convert to lower case for case-insensitivity in determining file type
    QString fileTypeString = QString::fromStdString(uri).toLower();

    // see if this is an image
    QImageReader imageReader(uri.c_str());

    if(imageReader.canRead() == true)
    {
        // get its size
        QSize size = imageReader.size();

        // small images will use Texture; larger images will use DynamicTexture
        boost::shared_ptr<Content> c;

        if(size.width() <= 4096 && size.height() <= 4096)
        {
            boost::shared_ptr<Content> temp(new TextureContent(uri));
            c = temp;
        }
        else
        {
            boost::shared_ptr<Content> temp(new DynamicTextureContent(uri));
            c = temp;
        }

        // set the size if valid
        if(size.isValid() == true)
        {
            c->setDimensions(size.width(), size.height());
        }

        return c;
    }
    // see if this is a movie
    // todo: need a better way to determine file type
    else if(fileTypeString.endsWith(".mov") || fileTypeString.endsWith(".avi") || fileTypeString.endsWith(".mp4") || fileTypeString.endsWith(".mkv") || fileTypeString.endsWith(".mpg") || fileTypeString.endsWith(".flv") || fileTypeString.endsWith(".wmv"))
    {
        boost::shared_ptr<Content> c(new MovieContent(uri));

        return c;
    }
    // see if this is an image pyramid
    else if(fileTypeString.endsWith(".pyr"))
    {
        boost::shared_ptr<Content> c(new DynamicTextureContent(uri));

        return c;
    }

    // otherwise, return NULL
    return boost::shared_ptr<Content>();
}
<|endoftext|>


<commit_before>#include "StateMachine.h"

#include <regex>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <map>
#include <list>
#include <set>

template <typename State>
std::string stringState(State state);

template <>
std::string stringState<std::string>(std::string state) {
  return state;
}

template <>
std::string stringState<std::set<std::string>>(std::set<std::string> states) {
  std::string newState = ":";
  for (auto state : states) {
    newState += state + ":";
  }
  return newState;
}

template <typename Input, typename State>
struct Automata {
  typedef std::multimap<Input, State>       Transitions;
  typedef std::map     <State, Transitions> StateChanges;
  typedef std::set     <State>              States;
  typedef std::set     <Input>              Inputs;
  typedef std::set     <State>              AcceptableStates;

  Automata(State initialState, StateChanges changes, AcceptableStates acceptableStates)
    : currentState_     (initialState)
    , stateChanges_     (changes)
    , acceptableStates_ (acceptableStates) {
  }

  State state() const {
    return currentState_;
  }

  StateChanges changes() const {
    return stateChanges_;
  }

  States acceptable() const {
    return acceptableStates_;
  }

  std::string toString() const {
    std::stringstream str;

    for (auto s : stateChanges_) {
      str << "state: " << stringState(s.first) << std::endl;
      for (auto t : s.second) {
        str << "\t  on \'"  << t.first  << "\' ";
        str << "goto " << stringState(t.second) << std::endl;
      }
    }
    str << "acceptable: " << std::endl;
    for (auto s : acceptableStates_) {
      str << "\t  " << stringState(s) << std::endl;
    }

    return str.str();
  }

  Automata prefix(const std::string& prefix) const {
    StateChanges states;
    for (auto s : stateChanges_) {
      for (auto t : s.second) {
        states[prefix + s.first].insert(std::make_pair(t.first, prefix + t.second));
      }
    }
    AcceptableStates accept;
    for (auto a : acceptableStates_) {
      accept.insert(prefix + a);
    }
    return Automata(prefix  + currentState_, states, accept);
  };

  Automata<Input, States> realize() {
    // 1. Create the start state of the DFA by taking the e-closure of the start state
    //    of the NFA.
    // 2. Perform the following for the new DFA state:
    //    For each possible input symbol:
    //    1. Apply move to the newly-created state and the input symbol; this will return
    //       a set of states.
    //    2. Apply the e-closure to this set of states, possibly resulting in a new set.
    //
    // This set of NFA states will be a single state in the DFA.
    // 3. Each time we generate a new DFA state, we must apply step 2 to it. The process
    //    is complete when applying step 2 does not yield any new states.
    // 4. The finish states of the DFA are those which contain any of the finish states
    //    of the NFA.
    typename Automata<Input, States>::StateChanges changes;
    typename Automata<Input, States>::States       acceptable;
    auto dfaState     = closure({currentState_}); //TODO initial state isn't current...
    auto initialState = dfaState;

    std::function<void (States)> simulate =
    [&](States state) {
      changes[state].insert({});
      for (auto i : inputs(state)) {
        auto newState = closure(move(state, i));
        if (i != '\0') {
          changes[state].insert(std::make_pair(i, newState));
          simulate(newState);
        }
      }
    };

    simulate(initialState);

    // acceptable states

    return Automata<Input, States>(initialState, changes, acceptable);
  }

  Inputs inputs(States states) {
    Inputs inputStates;

    for (auto state : states) {
      auto transitions        = stateChanges_.find(state);
      if (transitions != stateChanges_.end()) {
        for (auto transition : transitions->second) {
          inputStates.insert(transition.first);
        }
      }
    }
    return inputStates;
  }

  States closure(States states) {
    States closureStates = states;
    // The e-closure function takes a state and returns the set of states reachable
    // from it based on (one or more) e-transitions. Note that this will always
    // include the state tself. We should be able to get from a state to any state
    // in its e-closure without consuming any input.
    for (auto state : states) {
      auto transitions        = stateChanges_.find(state);
      if (transitions != stateChanges_.end()) {
        auto epsilonTransitions = transitions->second.equal_range('\0');
        for (auto epsilon  = epsilonTransitions.first;
                  epsilon != epsilonTransitions.second;
                ++epsilon) {
          if (!closureStates.count(epsilon->second)) {
            auto nextStates = closure({epsilon->second});
            closureStates.insert(nextStates.begin(), nextStates.end());
          }
        }
      }
    }

    return closureStates;
  }

  States move(States states, Input input) {
    States moveStates;
    // The function move takes a state and a character, and returns the set of
    // states reachable by one transition on this character.
    for (auto state : states) {
      auto transitions = stateChanges_.find(state);
      if (transitions != stateChanges_.end()) {
        auto matches     = transitions->second.equal_range(input);
        for (auto transition  = matches.first;
                  transition != matches.second;
                ++transition) {
          moveStates.insert(transition->second);
        }
      }
    }

    return closure(moveStates);
  };
protected:

private:
  State        currentState_;
  StateChanges stateChanges_;
  States       acceptableStates_;
};

typedef Automata<char, std::string> StringAutomata;

int main () {
  std::cout << "Lexer Test" << std::endl;
  typedef std::string                       Input;
  typedef std::string                       Token;
  typedef std::string                       State;

  typedef std::map<Input, std::list<State>> NfaTransitions;
  typedef std::map<State, NfaTransitions>   NfaStates;
  typedef std::tuple<State, NfaStates, std::list<State>>    Nfa;

  typedef std::map<Input, State>            DfaTransitions;
  typedef std::map<State, DfaTransitions>   DfaStates;
  typedef std::tuple<State, DfaStates>      Dfa;

  auto fsm = DfaStates({
    { "even", {
      {"0",  "even"},
      {"1",  "odd"},
      {"\a", "even"},
    }},
    { "odd",  {
      {"1",  "even"},
      {"0",  "odd"},
      {"\a", "odd"},
    }},
  });

  auto dfa_exec = [](Dfa& m, Input input) {
    auto& state  = std::get<0>(m);
    auto& states = std::get<1>(m);
    state = states.at(state).at(input);
    std::cout << "input = " << input << ", state = " << state << std::endl;
  };

  auto dfa_accept = [](Dfa& m) -> Token {
    auto& state  = std::get<0>(m);
    auto& states = std::get<1>(m);
    return states.at(state).at("\a");
  };

  auto re_symbol = [](char c) -> StringAutomata {
    auto states = StringAutomata::StateChanges({
      {
        { "0", { {c,  "1"} } },
        { "1", { StringAutomata::Transitions({}) } },
      }
    });

    return StringAutomata("0", states, {"1"});
  };

  auto re_union = [&](const StringAutomata& a, const StringAutomata& b) -> StringAutomata {
    auto re_a   = a.prefix("a.");
    auto re_b   = b.prefix("b.");

    auto a_state  = re_a.state();
    auto a_states = re_a.changes();
    auto a_accept = re_a.acceptable();
    auto b_state  = re_b.state();
    auto b_states = re_b.changes();
    auto b_accept = re_b.acceptable();

    auto states = StringAutomata::StateChanges({
      {
        { "0", { StringAutomata::Transitions({}) } },
        { "1", { StringAutomata::Transitions({}) } },
      }
    });

    // Epsilon transitions
    states["0"].insert(std::make_pair('\0', a_state));
    states["0"].insert(std::make_pair('\0', b_state));

    // Subexpressions
    for (auto s : a_states) {
      states[s.first] = s.second;
    }
    for (auto s : b_states) {
      states[s.first] = s.second;
    }

    //  Acceptors
    for (auto a : a_accept) {
      states[a].insert(std::make_pair('\0', "1"));
    }
    for (auto b : b_accept) {
      states[b].insert(std::make_pair('\0', "1"));
    }

    return StringAutomata("0", states, {"1"});
  };

  auto re = re_union(re_symbol('a'), re_union(re_symbol('b'), re_symbol('c')));
  //auto re = re_union(re_symbol('a'), re_symbol('b'));
  //auto re = re_symbol('a');

  std::cout << re.toString() << std::endl;
  std::cout << std::endl;
  std::cout << re.realize().toString() << std::endl;

  try {
  /*
    Dfa m = {"even", fsm};
    dfa_exec(m, "0");
    dfa_exec(m, "1");
    dfa_exec(m, "1");
    dfa_exec(m, "1");
    dfa_exec(m, "1");
    dfa_exec(m, "1");
    dfa_exec(m, "0");
    std::cout << " yield = " << dfa_accept(m) << std::endl;
  */
  } catch (std::exception& e) {
    std::cout << "error: " << e.what() << std::endl;
  }
}
<commit_msg>this is going somewhere...<commit_after>#include "StateMachine.h"

#include <regex>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <map>
#include <list>
#include <set>

template <typename State>
std::string stringState(State state);

template <>
std::string stringState<std::string>(std::string state) {
  return state;
}

template <>
std::string stringState<std::set<std::string>>(std::set<std::string> states) {
  std::string newState = ":";
  for (auto state : states) {
    newState += state + ":";
  }
  return newState;
}

template <typename Input, typename State>
struct Automata {
  typedef std::multimap<Input, State>       Transitions;
  typedef std::map     <State, Transitions> StateChanges;
  typedef std::set     <State>              States;
  typedef std::set     <Input>              Inputs;
  typedef std::set     <State>              AcceptableStates;

  Automata(State initialState, StateChanges changes, AcceptableStates acceptableStates)
    : currentState_     (initialState)
    , initialState_     (initialState)
    , stateChanges_     (changes)
    , acceptableStates_ (acceptableStates) {
  }

  State state() const {
    return currentState_;
  }

  State initial() const {
    return initialState_;
  }

  StateChanges changes() const {
    return stateChanges_;
  }

  States acceptable() const {
    return acceptableStates_;
  }

  void exec(Input input) {
    auto transition = stateChanges_.at(currentState_);
    if (transition.count(input) > 1) {
      throw std::runtime_error("need to realize NFA");
    }
    if (transition.count(input) == 0) {
      throw std::runtime_error("illegal state transition");
    }
    auto newState = transition.find(input);
    if (newState != transition.end()) {
      currentState_ = newState->second;
    }
  };

  bool accept () {
    return acceptableStates_.count(currentState_) > 0;
  };

  std::string toString() const {
    std::stringstream str;

    for (auto s : stateChanges_) {
      str << "state: " << stringState(s.first) << std::endl;
      for (auto t : s.second) {
        str << "\t  on \'"  << t.first  << "\' ";
        str << "goto " << stringState(t.second) << std::endl;
      }
    }
    str << "acceptable: " << std::endl;
    for (auto s : acceptableStates_) {
      str << "\t  " << stringState(s) << std::endl;
    }

    return str.str();
  }

  Automata prefix(const std::string& prefix) const {
    StateChanges states;
    for (auto s : stateChanges_) {
      for (auto t : s.second) {
        states[prefix + s.first].insert(std::make_pair(t.first, prefix + t.second));
      }
    }
    AcceptableStates accept;
    for (auto a : acceptableStates_) {
      accept.insert(prefix + a);
    }
    return Automata(prefix  + initialState_, states, accept);
  };

  Automata<Input, States> realize() const {
    // 1. Create the start state of the DFA by taking the e-closure of the start state
    //    of the NFA.
    // 2. Perform the following for the new DFA state:
    //    For each possible input symbol:
    //    1. Apply move to the newly-created state and the input symbol; this will return
    //       a set of states.
    //    2. Apply the e-closure to this set of states, possibly resulting in a new set.
    //
    // This set of NFA states will be a single state in the DFA.
    // 3. Each time we generate a new DFA state, we must apply step 2 to it. The process
    //    is complete when applying step 2 does not yield any new states.
    // 4. The finish states of the DFA are those which contain any of the finish states
    //    of the NFA.
    typename Automata<Input, States>::StateChanges changes;
    typename Automata<Input, States>::States       acceptable;
    auto dfaState     = closure({initialState_});
    auto initialState = dfaState;

    std::function<void (States)> simulate = [&](States state) {
      if (!changes.count(state)) {
        changes[state].insert({});
        for (auto i : inputs(state)) {
          auto newState = closure(move(state, i));
          if (i != '\0') {
            changes[state].insert(std::make_pair(i, newState));
            simulate(newState);
          }
        }
      }
    };

    simulate(initialState);

    for (auto a : acceptableStates_) {
      for (auto s : changes) {
        if (s.first.count(a)) {
          acceptable.insert(s.first);
        }
      }
    }
    // acceptable states

    return Automata<Input, States>(initialState, changes, acceptable);
  }

  Inputs inputs(States states) const {
    Inputs inputStates;

    for (auto state : states) {
      auto transitions        = stateChanges_.find(state);
      if (transitions != stateChanges_.end()) {
        for (auto transition : transitions->second) {
          inputStates.insert(transition.first);
        }
      }
    }
    return inputStates;
  }

  States closure(States states) const {
    States closureStates = states;
    // The e-closure function takes a state and returns the set of states reachable
    // from it based on (one or more) e-transitions. Note that this will always
    // include the state tself. We should be able to get from a state to any state
    // in its e-closure without consuming any input.
    for (auto state : states) {
      auto transitions        = stateChanges_.find(state);
      if (transitions != stateChanges_.end()) {
        auto epsilonTransitions = transitions->second.equal_range('\0');
        for (auto epsilon  = epsilonTransitions.first;
                  epsilon != epsilonTransitions.second;
                ++epsilon) {
          if (!closureStates.count(epsilon->second)) {
            auto nextStates = closure({epsilon->second});
            closureStates.insert(nextStates.begin(), nextStates.end());
          }
        }
      }
    }

    return closureStates;
  }

  States move(States states, Input input) const {
    States moveStates;
    // The function move takes a state and a character, and returns the set of
    // states reachable by one transition on this character.
    for (auto state : states) {
      auto transitions = stateChanges_.find(state);
      if (transitions != stateChanges_.end()) {
        auto matches     = transitions->second.equal_range(input);
        for (auto transition  = matches.first;
                  transition != matches.second;
                ++transition) {
          moveStates.insert(transition->second);
        }
      }
    }

    return closure(moveStates);
  };
protected:

private:
  State        currentState_;
  State        initialState_;
  StateChanges stateChanges_;
  States       acceptableStates_;
};

typedef Automata<char, std::string> StringAutomata;

auto re_symbol = [](char c) -> StringAutomata {
  auto states = StringAutomata::StateChanges({
    {
      { "0", { {c,  "1"} } },
      { "1", { StringAutomata::Transitions({}) } },
    }
  });

  return StringAutomata("0", states, {"1"});
};

auto re_union = [&](const StringAutomata& a, const StringAutomata& b) -> StringAutomata {
  auto re_a   = a.prefix("a.");
  auto re_b   = b.prefix("b.");

  auto states = StringAutomata::StateChanges({
    {
      { "0", { StringAutomata::Transitions({}) } },
      { "1", { StringAutomata::Transitions({}) } },
    }
  });

  // Epsilon transitions
  states["0"].insert(std::make_pair('\0', re_a.initial()));
  states["0"].insert(std::make_pair('\0', re_b.initial()));

  // Subexpressions
  for (auto s : re_a.changes()) {
    states[s.first] = s.second;
  }
  for (auto s : re_b.changes()) {
    states[s.first] = s.second;
  }

  //  Acceptors
  for (auto a : re_a.acceptable()) {
    states[a].insert(std::make_pair('\0', "1"));
  }
  for (auto b : re_b.acceptable()) {
    states[b].insert(std::make_pair('\0', "1"));
  }

  return StringAutomata("0", states, {"1"});
};

auto re_concat = [&](const StringAutomata& a, const StringAutomata& b) -> StringAutomata {
  auto re_a   = a.prefix("a.");
  auto re_b   = b.prefix("b.");

  auto a_states = re_a.changes();
  auto b_states = re_b.changes();

  auto states = StringAutomata::StateChanges({});
  states.insert(a_states.begin(), a_states.end());
  states.insert(b_states.begin(), b_states.end());

  for (auto a : re_a.acceptable()) {
    states[a].insert(std::make_pair('\0', re_b.initial()));
  }

  for (auto b : re_b.acceptable()) {
    states[b].insert(std::make_pair('\0', "1"));
  }

  return StringAutomata(re_a.initial(), states, {"1"});
};

auto re_star = [&](const StringAutomata& a) -> StringAutomata {
  auto re_a   = a.prefix("a.");

  auto states = StringAutomata::StateChanges({
    {
      { "0", { StringAutomata::Transitions({}) } },
      { "1", { StringAutomata::Transitions({}) } },
    }
  });

  // Epsilon transitions
  states["0"].insert(std::make_pair('\0', re_a.initial()));
  states["0"].insert(std::make_pair('\0', "1"));

  // Subexpressions
  for (auto s : re_a.changes()) {
    states[s.first] = s.second;
  }

  //  Acceptors
  for (auto a : re_a.acceptable()) {
    states[a].insert(std::make_pair('\0', "1"));
    states[a].insert(std::make_pair('\0', re_a.initial()));
  }

  return StringAutomata("0", states, {"1"});
};

StringAutomata operator+ (const StringAutomata& a, const StringAutomata& b) {
  return re_concat(a,b);
}

StringAutomata operator| (const StringAutomata& a, const StringAutomata& b) {
  return re_union(a,b);
}

StringAutomata operator* (const StringAutomata& a) {
  return re_star(a);
}

StringAutomata match(const std::string& str) {
  StringAutomata automata = re_symbol(str[0]);
  for (size_t i = 1; i < str.length(); i++) {
    automata = automata + re_symbol(str[i]);
  }
  return automata;
}

int main () {
  std::cout << "Lexer Test" << std::endl;

  try {
    auto re     = *(match("cat") | re_symbol('b') | (re_symbol('c') + re_symbol('d')));
    auto re_dfa = re.realize();

    std::cout << re.toString() << std::endl;
    std::cout << re_dfa.toString() << std::endl;
    re_dfa.exec('b');
    re_dfa.exec('c');
    re_dfa.exec('d');
    re_dfa.exec('c');
    re_dfa.exec('d');
    if (!re_dfa.accept()) {
      throw std::runtime_error("not an acceptable state");
    }
  } catch (std::exception& e) {
    std::cout << "error: " << e.what() << std::endl;
  }
}
<|endoftext|>


<commit_before>#include "CryFuse.h"

#include <sys/types.h>
#include <sys/time.h>
#include <dirent.h>
#include <cassert>

#define UNUSED(expr) (void)(expr)

using fusepp::path;

namespace cryfs {

namespace {
  int errcode_map(int exit_status) {
    if (exit_status < 0) {
      return -errno;
    }
    return exit_status;
  }
}

CryFuse::CryFuse(CryDevice *device)
  :_device(device) {
}

int CryFuse::getattr(const path &path, struct stat *stbuf) {
  UNUSED(stbuf);
  //printf("getattr(%s, _)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  int retstat = lstat(real_path.c_str(), stbuf);
  return errcode_map(retstat);
}

int CryFuse::fgetattr(const path &path, struct stat *stbuf, fuse_file_info *fileinfo) {
  //printf("fgetattr(%s, _, _)\n", path.c_str());

  // On FreeBSD, trying to do anything with the mountpoint ends up
  // opening it, and then using the FD for an fgetattr.  So in the
  // special case of a path of "/", I need to do a getattr on the
  // underlying root directory instead of doing the fgetattr().
  if (path.native() == "/") {
    return getattr(path, stbuf);
  }

  int retstat = fstat(fileinfo->fh, stbuf);
  return errcode_map(retstat);
}

int CryFuse::readlink(const path &path, char *buf, size_t size) {
  //printf("readlink(%s, _, %zu)\n", path.c_str(), size);
  auto real_path = _device->RootDir() / path;
  //size-1, because the fuse readlink() function includes the null terminating byte in the buffer size,
  //but the posix version does not and also doesn't append one.
  int real_size = ::readlink(real_path.c_str(), buf, size-1);
  if (real_size < 0) {
    return -errno;
  }
  //Terminate the string
  buf[real_size] = '\0';

  return 0;
}

int CryFuse::mknod(const path &path, mode_t mode, dev_t rdev) {
  UNUSED(rdev);
  //printf("Called non-implemented mknod(%s, %d, _)\n", path.c_str(), mode);
  return 0;
}

int CryFuse::mkdir(const path &path, mode_t mode) {
  //printf("mkdir(%s, %d)\n", path.c_str(), mode);
  auto real_path = _device->RootDir() / path;
  int retstat = ::mkdir(real_path.c_str(), mode);
  return errcode_map(retstat);
}

int CryFuse::unlink(const path &path) {
  //printf("unlink(%s)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  int retstat = ::unlink(real_path.c_str());
  return errcode_map(retstat);
}

int CryFuse::rmdir(const path &path) {
  //printf("rmdir(%s)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  int retstat = ::rmdir(real_path.c_str());
  return errcode_map(retstat);
}

int CryFuse::symlink(const path &from, const path &to) {
  //printf("symlink(%s, %s)\n", from.c_str(), to.c_str());
  auto real_from = _device->RootDir() / from;
  auto real_to = _device->RootDir() / to;
  int retstat = ::symlink(real_from.c_str(), real_to.c_str());
  return errcode_map(retstat);
}

int CryFuse::rename(const path &from, const path &to) {
  //printf("rename(%s, %s)\n", from.c_str(), to.c_str());
  auto real_from = _device->RootDir() / from;
  auto real_to = _device->RootDir() / to;
  int retstat = ::rename(real_from.c_str(), real_to.c_str());
  return errcode_map(retstat);
}

int CryFuse::link(const path &from, const path &to) {
  //printf("link(%s, %s)\n", from.c_str(), to.c_str());
  auto real_from = _device->RootDir() / from;
  auto real_to = _device->RootDir() / to;
  int retstat = ::link(real_from.c_str(), real_to.c_str());
  return errcode_map(retstat);
}

int CryFuse::chmod(const path &path, mode_t mode) {
  //printf("chmod(%s, %d)\n", path.c_str(), mode);
  auto real_path = _device->RootDir() / path;
  int retstat = ::chmod(real_path.c_str(), mode);
  return errcode_map(retstat);
}

int CryFuse::chown(const path &path, uid_t uid, gid_t gid) {
  //printf("chown(%s, %d, %d)\n", path.c_str(), uid, gid);
  auto real_path = _device->RootDir() / path;
  int retstat = ::chown(real_path.c_str(), uid, gid);
  return errcode_map(retstat);
}

int CryFuse::truncate(const path &path, off_t size) {
  //printf("truncate(%s, %zu)\n", path.c_str(), size);
  auto real_path = _device->RootDir() / path;
  int retstat = ::truncate(real_path.c_str(), size);
  return errcode_map(retstat);
}

int CryFuse::ftruncate(const path &path, off_t size, fuse_file_info *fileinfo) {
  //printf("ftruncate(%s, %zu, _)\n", path.c_str(), size);
  int retstat = ::ftruncate(fileinfo->fh, size);
  return errcode_map(retstat);
}

int CryFuse::utimens(const path &path, const timespec times[2]) {
  //printf("utimens(%s, _)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  struct timeval tv[2];
  tv[0].tv_sec = times[0].tv_sec;
  tv[0].tv_usec = times[0].tv_nsec / 1000;
  tv[1].tv_sec = times[1].tv_sec;
  tv[1].tv_usec = times[1].tv_nsec / 1000;
  int retstat = ::lutimes(real_path.c_str(), tv);
  return errcode_map(retstat);
}

int CryFuse::open(const path &path, fuse_file_info *fileinfo) {
  //printf("open(%s, _)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  int fd = ::open(real_path.c_str(), fileinfo->flags);
  if (fd < 0) {
    return -errno;
  }
  fileinfo->fh = fd;
  return 0;
}

int CryFuse::release(const path &path, fuse_file_info *fileinfo) {
  //printf("release(%s, _)\n", path.c_str());
  int retstat = ::close(fileinfo->fh);
  return errcode_map(retstat);
}

int CryFuse::read(const path &path, char *buf, size_t size, off_t offset, fuse_file_info *fileinfo) {
  //printf("read(%s, _, %zu, %zu, _)\n", path.c_str(), size, offset);
  int retstat = ::pread(fileinfo->fh, buf, size, offset);
  return errcode_map(retstat);
}

int CryFuse::write(const path &path, const char *buf, size_t size, off_t offset, fuse_file_info *fileinfo) {
  //printf("write(%s, _, %zu, %zu, _)\n", path.c_str(), size, offset);
  int retstat = ::pwrite(fileinfo->fh, buf, size, offset);
  return errcode_map(retstat);
}

int CryFuse::statfs(const path &path, struct statvfs *fsstat) {
  //printf("statfs(%s, _)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  int retstat = ::statvfs(real_path.c_str(), fsstat);
  return errcode_map(retstat);
}

int CryFuse::flush(const path &path, fuse_file_info *fileinfo) {
  //printf("Called non-implemented flush(%s, _)\n", path.c_str());
  return 0;
}

int CryFuse::fsync(const path &path, int datasync, fuse_file_info *fileinfo) {
  //printf("fsync(%s, %d, _)\n", path.c_str(), datasync);
  int retstat = 0;
  if (datasync) {
    retstat = ::fdatasync(fileinfo->fh);
  } else {
    retstat = ::fsync(fileinfo->fh);
  }
  return errcode_map(retstat);
}

int CryFuse::opendir(const path &path, fuse_file_info *fileinfo) {
  //printf("opendir(%s, _)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  DIR *dp = ::opendir(real_path.c_str());
  if (dp == nullptr) {
    return -errno;
  }
  fileinfo->fh = (intptr_t)dp;
  return 0;
}

int CryFuse::readdir(const path &path, void *buf, fuse_fill_dir_t filler, off_t offset, fuse_file_info *fileinfo) {
  //printf("readdir(%s, _, _, %zu, _)\n", path.c_str(), offset);
  auto real_path = _device->RootDir() / path;

  DIR *dp = (DIR*)(uintptr_t)fileinfo->fh;
  struct dirent *de = ::readdir(dp);
  if (de == nullptr) {
    return -errno;
  }

  do {
    if (filler(buf, de->d_name, nullptr, 0) != 0) {
      return -ENOMEM;
    }
  } while ((de = ::readdir(dp)) != nullptr);

  return 0;
}

int CryFuse::releasedir(const path &path, fuse_file_info *fileinfo) {
  //printf("releasedir(%s, _)\n", path.c_str());
  int retstat = closedir((DIR*)(uintptr_t)fileinfo->fh);
  return errcode_map(retstat);
}

int CryFuse::fsyncdir(const path &path, int datasync, fuse_file_info *fileinfo) {
  UNUSED(fileinfo);
  //printf("Called non-implemented fsyncdir(%s, %d, _)\n", path.c_str(), datasync);
  return 0;
}

void CryFuse::init(fuse_conn_info *conn) {
  UNUSED(conn);
  //printf("init()\n");
}

void CryFuse::destroy() {
  //printf("destroy()\n");
}

int CryFuse::access(const path &path, int mask) {
  //printf("access(%s, %d)\n", path.c_str(), mask);
  auto real_path = _device->RootDir() / path;
  int retstat = ::access(real_path.c_str(), mask);
  return errcode_map(retstat);
}

int CryFuse::create(const path &path, mode_t mode, fuse_file_info *fileinfo) {
  //printf("create(%s, %d, _)\n", path.c_str(), mode);
  auto real_path = _device->RootDir() / path;
  int fd = ::creat(real_path.c_str(), mode);
  if (fd < 0) {
    return -errno;
  }
  fileinfo->fh = fd;
  return 0;
}

} /* namespace cryfs */
<commit_msg>Fix some stuff and make getattr go through our class structure<commit_after>#include "CryFuse.h"

#include <sys/types.h>
#include <sys/time.h>
#include <dirent.h>
#include <cassert>

#include "cryfs_lib/CryNode.h"
#include "cryfs_lib/CryErrnoException.h"

#define UNUSED(expr) (void)(expr)

using fusepp::path;

namespace cryfs {

namespace {
  int errcode_map(int exit_status) {
    if (exit_status < 0) {
      return -errno;
    }
    return exit_status;
  }
}

CryFuse::CryFuse(CryDevice *device)
  :_device(device) {
}

int CryFuse::getattr(const path &path, struct stat *stbuf) {
  try {
    _device->LoadFromPath(path)->stat(stbuf);
    return 0;
  } catch(cryfs::CryErrnoException &e) {
    return -e.getErrno();
  }
}

int CryFuse::fgetattr(const path &path, struct stat *stbuf, fuse_file_info *fileinfo) {
  //printf("fgetattr(%s, _, _)\n", path.c_str());

  // On FreeBSD, trying to do anything with the mountpoint ends up
  // opening it, and then using the FD for an fgetattr.  So in the
  // special case of a path of "/", I need to do a getattr on the
  // underlying root directory instead of doing the fgetattr().
  if (path.native() == "/") {
    return getattr(path, stbuf);
  }

  int retstat = fstat(fileinfo->fh, stbuf);
  return errcode_map(retstat);
}

int CryFuse::readlink(const path &path, char *buf, size_t size) {
  //printf("readlink(%s, _, %zu)\n", path.c_str(), size);
  auto real_path = _device->RootDir() / path;
  //size-1, because the fuse readlink() function includes the null terminating byte in the buffer size,
  //but the posix version does not and also doesn't append one.
  int real_size = ::readlink(real_path.c_str(), buf, size-1);
  if (real_size < 0) {
    return -errno;
  }
  //Terminate the string
  buf[real_size] = '\0';

  return 0;
}

int CryFuse::mknod(const path &path, mode_t mode, dev_t rdev) {
  UNUSED(rdev);
  //printf("Called non-implemented mknod(%s, %d, _)\n", path.c_str(), mode);
  return 0;
}

int CryFuse::mkdir(const path &path, mode_t mode) {
  //printf("mkdir(%s, %d)\n", path.c_str(), mode);
  auto real_path = _device->RootDir() / path;
  int retstat = ::mkdir(real_path.c_str(), mode);
  return errcode_map(retstat);
}

int CryFuse::unlink(const path &path) {
  //printf("unlink(%s)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  int retstat = ::unlink(real_path.c_str());
  return errcode_map(retstat);
}

int CryFuse::rmdir(const path &path) {
  //printf("rmdir(%s)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  int retstat = ::rmdir(real_path.c_str());
  return errcode_map(retstat);
}

int CryFuse::symlink(const path &from, const path &to) {
  //printf("symlink(%s, %s)\n", from.c_str(), to.c_str());
  auto real_from = _device->RootDir() / from;
  auto real_to = _device->RootDir() / to;
  int retstat = ::symlink(real_from.c_str(), real_to.c_str());
  return errcode_map(retstat);
}

int CryFuse::rename(const path &from, const path &to) {
  //printf("rename(%s, %s)\n", from.c_str(), to.c_str());
  auto real_from = _device->RootDir() / from;
  auto real_to = _device->RootDir() / to;
  int retstat = ::rename(real_from.c_str(), real_to.c_str());
  return errcode_map(retstat);
}

int CryFuse::link(const path &from, const path &to) {
  //printf("link(%s, %s)\n", from.c_str(), to.c_str());
  auto real_from = _device->RootDir() / from;
  auto real_to = _device->RootDir() / to;
  int retstat = ::link(real_from.c_str(), real_to.c_str());
  return errcode_map(retstat);
}

int CryFuse::chmod(const path &path, mode_t mode) {
  //printf("chmod(%s, %d)\n", path.c_str(), mode);
  auto real_path = _device->RootDir() / path;
  int retstat = ::chmod(real_path.c_str(), mode);
  return errcode_map(retstat);
}

int CryFuse::chown(const path &path, uid_t uid, gid_t gid) {
  //printf("chown(%s, %d, %d)\n", path.c_str(), uid, gid);
  auto real_path = _device->RootDir() / path;
  int retstat = ::chown(real_path.c_str(), uid, gid);
  return errcode_map(retstat);
}

int CryFuse::truncate(const path &path, off_t size) {
  //printf("truncate(%s, %zu)\n", path.c_str(), size);
  auto real_path = _device->RootDir() / path;
  int retstat = ::truncate(real_path.c_str(), size);
  return errcode_map(retstat);
}

int CryFuse::ftruncate(const path &path, off_t size, fuse_file_info *fileinfo) {
  //printf("ftruncate(%s, %zu, _)\n", path.c_str(), size);
  int retstat = ::ftruncate(fileinfo->fh, size);
  return errcode_map(retstat);
}

int CryFuse::utimens(const path &path, const timespec times[2]) {
  //printf("utimens(%s, _)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  struct timeval tv[2];
  tv[0].tv_sec = times[0].tv_sec;
  tv[0].tv_usec = times[0].tv_nsec / 1000;
  tv[1].tv_sec = times[1].tv_sec;
  tv[1].tv_usec = times[1].tv_nsec / 1000;
  int retstat = ::lutimes(real_path.c_str(), tv);
  return errcode_map(retstat);
}

int CryFuse::open(const path &path, fuse_file_info *fileinfo) {
  //printf("open(%s, _)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  int fd = ::open(real_path.c_str(), fileinfo->flags);
  if (fd < 0) {
    return -errno;
  }
  fileinfo->fh = fd;
  return 0;
}

int CryFuse::release(const path &path, fuse_file_info *fileinfo) {
  //printf("release(%s, _)\n", path.c_str());
  int retstat = ::close(fileinfo->fh);
  return errcode_map(retstat);
}

int CryFuse::read(const path &path, char *buf, size_t size, off_t offset, fuse_file_info *fileinfo) {
  //printf("read(%s, _, %zu, %zu, _)\n", path.c_str(), size, offset);
  int retstat = ::pread(fileinfo->fh, buf, size, offset);
  return errcode_map(retstat);
}

int CryFuse::write(const path &path, const char *buf, size_t size, off_t offset, fuse_file_info *fileinfo) {
  //printf("write(%s, _, %zu, %zu, _)\n", path.c_str(), size, offset);
  int retstat = ::pwrite(fileinfo->fh, buf, size, offset);
  return errcode_map(retstat);
}

int CryFuse::statfs(const path &path, struct statvfs *fsstat) {
  //printf("statfs(%s, _)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  int retstat = ::statvfs(real_path.c_str(), fsstat);
  return errcode_map(retstat);
}

int CryFuse::flush(const path &path, fuse_file_info *fileinfo) {
  //printf("Called non-implemented flush(%s, _)\n", path.c_str());
  return 0;
}

int CryFuse::fsync(const path &path, int datasync, fuse_file_info *fileinfo) {
  //printf("fsync(%s, %d, _)\n", path.c_str(), datasync);
  int retstat = 0;
  if (datasync) {
    retstat = ::fdatasync(fileinfo->fh);
  } else {
    retstat = ::fsync(fileinfo->fh);
  }
  return errcode_map(retstat);
}

int CryFuse::opendir(const path &path, fuse_file_info *fileinfo) {
  //printf("opendir(%s, _)\n", path.c_str());
  auto real_path = _device->RootDir() / path;
  DIR *dp = ::opendir(real_path.c_str());
  if (dp == nullptr) {
    return -errno;
  }
  fileinfo->fh = (intptr_t)dp;
  return 0;
}

int CryFuse::readdir(const path &path, void *buf, fuse_fill_dir_t filler, off_t offset, fuse_file_info *fileinfo) {
  //printf("readdir(%s, _, _, %zu, _)\n", path.c_str(), offset);
  auto real_path = _device->RootDir() / path;

  DIR *dp = (DIR*)(uintptr_t)fileinfo->fh;
  struct dirent *de = ::readdir(dp);
  if (de == nullptr) {
    return -errno;
  }

  do {
    if (filler(buf, de->d_name, nullptr, 0) != 0) {
      return -ENOMEM;
    }
  } while ((de = ::readdir(dp)) != nullptr);

  return 0;
}

int CryFuse::releasedir(const path &path, fuse_file_info *fileinfo) {
  //printf("releasedir(%s, _)\n", path.c_str());
  int retstat = closedir((DIR*)(uintptr_t)fileinfo->fh);
  return errcode_map(retstat);
}

int CryFuse::fsyncdir(const path &path, int datasync, fuse_file_info *fileinfo) {
  UNUSED(fileinfo);
  //printf("Called non-implemented fsyncdir(%s, %d, _)\n", path.c_str(), datasync);
  return 0;
}

void CryFuse::init(fuse_conn_info *conn) {
  UNUSED(conn);
  //printf("init()\n");
}

void CryFuse::destroy() {
  //printf("destroy()\n");
}

int CryFuse::access(const path &path, int mask) {
  //printf("access(%s, %d)\n", path.c_str(), mask);
  auto real_path = _device->RootDir() / path;
  int retstat = ::access(real_path.c_str(), mask);
  return errcode_map(retstat);
}

int CryFuse::create(const path &path, mode_t mode, fuse_file_info *fileinfo) {
  //printf("create(%s, %d, _)\n", path.c_str(), mode);
  auto real_path = _device->RootDir() / path;
  int fd = ::creat(real_path.c_str(), mode);
  if (fd < 0) {
    return -errno;
  }
  fileinfo->fh = fd;
  return 0;
}

} /* namespace cryfs */
<|endoftext|>