<commit_before>AliAnalysisTaskSE *AddTaskSigma0Run2(bool isRun1 = false, bool isMC = false, bool isHeavyIon = false,
                                     TString trigger = "kINT7",
                                     const char *cutVariation = "0") {
  TString suffix;
  suffix.Form("%s", cutVariation);

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskSigma0Run2()", "No analysis manager found.");
    return 0x0;
  }

  // ================== GetInputEventHandler =============================
  AliVEventHandler *inputHandler = mgr->GetInputEventHandler();
  AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();

  //=========  Set Cutnumber for V0Reader ================================
  TString cutnumberPhoton;
  cutnumberPhoton = "00200008400000002280920000";
  TString cutnumberEvent = "00000000";
  if (suffix == "0") {
    // Borissov cuts
    cutnumberPhoton = "00200008400020002282020000";
    cutnumberEvent = "00000003";
  }
  TString periodNameV0Reader = "";
  Bool_t enableV0findingEffi = kFALSE;
  Bool_t fillHistos = kTRUE;
  Bool_t runLightOutput = kFALSE;
  if (suffix != "0" && suffix != "999") {
    runLightOutput = kTRUE;
    fillHistos = kFALSE;
  }

  //========= Add V0 Reader to  ANALYSIS manager if not yet existent =====
  TString V0ReaderName =
      Form("V0ReaderV1_%s_%s", cutnumberEvent.Data(), cutnumberPhoton.Data());
  AliConvEventCuts *fEventCuts = NULL;

  if (!(AliV0ReaderV1 *)mgr->GetTask(V0ReaderName.Data())) {
    AliV0ReaderV1 *fV0ReaderV1 = new AliV0ReaderV1(V0ReaderName.Data());
    if (periodNameV0Reader.CompareTo("") != 0)
      fV0ReaderV1->SetPeriodName(periodNameV0Reader);
    fV0ReaderV1->SetUseOwnXYZCalculation(kTRUE);
    fV0ReaderV1->SetCreateAODs(kFALSE);  // AOD Output
    fV0ReaderV1->SetUseAODConversionPhoton(kTRUE);
    fV0ReaderV1->SetProduceV0FindingEfficiency(enableV0findingEffi);

    if (!mgr) {
      Error("AddTask_V0ReaderV1", "No analysis manager found.");
      return NULL;
    }

    if (cutnumberEvent != "") {
      fEventCuts =
          new AliConvEventCuts(cutnumberEvent.Data(), cutnumberEvent.Data());
      fEventCuts->SetPreSelectionCutFlag(kTRUE);
      fEventCuts->SetV0ReaderName(V0ReaderName);
      fEventCuts->SetLightOutput(runLightOutput);
      fEventCuts->SetFillCutHistograms("", fillHistos);
      if (periodNameV0Reader.CompareTo("") != 0)
        fEventCuts->SetPeriodEnum(periodNameV0Reader);
      fV0ReaderV1->SetEventCuts(fEventCuts);
    }

    // Set AnalysisCut Number
    AliConversionPhotonCuts *fCuts = NULL;
    if (cutnumberPhoton != "") {
      fCuts = new AliConversionPhotonCuts(cutnumberPhoton.Data(),
                                          cutnumberPhoton.Data());
      fCuts->SetPreSelectionCutFlag(kTRUE);
      fCuts->SetIsHeavyIon(isHeavyIon);
      fCuts->SetV0ReaderName(V0ReaderName);
      fCuts->SetLightOutput(runLightOutput);
      fCuts->SetFillCutHistograms("", fillHistos);
      if (fCuts->InitializeCutsFromCutString(cutnumberPhoton.Data())) {
        fV0ReaderV1->SetConversionCuts(fCuts);
      }
    }
    fV0ReaderV1->Init();
    AliLog::SetGlobalLogLevel(AliLog::kFatal);

    // connect input V0Reader
    mgr->AddTask(fV0ReaderV1);
    mgr->ConnectInput(fV0ReaderV1, 0, cinput);
  }

  //========= Init subtasks and start analyis ============================
  // Track Cuts

  AliSigma0V0Cuts *v0Cuts = AliSigma0V0Cuts::LambdaCuts();
  v0Cuts->SetIsMC(isMC);
  v0Cuts->SetPID(3122);
  v0Cuts->SetPosPID(AliPID::kProton, 2212);
  v0Cuts->SetNegPID(AliPID::kPion, -211);
  if (suffix == "0") {
    // Run1 cuts
    v0Cuts->SetPileUpRejectionMode(AliSigma0V0Cuts::None);
    v0Cuts->SetV0OnFlyStatus(true);
    v0Cuts->SetDaughterDCAtoPV(0.06);
    v0Cuts->SetDaughterDCAMax(1.5);
    v0Cuts->SetDaughterDCAtoPV(0.06);
    v0Cuts->SetV0CosPAMin(0.993);
    v0Cuts->SetV0RadiusMax(220.f);
    v0Cuts->SetV0RadiusMin(0.5);
    v0Cuts->SetArmenterosCut(0.01, 0.17, 0.2, 0.9);
    v0Cuts->SetPIDnSigma(100.f);
    v0Cuts->SetV0PtMin(0.);
    v0Cuts->SetK0Rejection(0., 0.);
    v0Cuts->SetLambdaSelection(1.110, 1.120);
    v0Cuts->SetTPCclusterMin(0.f);
    v0Cuts->SetEtaMax(0.9);
  }

  // TEMPORARY FIX TO GET MORE YIELD IN MC
  v0Cuts->SetV0OnFlyStatus(false);

  AliSigma0V0Cuts *antiv0Cuts = AliSigma0V0Cuts::LambdaCuts();
  antiv0Cuts->SetIsMC(isMC);
  antiv0Cuts->SetPID(-3122);
  antiv0Cuts->SetPosPID(AliPID::kPion, 211);
  antiv0Cuts->SetNegPID(AliPID::kProton, -2212);
  if (suffix == "0") {
    // Run1 cuts
    antiv0Cuts->SetPileUpRejectionMode(AliSigma0V0Cuts::None);
    antiv0Cuts->SetV0OnFlyStatus(true);
    antiv0Cuts->SetDaughterDCAtoPV(0.06);
    antiv0Cuts->SetDaughterDCAMax(1.5);
    antiv0Cuts->SetDaughterDCAtoPV(0.06);
    antiv0Cuts->SetV0CosPAMin(0.993);
    antiv0Cuts->SetV0RadiusMax(220.f);
    antiv0Cuts->SetV0RadiusMin(0.5);
    antiv0Cuts->SetArmenterosCut(0.01, 0.17, 0.2, 0.9);
    antiv0Cuts->SetPIDnSigma(100.f);
    antiv0Cuts->SetV0PtMin(0.);
    antiv0Cuts->SetK0Rejection(0., 0.);
    antiv0Cuts->SetLambdaSelection(1.110, 1.120);
    antiv0Cuts->SetTPCclusterMin(0.f);
    antiv0Cuts->SetEtaMax(0.9);
  }
  // TEMPORARY FIX TO GET MORE YIELD IN MC
  antiv0Cuts->SetV0OnFlyStatus(false);

  if (suffix != "0") {
    v0Cuts->SetLightweight(true);
    antiv0Cuts->SetLightweight(true);
  }
  if (suffix == "999") {
    v0Cuts->SetCheckCutsMC(true);
    antiv0Cuts->SetCheckCutsMC(true);
    v0Cuts->SetLightweight(false);
    antiv0Cuts->SetLightweight(false);
  }

  AliSigma0PhotonMotherCuts *sigmaCuts =
      AliSigma0PhotonMotherCuts::DefaultCuts();
  sigmaCuts->SetIsMC(isMC);
  sigmaCuts->SetPDG(3212, 3122, 22);
  sigmaCuts->SetLambdaCuts(v0Cuts);
  sigmaCuts->SetV0ReaderName(V0ReaderName.Data());
  if (suffix == "0"){
  sigmaCuts->SetArmenterosCut(0,0.12,-1,-0.6);
  }
  if (suffix != "0" && suffix != "999") {
    sigmaCuts->SetLightweight(true);
    sigmaCuts->SetIsSpectrum(false);
  }

  AliSigma0PhotonMotherCuts *antiSigmaCuts =
      AliSigma0PhotonMotherCuts::DefaultCuts();
  antiSigmaCuts->SetIsMC(isMC);
  antiSigmaCuts->SetPDG(-3212, -3122, 22);
  antiSigmaCuts->SetLambdaCuts(antiv0Cuts);
  antiSigmaCuts->SetV0ReaderName(V0ReaderName.Data());
  if (suffix == "0"){
  antiSigmaCuts->SetArmenterosCut(0,0.12,-1,-0.6);
  }
  if (suffix != "0" && suffix != "999") {
    antiSigmaCuts->SetLightweight(true);
    antiSigmaCuts->SetIsSpectrum(false);
  }

  if (trigger == "kINT7") {
    sigmaCuts->SetMultiplicityMode(AliVEvent::kINT7);
    antiSigmaCuts->SetMultiplicityMode(AliVEvent::kINT7);
  } else if (trigger == "kHighMultV0") {
    sigmaCuts->SetMultiplicityMode(AliVEvent::kHighMultV0);
    antiSigmaCuts->SetMultiplicityMode(AliVEvent::kHighMultV0);
  } else if (trigger == "AliVEvent::kMB") {
    sigmaCuts->SetMultiplicityMode(AliVEvent::kINT7);
    antiSigmaCuts->SetMultiplicityMode(AliVEvent::kINT7);
  }

  AliAnalysisTaskSigma0Run2 *task =
      new AliAnalysisTaskSigma0Run2("AnalysisTaskSigma0Run2");
  if (trigger == "kINT7") {
    task->SetTrigger(AliVEvent::kINT7);
    task->SetMultiplicityMode(AliVEvent::kINT7);
    task->SelectCollisionCandidates(AliVEvent::kINT7);
  } else if (trigger == "kHighMultV0") {
    if (isMC) {
      task->SetTrigger(AliVEvent::kINT7);
      task->SelectCollisionCandidates(AliVEvent::kINT7);
      task->SetMultiplicityMode(AliVEvent::kHighMultV0);
    } else {
      task->SetTrigger(AliVEvent::kHighMultV0);
      task->SelectCollisionCandidates(AliVEvent::kHighMultV0);
      task->SetMultiplicityMode(AliVEvent::kHighMultV0);
    }
  } else if (trigger == "AliVEvent::kMB") {
    task->SetTrigger(AliVEvent::kMB);
    task->SelectCollisionCandidates(AliVEvent::kMB);
    task->SetMultiplicityMode(AliVEvent::kINT7);
  }
  task->SetV0ReaderName(V0ReaderName.Data());
  task->SetIsRun1(isRun1);
  task->SetIsHeavyIon(isHeavyIon);
  task->SetIsMC(isMC);
  task->SetV0Cuts(v0Cuts);
  task->SetAntiV0Cuts(antiv0Cuts);
  task->SetSigmaCuts(sigmaCuts);
  task->SetAntiSigmaCuts(antiSigmaCuts);

  if (suffix != "0" && suffix != "999") {
    task->SetLightweight(true);
  }

  mgr->AddTask(task);

  TString containerName = mgr->GetCommonFileName();
  containerName += ":Sigma0_Femto_";
  if (trigger == "kHighMultV0") containerName += "HighMultV0_";
  containerName += suffix;

  TString name = "histo_";
  if (trigger == "kHighMultV0") name += "HighMultV0_";
  name += suffix;
  AliAnalysisDataContainer *cOutputList = mgr->CreateContainer(
      name, TList::Class(), AliAnalysisManager::kOutputContainer,
      containerName.Data());

  mgr->ConnectInput(task, 0, cinput);
  mgr->ConnectOutput(task, 1, cOutputList);

  return task;
}
<commit_msg>Additional Output for CutVariation.<commit_after>AliAnalysisTaskSE *AddTaskSigma0Run2(bool isRun1 = false, bool isMC = false, bool isHeavyIon = false,
                                     TString trigger = "kINT7",
                                     const char *cutVariation = "0") {
  TString suffix;
  suffix.Form("%s", cutVariation);

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskSigma0Run2()", "No analysis manager found.");
    return 0x0;
  }

  // ================== GetInputEventHandler =============================
  AliVEventHandler *inputHandler = mgr->GetInputEventHandler();
  AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();

  //=========  Set Cutnumber for V0Reader ================================
  TString cutnumberPhoton;
  cutnumberPhoton = "00200008400000002280920000";
  TString cutnumberEvent = "00000000";
  if (suffix == "0") {
    // Borissov cuts
    cutnumberPhoton = "00200008400020002282020000";
    cutnumberEvent = "00000003";
  }
  TString periodNameV0Reader = "";
  Bool_t enableV0findingEffi = kFALSE;
  Bool_t fillHistos = kTRUE;
  Bool_t runLightOutput = kFALSE;
  if (suffix != "0" && suffix != "999") {
    runLightOutput = kTRUE;
    fillHistos = kFALSE;
  }

  //========= Add V0 Reader to  ANALYSIS manager if not yet existent =====
  TString V0ReaderName =
      Form("V0ReaderV1_%s_%s", cutnumberEvent.Data(), cutnumberPhoton.Data());
  AliConvEventCuts *fEventCuts = NULL;

  if (!(AliV0ReaderV1 *)mgr->GetTask(V0ReaderName.Data())) {
    AliV0ReaderV1 *fV0ReaderV1 = new AliV0ReaderV1(V0ReaderName.Data());
    if (periodNameV0Reader.CompareTo("") != 0)
      fV0ReaderV1->SetPeriodName(periodNameV0Reader);
    fV0ReaderV1->SetUseOwnXYZCalculation(kTRUE);
    fV0ReaderV1->SetCreateAODs(kFALSE);  // AOD Output
    fV0ReaderV1->SetUseAODConversionPhoton(kTRUE);
    fV0ReaderV1->SetProduceV0FindingEfficiency(enableV0findingEffi);

    if (!mgr) {
      Error("AddTask_V0ReaderV1", "No analysis manager found.");
      return NULL;
    }

    if (cutnumberEvent != "") {
      fEventCuts =
          new AliConvEventCuts(cutnumberEvent.Data(), cutnumberEvent.Data());
      fEventCuts->SetPreSelectionCutFlag(kTRUE);
      fEventCuts->SetV0ReaderName(V0ReaderName);
      fEventCuts->SetLightOutput(runLightOutput);
      fEventCuts->SetFillCutHistograms("", fillHistos);
      if (periodNameV0Reader.CompareTo("") != 0)
        fEventCuts->SetPeriodEnum(periodNameV0Reader);
      fV0ReaderV1->SetEventCuts(fEventCuts);
    }

    // Set AnalysisCut Number
    AliConversionPhotonCuts *fCuts = NULL;
    if (cutnumberPhoton != "") {
      fCuts = new AliConversionPhotonCuts(cutnumberPhoton.Data(),
                                          cutnumberPhoton.Data());
      fCuts->SetPreSelectionCutFlag(kTRUE);
      fCuts->SetIsHeavyIon(isHeavyIon);
      fCuts->SetV0ReaderName(V0ReaderName);
      fCuts->SetLightOutput(runLightOutput);
      fCuts->SetFillCutHistograms("", fillHistos);
      if (fCuts->InitializeCutsFromCutString(cutnumberPhoton.Data())) {
        fV0ReaderV1->SetConversionCuts(fCuts);
      }
    }
    fV0ReaderV1->Init();
    AliLog::SetGlobalLogLevel(AliLog::kFatal);

    // connect input V0Reader
    mgr->AddTask(fV0ReaderV1);
    mgr->ConnectInput(fV0ReaderV1, 0, cinput);
  }

  //========= Init subtasks and start analyis ============================
  // Track Cuts

  AliSigma0V0Cuts *v0Cuts = AliSigma0V0Cuts::LambdaCuts();
  v0Cuts->SetIsMC(isMC);
  v0Cuts->SetPID(3122);
  v0Cuts->SetPosPID(AliPID::kProton, 2212);
  v0Cuts->SetNegPID(AliPID::kPion, -211);
  if (suffix == "0") {
    // Run1 cuts
    v0Cuts->SetPileUpRejectionMode(AliSigma0V0Cuts::None);
    v0Cuts->SetV0OnFlyStatus(true);
    v0Cuts->SetDaughterDCAtoPV(0.06);
    v0Cuts->SetDaughterDCAMax(1.5);
    v0Cuts->SetDaughterDCAtoPV(0.06);
    v0Cuts->SetV0CosPAMin(0.993);
    v0Cuts->SetV0RadiusMax(220.f);
    v0Cuts->SetV0RadiusMin(0.5);
    v0Cuts->SetArmenterosCut(0.01, 0.17, 0.2, 0.9);
    v0Cuts->SetPIDnSigma(100.f);
    v0Cuts->SetV0PtMin(0.);
    v0Cuts->SetK0Rejection(0., 0.);
    v0Cuts->SetLambdaSelection(1.110, 1.120);
    v0Cuts->SetTPCclusterMin(0.f);
    v0Cuts->SetEtaMax(0.9);
  }

  // TEMPORARY FIX TO GET MORE YIELD IN MC
  v0Cuts->SetV0OnFlyStatus(false);

  AliSigma0V0Cuts *antiv0Cuts = AliSigma0V0Cuts::LambdaCuts();
  antiv0Cuts->SetIsMC(isMC);
  antiv0Cuts->SetPID(-3122);
  antiv0Cuts->SetPosPID(AliPID::kPion, 211);
  antiv0Cuts->SetNegPID(AliPID::kProton, -2212);
  if (suffix == "0") {
    // Run1 cuts
    antiv0Cuts->SetPileUpRejectionMode(AliSigma0V0Cuts::None);
    antiv0Cuts->SetV0OnFlyStatus(true);
    antiv0Cuts->SetDaughterDCAtoPV(0.06);
    antiv0Cuts->SetDaughterDCAMax(1.5);
    antiv0Cuts->SetDaughterDCAtoPV(0.06);
    antiv0Cuts->SetV0CosPAMin(0.993);
    antiv0Cuts->SetV0RadiusMax(220.f);
    antiv0Cuts->SetV0RadiusMin(0.5);
    antiv0Cuts->SetArmenterosCut(0.01, 0.17, 0.2, 0.9);
    antiv0Cuts->SetPIDnSigma(100.f);
    antiv0Cuts->SetV0PtMin(0.);
    antiv0Cuts->SetK0Rejection(0., 0.);
    antiv0Cuts->SetLambdaSelection(1.110, 1.120);
    antiv0Cuts->SetTPCclusterMin(0.f);
    antiv0Cuts->SetEtaMax(0.9);
  }
  // TEMPORARY FIX TO GET MORE YIELD IN MC
  antiv0Cuts->SetV0OnFlyStatus(false);

  if (suffix != "0" && suffix != "1") {
    v0Cuts->SetLightweight(true);
    antiv0Cuts->SetLightweight(true);
  }
  if (suffix == "999") {
    v0Cuts->SetCheckCutsMC(true);
    antiv0Cuts->SetCheckCutsMC(true);
    v0Cuts->SetLightweight(false);
    antiv0Cuts->SetLightweight(false);
  }

  AliSigma0PhotonMotherCuts *sigmaCuts =
      AliSigma0PhotonMotherCuts::DefaultCuts();
  sigmaCuts->SetIsMC(isMC);
  sigmaCuts->SetPDG(3212, 3122, 22);
  sigmaCuts->SetLambdaCuts(v0Cuts);
  sigmaCuts->SetV0ReaderName(V0ReaderName.Data());
  if (suffix == "0"){
  sigmaCuts->SetArmenterosCut(0,0.12,-1,-0.6);
  }
  if (suffix != "0" && suffix != "999" && suffix != "1") {
    sigmaCuts->SetLightweight(true);
    sigmaCuts->SetIsSpectrum(false);
  }

  AliSigma0PhotonMotherCuts *antiSigmaCuts =
      AliSigma0PhotonMotherCuts::DefaultCuts();
  antiSigmaCuts->SetIsMC(isMC);
  antiSigmaCuts->SetPDG(-3212, -3122, 22);
  antiSigmaCuts->SetLambdaCuts(antiv0Cuts);
  antiSigmaCuts->SetV0ReaderName(V0ReaderName.Data());
  if (suffix == "0"){
  antiSigmaCuts->SetArmenterosCut(0,0.12,-1,-0.6);
  }
  if (suffix != "0" && suffix != "999" && suffix != "1") {
    antiSigmaCuts->SetLightweight(true);
    antiSigmaCuts->SetIsSpectrum(false);
  }

  if (trigger == "kINT7") {
    sigmaCuts->SetMultiplicityMode(AliVEvent::kINT7);
    antiSigmaCuts->SetMultiplicityMode(AliVEvent::kINT7);
  } else if (trigger == "kHighMultV0") {
    sigmaCuts->SetMultiplicityMode(AliVEvent::kHighMultV0);
    antiSigmaCuts->SetMultiplicityMode(AliVEvent::kHighMultV0);
  } else if (trigger == "AliVEvent::kMB") {
    sigmaCuts->SetMultiplicityMode(AliVEvent::kINT7);
    antiSigmaCuts->SetMultiplicityMode(AliVEvent::kINT7);
  }

  AliAnalysisTaskSigma0Run2 *task =
      new AliAnalysisTaskSigma0Run2("AnalysisTaskSigma0Run2");
  if (trigger == "kINT7") {
    task->SetTrigger(AliVEvent::kINT7);
    task->SetMultiplicityMode(AliVEvent::kINT7);
    task->SelectCollisionCandidates(AliVEvent::kINT7);
  } else if (trigger == "kHighMultV0") {
    if (isMC) {
      task->SetTrigger(AliVEvent::kINT7);
      task->SelectCollisionCandidates(AliVEvent::kINT7);
      task->SetMultiplicityMode(AliVEvent::kHighMultV0);
    } else {
      task->SetTrigger(AliVEvent::kHighMultV0);
      task->SelectCollisionCandidates(AliVEvent::kHighMultV0);
      task->SetMultiplicityMode(AliVEvent::kHighMultV0);
    }
  } else if (trigger == "AliVEvent::kMB") {
    task->SetTrigger(AliVEvent::kMB);
    task->SelectCollisionCandidates(AliVEvent::kMB);
    task->SetMultiplicityMode(AliVEvent::kINT7);
  }
  task->SetV0ReaderName(V0ReaderName.Data());
  task->SetIsRun1(isRun1);
  task->SetIsHeavyIon(isHeavyIon);
  task->SetIsMC(isMC);
  task->SetV0Cuts(v0Cuts);
  task->SetAntiV0Cuts(antiv0Cuts);
  task->SetSigmaCuts(sigmaCuts);
  task->SetAntiSigmaCuts(antiSigmaCuts);

  if (suffix != "0" && suffix != "999" && suffix != "1") {
    task->SetLightweight(true);
  }

  mgr->AddTask(task);

  TString containerName = mgr->GetCommonFileName();
  containerName += ":Sigma0_Femto_";
  if (trigger == "kHighMultV0") containerName += "HighMultV0_";
  containerName += suffix;

  TString name = "histo_";
  if (trigger == "kHighMultV0") name += "HighMultV0_";
  name += suffix;
  AliAnalysisDataContainer *cOutputList = mgr->CreateContainer(
      name, TList::Class(), AliAnalysisManager::kOutputContainer,
      containerName.Data());

  mgr->ConnectInput(task, 0, cinput);
  mgr->ConnectOutput(task, 1, cOutputList);

  return task;
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#include    <sys/types.h>
#include    <sys/stat.h>
#include    <fcntl.h>

#if     qPlatform_Windows
#include    <io.h>
#elif   qPlatform_POSIX
#include    <unistd.h>
#endif

#include    "../../Debug/AssertExternallySynchronizedLock.h"
#include    "../../Execution/Common.h"
#include    "../../Execution/ErrNoException.h"
#include    "../../Execution/Exceptions.h"
#if     qPlatform_Windows
#include    "../../Execution/Platform/Windows/Exception.h"
#endif
#include    "../../IO/FileAccessException.h"
#include    "../../Streams/BufferedInputStream.h"

#include    "FileInputStream.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Characters;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::FileSystem;

using   Execution::make_unique_lock;
using   Streams::InputStream;
using   Streams::SeekOffsetType;

#if     qPlatform_Windows
using   Execution::Platform::Windows::ThrowIfFalseGetLastError;
#endif

/*
 ********************************************************************************
 **************************** FileSystem::FileInputStream ***********************
 ********************************************************************************
 */
class   FileInputStream::Rep_ : public InputStream<Byte>::_IRep, private Debug::AssertExternallySynchronizedLock {
public:
    Rep_ () = delete;
    Rep_ (const Rep_&) = delete;
    Rep_ (const String& fileName, SeekableFlag seekable)
        : fFD_ (-1)
        , fSeekable_ (seekable)
    {
        try {
#if     qPlatform_Windows
            errno_t e = _wsopen_s (&fFD_, fileName.c_str (), (O_RDONLY | O_BINARY), _SH_DENYNO, 0);
            if (e != 0) {
                Execution::errno_ErrorException::Throw (e);
            }
            ThrowIfFalseGetLastError (fFD_ != -1);
#else
            Execution::ThrowErrNoIfNegative (fFD_ = open (fileName.AsNarrowSDKString ().c_str (), O_RDONLY));
#endif
        }
        Stroika_Foundation_IO_FileAccessException_CATCH_REBIND_FILENAME_ACCCESS_HELPER(fileName, FileAccessMode::eRead);
    }
    ~Rep_ ()
    {
#if     qPlatform_Windows
        ::_close (fFD_);
#else
        ::close (fFD_);
#endif
    }
    nonvirtual  Rep_& operator= (const Rep_&) = delete;

    virtual bool    IsSeekable () const override
    {
        return fSeekable_ == eSeekable;
    }
    virtual size_t  Read (SeekOffsetType* offset, Byte* intoStart, Byte* intoEnd) override
    {
        // @todo implement 'offset' support
        RequireNotNull (intoStart);
        RequireNotNull (intoEnd);
        Require (intoStart < intoEnd);
        size_t  nRequested  =   intoEnd - intoStart;
        lock_guard<const AssertExternallySynchronizedLock> critSec { *this };
#if     qPlatform_Windows
        return static_cast<size_t> (Execution::ThrowErrNoIfNegative (::_read (fFD_, intoStart, Math::PinToMaxForType<unsigned int> (nRequested))));
#else
        return static_cast<size_t> (Execution::ThrowErrNoIfNegative (::read (fFD_, intoStart, nRequested)));
#endif
    }
    virtual Streams::SeekOffsetType  GetReadOffset () const override
    {
        lock_guard<const AssertExternallySynchronizedLock> critSec { *this };
#if     qPlatform_Windows
        return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (_lseeki64 (fFD_, 0, SEEK_CUR)));
#else
        return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (lseek64 (fFD_, 0, SEEK_CUR)));
#endif
    }
    virtual Streams::SeekOffsetType    SeekRead (Streams::Whence whence, Streams::SignedSeekOffsetType offset) override
    {
        using namespace Streams;
        lock_guard<const AssertExternallySynchronizedLock> critSec { *this };
        switch (whence) {
            case    Whence::eFromStart: {
                    if (offset < 0) {
                        Execution::Throw (std::range_error ("seek"));
                    }
#if     qPlatform_Windows
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (_lseeki64 (fFD_, offset, SEEK_SET)));
#else
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (lseek64 (fFD_, offset, SEEK_SET)));
#endif
                }
                break;
            case    Whence::eFromCurrent: {
#if     qPlatform_Windows
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (_lseeki64 (fFD_, offset, SEEK_CUR)));
#else
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (lseek64 (fFD_, offset, SEEK_CUR)));
#endif
                }
                break;
            case    Whence::eFromEnd: {
#if     qPlatform_Windows
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (_lseeki64 (fFD_, offset, SEEK_END)));
#else
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (lseek64 (fFD_, offset, SEEK_END)));
#endif
                }
                break;
        }
        RequireNotReached ();
        return 0;
    }

private:
    int             fFD_;
    SeekableFlag    fSeekable_;
};

FileInputStream::FileInputStream (const String& fileName, SeekableFlag seekable)
    : FileInputStream (make_shared<Rep_> (fileName, seekable))
{
}

FileInputStream::FileInputStream (const shared_ptr<Rep_>& rep)
    : inherited (rep)
{
}

InputStream<Byte>   FileInputStream::mk (const String& fileName, SeekableFlag seekable, BufferFlag bufferFlag)
{
    InputStream<Byte>   in  =   FileInputStream (fileName, seekable);
    switch (bufferFlag) {
        case eBuffered:
            return Streams::BufferedInputStream<Byte> (in);
        case eUnbuffered:
            return in;
        default:
            AssertNotReached ();
            return in;
    }
}
<commit_msg>cleanup; and added disabled USE_NOISY_TRACE_IN_THIS_MODULE_; to IO/FileSystem/FileInputStream<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#include    <sys/types.h>
#include    <sys/stat.h>
#include    <fcntl.h>

#if     qPlatform_Windows
#include    <io.h>
#elif   qPlatform_POSIX
#include    <unistd.h>
#endif

#include    "../../Debug/AssertExternallySynchronizedLock.h"
#include    "../../Debug/Trace.h"
#include    "../../Execution/Common.h"
#include    "../../Execution/ErrNoException.h"
#include    "../../Execution/Exceptions.h"
#if     qPlatform_Windows
#include    "../../Execution/Platform/Windows/Exception.h"
#endif
#include    "../../IO/FileAccessException.h"
#include    "../../Streams/BufferedInputStream.h"

#include    "FileInputStream.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Characters;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::FileSystem;

using   Execution::make_unique_lock;
using   Streams::InputStream;
using   Streams::SeekOffsetType;

#if     qPlatform_Windows
using   Execution::Platform::Windows::ThrowIfFalseGetLastError;
#endif

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

/*
 ********************************************************************************
 **************************** FileSystem::FileInputStream ***********************
 ********************************************************************************
 */
class   FileInputStream::Rep_ : public InputStream<Byte>::_IRep, private Debug::AssertExternallySynchronizedLock {
public:
    Rep_ () = delete;
    Rep_ (const Rep_&) = delete;
    Rep_ (const String& fileName, SeekableFlag seekable)
        : fFD_ (-1)
        , fSeekable_ (seekable)
    {
        try {
#if     qPlatform_Windows
            errno_t e = ::_wsopen_s (&fFD_, fileName.c_str (), (O_RDONLY | O_BINARY), _SH_DENYNO, 0);
            if (e != 0) {
                Execution::errno_ErrorException::Throw (e);
            }
            ThrowIfFalseGetLastError (fFD_ != -1);
#else
            Execution::ThrowErrNoIfNegative (fFD_ = ::open (fileName.AsNarrowSDKString ().c_str (), O_RDONLY));
#endif
        }
        Stroika_Foundation_IO_FileAccessException_CATCH_REBIND_FILENAME_ACCCESS_HELPER(fileName, FileAccessMode::eRead);
    }
    ~Rep_ ()
    {
#if     qPlatform_Windows
        ::_close (fFD_);
#else
        ::close (fFD_);
#endif
    }
    nonvirtual  Rep_& operator= (const Rep_&) = delete;

    virtual bool    IsSeekable () const override
    {
        return fSeekable_ == eSeekable;
    }
    virtual size_t  Read (SeekOffsetType* offset, Byte* intoStart, Byte* intoEnd) override
    {
        // @todo implement 'offset' support
        RequireNotNull (intoStart);
        RequireNotNull (intoEnd);
        Require (intoStart < intoEnd);
        size_t  nRequested  =   intoEnd - intoStart;
        lock_guard<const AssertExternallySynchronizedLock> critSec { *this };
#if     qPlatform_Windows
        return static_cast<size_t> (Execution::ThrowErrNoIfNegative (::_read (fFD_, intoStart, Math::PinToMaxForType<unsigned int> (nRequested))));
#else
        return static_cast<size_t> (Execution::ThrowErrNoIfNegative (::read (fFD_, intoStart, nRequested)));
#endif
    }
    virtual Streams::SeekOffsetType  GetReadOffset () const override
    {
        lock_guard<const AssertExternallySynchronizedLock> critSec { *this };
#if     qPlatform_Windows
        return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (::_lseeki64 (fFD_, 0, SEEK_CUR)));
#else
        return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (::lseek64 (fFD_, 0, SEEK_CUR)));
#endif
    }
    virtual Streams::SeekOffsetType    SeekRead (Streams::Whence whence, Streams::SignedSeekOffsetType offset) override
    {
        using namespace Streams;
        lock_guard<const AssertExternallySynchronizedLock> critSec { *this };
        switch (whence) {
            case    Whence::eFromStart: {
                    if (offset < 0) {
                        Execution::Throw (std::range_error ("seek"));
                    }
#if     qPlatform_Windows
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (::_lseeki64 (fFD_, offset, SEEK_SET)));
#else
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (::lseek64 (fFD_, offset, SEEK_SET)));
#endif
                }
                break;
            case    Whence::eFromCurrent: {
#if     qPlatform_Windows
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (::_lseeki64 (fFD_, offset, SEEK_CUR)));
#else
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (::lseek64 (fFD_, offset, SEEK_CUR)));
#endif
                }
                break;
            case    Whence::eFromEnd: {
#if     qPlatform_Windows
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (::_lseeki64 (fFD_, offset, SEEK_END)));
#else
                    return static_cast<Streams::SeekOffsetType> (Execution::ThrowErrNoIfNegative (::lseek64 (fFD_, offset, SEEK_END)));
#endif
                }
                break;
        }
        RequireNotReached ();
        return 0;
    }

private:
    int             fFD_;
    SeekableFlag    fSeekable_;
};

FileInputStream::FileInputStream (const String& fileName, SeekableFlag seekable)
    : FileInputStream (make_shared<Rep_> (fileName, seekable))
{
}

FileInputStream::FileInputStream (const shared_ptr<Rep_>& rep)
    : inherited (rep)
{
}

InputStream<Byte>   FileInputStream::mk (const String& fileName, SeekableFlag seekable, BufferFlag bufferFlag)
{
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
    Debug::TraceContextBumper ctx (L"FileInputStream::mk");
    DbgTrace (L"(fileName: %s, seekable: %d, bufferFlag: %d)", fileName.c_str (), seekable, bufferFlag);
#endif
    InputStream<Byte>   in  =   FileInputStream (fileName, seekable);
    switch (bufferFlag) {
        case eBuffered:
            return Streams::BufferedInputStream<Byte> (in);
        case eUnbuffered:
            return in;
        default:
            AssertNotReached ();
            return in;
    }
}
<|endoftext|>


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

 Program:   Visualization Toolkit
 Module:    vtkFieldDataSerializer.cxx

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

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

 =========================================================================*/
#include "vtkFieldDataSerializer.h"
#include "vtkObjectFactory.h"
#include "vtkFieldData.h"
#include "vtkDataArray.h"
#include "vtkIdList.h"
#include "vtkStructuredData.h"
#include "vtkStringArray.h"
#include "vtkIntArray.h"
#include "vtkMultiProcessStream.h"

#include <cassert> // For assert()
#include <cstring> // For memcpy

vtkStandardNewMacro(vtkFieldDataSerializer);

//------------------------------------------------------------------------------
vtkFieldDataSerializer::vtkFieldDataSerializer()
{

}

//------------------------------------------------------------------------------
vtkFieldDataSerializer::~vtkFieldDataSerializer()
{

}

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

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeMetaData(
    vtkFieldData *fieldData, vtkMultiProcessStream& bytestream)
{
  if( fieldData == NULL )
    {
    vtkGenericWarningMacro("Field data is NULL!");
    return;
    }

  // STEP 0: Write the number of arrays
  bytestream << fieldData->GetNumberOfArrays();

  // STEP 1: Loop through each array and write the metadata
  for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
    {
    vtkDataArray *dataArray = fieldData->GetArray( array );
    assert("pre: data array should not be NULL!" && (dataArray != NULL));

    int dataType  = dataArray->GetDataType();
    int numComp   = dataArray->GetNumberOfComponents();
    int numTuples = dataArray->GetNumberOfTuples();

    // serialize array information
    bytestream << dataType << numTuples << numComp;
    bytestream << std::string( dataArray->GetName() );
    } // END for all arrays
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::DeserializeMetaData(
    vtkMultiProcessStream& bytestream,
    vtkStringArray *names,
    vtkIntArray *datatypes,
    vtkIntArray *dimensions)
{
  if( bytestream.Empty() )
    {
    vtkGenericWarningMacro("ByteStream is empty");
    return;
    }

  if( (names == NULL) || (datatypes == NULL) || (dimensions == NULL) )
    {
    vtkGenericWarningMacro(
        "ERROR: caller must pre-allocation names/datatypes/dimensions!");
    return;
    }

  // STEP 0: Extract the number of arrays
  int NumberOfArrays;
  bytestream >> NumberOfArrays;
  if( NumberOfArrays == 0 )
    {
    return;
    }

  // STEP 1: Allocate output data-structures
  names->SetNumberOfValues(NumberOfArrays);
  datatypes->SetNumberOfValues(NumberOfArrays);
  dimensions->SetNumberOfComponents(2);
  dimensions->SetNumberOfValues(NumberOfArrays);

  std::string *namesPtr = static_cast<std::string*>(names->GetVoidPointer(0));
  int *datatypesPtr     = static_cast<int*>(datatypes->GetVoidPointer(0));
  int *dimensionsPtr    = static_cast<int*>(dimensions->GetVoidPointer(0));

  // STEP 2: Extract metadata for each array in corresponding output arrays
  for( int arrayIdx=0; arrayIdx < NumberOfArrays; ++arrayIdx )
    {
    bytestream >> datatypesPtr[ arrayIdx ] >> dimensionsPtr[arrayIdx*2] >>
                  dimensionsPtr[arrayIdx*2+1] >> namesPtr[ arrayIdx ];
    } // END for all arrays
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::Serialize(
    vtkFieldData *fieldData, vtkMultiProcessStream& bytestream)
{
  if( fieldData == NULL )
    {
    vtkGenericWarningMacro("Field data is NULL!");
    return;
    }

  // STEP 0: Write the number of arrays
  bytestream << fieldData->GetNumberOfArrays();

  if( fieldData->GetNumberOfArrays() == 0 )
    {
    return;
    }

  // STEP 1: Loop through each array and serialize its metadata
  for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
    {
    vtkDataArray *dataArray = fieldData->GetArray( array );
    vtkFieldDataSerializer::SerializeDataArray( dataArray, bytestream );
    } // END for all arrays
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeTuples(
    vtkIdList *tupleIds, vtkFieldData *fieldData,
    vtkMultiProcessStream& bytestream )
{
  if( fieldData == NULL )
   {
   vtkGenericWarningMacro("Field data is NULL!");
   return;
   }

  // STEP 0: Write the number of arrays
  bytestream << fieldData->GetNumberOfArrays();

  if( fieldData->GetNumberOfArrays() == 0 )
    {
    return;
    }

  // STEP 1: Loop through each array, extract the data on the selected tuples
  // and serialize it
  for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
   {
   vtkDataArray *dataArray = fieldData->GetArray( array );

   // STEP 2: For each array extract only the selected tuples, i.e., a subset
   vtkDataArray *subSet = NULL;
   subSet = vtkFieldDataSerializer::ExtractSelectedTuples(tupleIds,dataArray);
   assert("pre: subset array is NULL!" && (subSet != NULL) );

   // STEP 3: Serialize only a subset of the data
   vtkFieldDataSerializer::SerializeDataArray( subSet, bytestream );
   subSet->Delete();
   } // END for all arrays

}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeSubExtent(
    int subext[6], int gridExtent[6], vtkFieldData *fieldData,
    vtkMultiProcessStream& bytestream)
{
  if( fieldData == NULL )
   {
   vtkGenericWarningMacro("Field data is NULL!");
   return;
   }

  // STEP 0: Write the number of arrays
  bytestream << fieldData->GetNumberOfArrays();

  if( fieldData->GetNumberOfArrays() == 0 )
    {
    return;
    }

  // STEP 1: Loop through each array, extract the data within the subext
  // and serialize it
  for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
    {
    vtkDataArray *dataArray = fieldData->GetArray( array );

    // STEP 2: Extract the data within the requested sub-extent
    vtkDataArray *subSet = NULL;
    subSet = vtkFieldDataSerializer::ExtractSubExtentData(
        subext,gridExtent,dataArray);
    assert("pre: subset array is NULL!" && (subSet != NULL) );

    // STEP 3: Serialize only a subset of the data
    vtkFieldDataSerializer::SerializeDataArray( subSet, bytestream );
    subSet->Delete();
    } // END for all arrays

}

//------------------------------------------------------------------------------
vtkDataArray* vtkFieldDataSerializer::ExtractSubExtentData(
    int subext[6], int gridExtent[6], vtkDataArray *inputDataArray )
{
  if( inputDataArray == NULL )
    {
    vtkGenericWarningMacro("input data array is NULL!");
    return NULL;
    }

  // STEP 0: Acquire structured data description, i.e, XY_PLANE, XYZ_GRID etc.
  int description = vtkStructuredData::GetDataDescriptionFromExtent(gridExtent);

  // STEP 1: Allocate subset array
  vtkDataArray *subSetArray =
      vtkDataArray::CreateDataArray( inputDataArray->GetDataType() );
  subSetArray->SetName( inputDataArray->GetName() );
  subSetArray->SetNumberOfComponents( inputDataArray->GetNumberOfComponents());
  subSetArray->SetNumberOfTuples(
      vtkStructuredData::GetNumberOfNodes(subext,description));

  int ijk[3];
  for( ijk[0]=subext[0]; ijk[0] <= subext[1]; ++ijk[0] )
    {
    for( ijk[1]=subext[2]; ijk[1] <= subext[3]; ++ijk[1] )
      {
      for( ijk[2]=subext[4]; ijk[2] <= subext[5]; ++ijk[2] )
        {
        // Compute the source index from the grid extent. Note, this could be
        // a cell index if the incoming gridExtent and subext are cell extents.
        vtkIdType sourceIdx =
            vtkStructuredData::ComputePointIdForExtent(
                gridExtent,ijk,description);
        assert("pre: source index is out-of-bounds" &&
               (sourceIdx >= 0) &&
               (sourceIdx < inputDataArray->GetNumberOfTuples()));

        // Compute the target index in the subset array. Likewise, this could be
        // either a cell index or a node index depending on what gridExtent or
        // subext represent.
        vtkIdType targetIdx =
            vtkStructuredData::ComputePointIdForExtent(
                subext,ijk,description);
        assert("pre: target index is out-of-bounds" &&
               (targetIdx >= 0) &&
               (targetIdx < subSetArray->GetNumberOfTuples()));

        subSetArray->SetTuple( targetIdx, sourceIdx, inputDataArray );
        } // END for all k
      } // END for all j
    } // END for all i

  return(subSetArray);
}

//------------------------------------------------------------------------------
vtkDataArray* vtkFieldDataSerializer::ExtractSelectedTuples(
    vtkIdList *tupleIds, vtkDataArray *inputDataArray )
{
  vtkDataArray *subSetArray =
      vtkDataArray::CreateDataArray( inputDataArray->GetDataType() );
  subSetArray->SetName( inputDataArray->GetName() );
  subSetArray->SetNumberOfComponents( inputDataArray->GetNumberOfComponents());
  subSetArray->SetNumberOfTuples(tupleIds->GetNumberOfIds());

  vtkIdType idx = 0;
  for( ; idx < tupleIds->GetNumberOfIds(); ++idx )
    {
    vtkIdType tupleIdx = tupleIds->GetId(idx);
    assert("pre: tuple ID is out-of bounds" &&
           (tupleIdx >= 0) && (tupleIdx < inputDataArray->GetNumberOfTuples()));

    subSetArray->SetTuple( idx, tupleIdx, inputDataArray );
    } // END for all tuples to extract
  return( subSetArray );
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeDataArray(
    vtkDataArray *dataArray, vtkMultiProcessStream& bytestream)
{
  if( dataArray == NULL )
    {
    vtkGenericWarningMacro("data array is NULL!");
    return;
    }

  // STEP 0: Serialize array information
  int dataType  = dataArray->GetDataType();
  int numComp   = dataArray->GetNumberOfComponents();
  int numTuples = dataArray->GetNumberOfTuples();

  // serialize array information
  bytestream << dataType << numTuples << numComp;
  bytestream << std::string( dataArray->GetName() );

  // STEP 1: Push the raw data into the bytestream
  // TODO: Add more cases for more datatypes here (?)
  unsigned int size = numComp*numTuples;
  switch( dataArray->GetDataType() )
    {
    case VTK_FLOAT:
       bytestream.Push(static_cast<float*>(dataArray->GetVoidPointer(0)),size);
       break;
     case VTK_DOUBLE:
       bytestream.Push(static_cast<double*>(dataArray->GetVoidPointer(0)),size);
       break;
     case VTK_INT:
       bytestream.Push(static_cast<int*>(dataArray->GetVoidPointer(0)),size);
       break;
     default:
       assert("ERROR: cannot serialize data of given type" && false);
       cerr << "Canot serialize data of type="
            << dataArray->GetDataType() << endl;

    }
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::Deserialize(
    vtkMultiProcessStream& bytestream, vtkFieldData *fieldData)
{
  if( fieldData == NULL )
    {
    vtkGenericWarningMacro("FieldData is NULL!");
    return;
    }

  if( bytestream.Empty() )
    {
    vtkGenericWarningMacro("Bytestream is empty!");
    return;
    }

  // STEP 0: Get the number of arrays
  int numberOfArrays = 0;
  bytestream >> numberOfArrays;

  if( numberOfArrays == 0 )
    {
    return;
    }

  // STEP 1: Loop and deserialize each array
  for( int array=0; array < numberOfArrays; ++array )
    {
    vtkDataArray *dataArray = NULL;
    vtkFieldDataSerializer::DeserializeDataArray( bytestream,dataArray );
    assert("post: deserialized data array should not be NULL!" &&
            (dataArray != NULL));
    fieldData->AddArray( dataArray );
    dataArray->Delete();
    } // END for all arrays
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::DeserializeDataArray(
    vtkMultiProcessStream& bytestream,
    vtkDataArray *&dataArray)
{
  if( bytestream.Empty() )
    {
    vtkGenericWarningMacro("Bytestream is empty!");
    return;
    }

  // STEP 0: Deserialize array information
  int dataType, numTuples, numComp;
  std::string name;

  bytestream >> dataType >> numTuples >> numComp >> name;

  // STEP 1: Construct vtkDataArray object
  dataArray = vtkDataArray::CreateDataArray( dataType );
  dataArray->SetNumberOfComponents( numComp );
  dataArray->SetNumberOfTuples( numTuples );
  dataArray->SetName( name.c_str() );

  // STEP 2: Extract raw data to vtkDataArray
  // TODO: Add more cases for more datatypes here (?)
  unsigned int size = 0;
  switch( dataType )
    {
    case VTK_FLOAT:
      {
      float *data = NULL;
      bytestream.Pop(data,size);
      assert("pre: deserialized raw data array is NULL" && (data != NULL) );

      float *dataArrayPtr = static_cast<float*>(dataArray->GetVoidPointer(0));
      assert("pre: data array pointer is NULL!" && (dataArrayPtr != NULL) );

      std::memcpy(dataArrayPtr,data,size*sizeof(float));
      delete [] data;
      }
      break;
    case VTK_DOUBLE:
      {
      double *data = NULL;
      bytestream.Pop(data,size);
      assert("pre: deserialized raw data array is NULL" && (data != NULL) );

      double *dataArrayPtr = static_cast<double*>(dataArray->GetVoidPointer(0));
      assert("pre: data array pointer is NULL!" && (dataArrayPtr != NULL) );

      std::memcpy(dataArrayPtr,data,size*sizeof(double));
      delete [] data;
      }
      break;
    case VTK_INT:
      {
      int *data = NULL;
      bytestream.Pop(data,size);
      assert("pre: deserialized raw data array is NULL" && (data != NULL) );

      int *dataArrayPtr = static_cast<int*>(dataArray->GetVoidPointer(0));
      assert("pre: data array pointer is NULL!" && (dataArrayPtr != NULL) );

      std::memcpy(dataArrayPtr,data,size*sizeof(int));
      delete [] data;
      }
      break;
    default:
      assert("ERROR: cannot serialize data of given type" && false);
      cerr << "Canot serialize data of type="
           << dataArray->GetDataType() << endl;
    }
}
<commit_msg>Fix TestFieldDataSerialization.<commit_after>/*=========================================================================

 Program:   Visualization Toolkit
 Module:    vtkFieldDataSerializer.cxx

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

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

 =========================================================================*/
#include "vtkFieldDataSerializer.h"
#include "vtkObjectFactory.h"
#include "vtkFieldData.h"
#include "vtkDataArray.h"
#include "vtkIdList.h"
#include "vtkStructuredData.h"
#include "vtkStringArray.h"
#include "vtkIntArray.h"
#include "vtkMultiProcessStream.h"

#include <cassert> // For assert()
#include <cstring> // For memcpy

vtkStandardNewMacro(vtkFieldDataSerializer);

//------------------------------------------------------------------------------
vtkFieldDataSerializer::vtkFieldDataSerializer()
{

}

//------------------------------------------------------------------------------
vtkFieldDataSerializer::~vtkFieldDataSerializer()
{

}

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

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeMetaData(
    vtkFieldData *fieldData, vtkMultiProcessStream& bytestream)
{
  if( fieldData == NULL )
    {
    vtkGenericWarningMacro("Field data is NULL!");
    return;
    }

  // STEP 0: Write the number of arrays
  bytestream << fieldData->GetNumberOfArrays();

  // STEP 1: Loop through each array and write the metadata
  for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
    {
    vtkDataArray *dataArray = fieldData->GetArray( array );
    assert("pre: data array should not be NULL!" && (dataArray != NULL));

    int dataType  = dataArray->GetDataType();
    int numComp   = dataArray->GetNumberOfComponents();
    int numTuples = dataArray->GetNumberOfTuples();

    // serialize array information
    bytestream << dataType << numTuples << numComp;
    bytestream << std::string( dataArray->GetName() );
    } // END for all arrays
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::DeserializeMetaData(
    vtkMultiProcessStream& bytestream,
    vtkStringArray *names,
    vtkIntArray *datatypes,
    vtkIntArray *dimensions)
{
  if( bytestream.Empty() )
    {
    vtkGenericWarningMacro("ByteStream is empty");
    return;
    }

  if( (names == NULL) || (datatypes == NULL) || (dimensions == NULL) )
    {
    vtkGenericWarningMacro(
        "ERROR: caller must pre-allocation names/datatypes/dimensions!");
    return;
    }

  // STEP 0: Extract the number of arrays
  int NumberOfArrays;
  bytestream >> NumberOfArrays;
  if( NumberOfArrays == 0 )
    {
    return;
    }

  // STEP 1: Allocate output data-structures
  names->SetNumberOfValues(NumberOfArrays);
  datatypes->SetNumberOfValues(NumberOfArrays);
  dimensions->SetNumberOfComponents(2);
  dimensions->SetNumberOfTuples(NumberOfArrays);

  std::string *namesPtr = static_cast<std::string*>(names->GetVoidPointer(0));
  int *datatypesPtr     = static_cast<int*>(datatypes->GetVoidPointer(0));
  int *dimensionsPtr    = static_cast<int*>(dimensions->GetVoidPointer(0));

  // STEP 2: Extract metadata for each array in corresponding output arrays
  for( int arrayIdx=0; arrayIdx < NumberOfArrays; ++arrayIdx )
    {
    bytestream >> datatypesPtr[ arrayIdx ] >> dimensionsPtr[arrayIdx*2] >>
                  dimensionsPtr[arrayIdx*2+1] >> namesPtr[ arrayIdx ];
    } // END for all arrays
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::Serialize(
    vtkFieldData *fieldData, vtkMultiProcessStream& bytestream)
{
  if( fieldData == NULL )
    {
    vtkGenericWarningMacro("Field data is NULL!");
    return;
    }

  // STEP 0: Write the number of arrays
  bytestream << fieldData->GetNumberOfArrays();

  if( fieldData->GetNumberOfArrays() == 0 )
    {
    return;
    }

  // STEP 1: Loop through each array and serialize its metadata
  for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
    {
    vtkDataArray *dataArray = fieldData->GetArray( array );
    vtkFieldDataSerializer::SerializeDataArray( dataArray, bytestream );
    } // END for all arrays
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeTuples(
    vtkIdList *tupleIds, vtkFieldData *fieldData,
    vtkMultiProcessStream& bytestream )
{
  if( fieldData == NULL )
   {
   vtkGenericWarningMacro("Field data is NULL!");
   return;
   }

  // STEP 0: Write the number of arrays
  bytestream << fieldData->GetNumberOfArrays();

  if( fieldData->GetNumberOfArrays() == 0 )
    {
    return;
    }

  // STEP 1: Loop through each array, extract the data on the selected tuples
  // and serialize it
  for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
   {
   vtkDataArray *dataArray = fieldData->GetArray( array );

   // STEP 2: For each array extract only the selected tuples, i.e., a subset
   vtkDataArray *subSet = NULL;
   subSet = vtkFieldDataSerializer::ExtractSelectedTuples(tupleIds,dataArray);
   assert("pre: subset array is NULL!" && (subSet != NULL) );

   // STEP 3: Serialize only a subset of the data
   vtkFieldDataSerializer::SerializeDataArray( subSet, bytestream );
   subSet->Delete();
   } // END for all arrays

}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeSubExtent(
    int subext[6], int gridExtent[6], vtkFieldData *fieldData,
    vtkMultiProcessStream& bytestream)
{
  if( fieldData == NULL )
   {
   vtkGenericWarningMacro("Field data is NULL!");
   return;
   }

  // STEP 0: Write the number of arrays
  bytestream << fieldData->GetNumberOfArrays();

  if( fieldData->GetNumberOfArrays() == 0 )
    {
    return;
    }

  // STEP 1: Loop through each array, extract the data within the subext
  // and serialize it
  for( int array=0; array < fieldData->GetNumberOfArrays(); ++array )
    {
    vtkDataArray *dataArray = fieldData->GetArray( array );

    // STEP 2: Extract the data within the requested sub-extent
    vtkDataArray *subSet = NULL;
    subSet = vtkFieldDataSerializer::ExtractSubExtentData(
        subext,gridExtent,dataArray);
    assert("pre: subset array is NULL!" && (subSet != NULL) );

    // STEP 3: Serialize only a subset of the data
    vtkFieldDataSerializer::SerializeDataArray( subSet, bytestream );
    subSet->Delete();
    } // END for all arrays

}

//------------------------------------------------------------------------------
vtkDataArray* vtkFieldDataSerializer::ExtractSubExtentData(
    int subext[6], int gridExtent[6], vtkDataArray *inputDataArray )
{
  if( inputDataArray == NULL )
    {
    vtkGenericWarningMacro("input data array is NULL!");
    return NULL;
    }

  // STEP 0: Acquire structured data description, i.e, XY_PLANE, XYZ_GRID etc.
  int description = vtkStructuredData::GetDataDescriptionFromExtent(gridExtent);

  // STEP 1: Allocate subset array
  vtkDataArray *subSetArray =
      vtkDataArray::CreateDataArray( inputDataArray->GetDataType() );
  subSetArray->SetName( inputDataArray->GetName() );
  subSetArray->SetNumberOfComponents( inputDataArray->GetNumberOfComponents());
  subSetArray->SetNumberOfTuples(
      vtkStructuredData::GetNumberOfNodes(subext,description));

  int ijk[3];
  for( ijk[0]=subext[0]; ijk[0] <= subext[1]; ++ijk[0] )
    {
    for( ijk[1]=subext[2]; ijk[1] <= subext[3]; ++ijk[1] )
      {
      for( ijk[2]=subext[4]; ijk[2] <= subext[5]; ++ijk[2] )
        {
        // Compute the source index from the grid extent. Note, this could be
        // a cell index if the incoming gridExtent and subext are cell extents.
        vtkIdType sourceIdx =
            vtkStructuredData::ComputePointIdForExtent(
                gridExtent,ijk,description);
        assert("pre: source index is out-of-bounds" &&
               (sourceIdx >= 0) &&
               (sourceIdx < inputDataArray->GetNumberOfTuples()));

        // Compute the target index in the subset array. Likewise, this could be
        // either a cell index or a node index depending on what gridExtent or
        // subext represent.
        vtkIdType targetIdx =
            vtkStructuredData::ComputePointIdForExtent(
                subext,ijk,description);
        assert("pre: target index is out-of-bounds" &&
               (targetIdx >= 0) &&
               (targetIdx < subSetArray->GetNumberOfTuples()));

        subSetArray->SetTuple( targetIdx, sourceIdx, inputDataArray );
        } // END for all k
      } // END for all j
    } // END for all i

  return(subSetArray);
}

//------------------------------------------------------------------------------
vtkDataArray* vtkFieldDataSerializer::ExtractSelectedTuples(
    vtkIdList *tupleIds, vtkDataArray *inputDataArray )
{
  vtkDataArray *subSetArray =
      vtkDataArray::CreateDataArray( inputDataArray->GetDataType() );
  subSetArray->SetName( inputDataArray->GetName() );
  subSetArray->SetNumberOfComponents( inputDataArray->GetNumberOfComponents());
  subSetArray->SetNumberOfTuples(tupleIds->GetNumberOfIds());

  vtkIdType idx = 0;
  for( ; idx < tupleIds->GetNumberOfIds(); ++idx )
    {
    vtkIdType tupleIdx = tupleIds->GetId(idx);
    assert("pre: tuple ID is out-of bounds" &&
           (tupleIdx >= 0) && (tupleIdx < inputDataArray->GetNumberOfTuples()));

    subSetArray->SetTuple( idx, tupleIdx, inputDataArray );
    } // END for all tuples to extract
  return( subSetArray );
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::SerializeDataArray(
    vtkDataArray *dataArray, vtkMultiProcessStream& bytestream)
{
  if( dataArray == NULL )
    {
    vtkGenericWarningMacro("data array is NULL!");
    return;
    }

  // STEP 0: Serialize array information
  int dataType  = dataArray->GetDataType();
  int numComp   = dataArray->GetNumberOfComponents();
  int numTuples = dataArray->GetNumberOfTuples();

  // serialize array information
  bytestream << dataType << numTuples << numComp;
  bytestream << std::string( dataArray->GetName() );

  // STEP 1: Push the raw data into the bytestream
  // TODO: Add more cases for more datatypes here (?)
  unsigned int size = numComp*numTuples;
  switch( dataArray->GetDataType() )
    {
    case VTK_FLOAT:
       bytestream.Push(static_cast<float*>(dataArray->GetVoidPointer(0)),size);
       break;
     case VTK_DOUBLE:
       bytestream.Push(static_cast<double*>(dataArray->GetVoidPointer(0)),size);
       break;
     case VTK_INT:
       bytestream.Push(static_cast<int*>(dataArray->GetVoidPointer(0)),size);
       break;
     default:
       assert("ERROR: cannot serialize data of given type" && false);
       cerr << "Canot serialize data of type="
            << dataArray->GetDataType() << endl;

    }
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::Deserialize(
    vtkMultiProcessStream& bytestream, vtkFieldData *fieldData)
{
  if( fieldData == NULL )
    {
    vtkGenericWarningMacro("FieldData is NULL!");
    return;
    }

  if( bytestream.Empty() )
    {
    vtkGenericWarningMacro("Bytestream is empty!");
    return;
    }

  // STEP 0: Get the number of arrays
  int numberOfArrays = 0;
  bytestream >> numberOfArrays;

  if( numberOfArrays == 0 )
    {
    return;
    }

  // STEP 1: Loop and deserialize each array
  for( int array=0; array < numberOfArrays; ++array )
    {
    vtkDataArray *dataArray = NULL;
    vtkFieldDataSerializer::DeserializeDataArray( bytestream,dataArray );
    assert("post: deserialized data array should not be NULL!" &&
            (dataArray != NULL));
    fieldData->AddArray( dataArray );
    dataArray->Delete();
    } // END for all arrays
}

//------------------------------------------------------------------------------
void vtkFieldDataSerializer::DeserializeDataArray(
    vtkMultiProcessStream& bytestream,
    vtkDataArray *&dataArray)
{
  if( bytestream.Empty() )
    {
    vtkGenericWarningMacro("Bytestream is empty!");
    return;
    }

  // STEP 0: Deserialize array information
  int dataType, numTuples, numComp;
  std::string name;

  bytestream >> dataType >> numTuples >> numComp >> name;

  // STEP 1: Construct vtkDataArray object
  dataArray = vtkDataArray::CreateDataArray( dataType );
  dataArray->SetNumberOfComponents( numComp );
  dataArray->SetNumberOfTuples( numTuples );
  dataArray->SetName( name.c_str() );

  // STEP 2: Extract raw data to vtkDataArray
  // TODO: Add more cases for more datatypes here (?)
  unsigned int size = 0;
  switch( dataType )
    {
    case VTK_FLOAT:
      {
      float *data = NULL;
      bytestream.Pop(data,size);
      assert("pre: deserialized raw data array is NULL" && (data != NULL) );

      float *dataArrayPtr = static_cast<float*>(dataArray->GetVoidPointer(0));
      assert("pre: data array pointer is NULL!" && (dataArrayPtr != NULL) );

      std::memcpy(dataArrayPtr,data,size*sizeof(float));
      delete [] data;
      }
      break;
    case VTK_DOUBLE:
      {
      double *data = NULL;
      bytestream.Pop(data,size);
      assert("pre: deserialized raw data array is NULL" && (data != NULL) );

      double *dataArrayPtr = static_cast<double*>(dataArray->GetVoidPointer(0));
      assert("pre: data array pointer is NULL!" && (dataArrayPtr != NULL) );

      std::memcpy(dataArrayPtr,data,size*sizeof(double));
      delete [] data;
      }
      break;
    case VTK_INT:
      {
      int *data = NULL;
      bytestream.Pop(data,size);
      assert("pre: deserialized raw data array is NULL" && (data != NULL) );

      int *dataArrayPtr = static_cast<int*>(dataArray->GetVoidPointer(0));
      assert("pre: data array pointer is NULL!" && (dataArrayPtr != NULL) );

      std::memcpy(dataArrayPtr,data,size*sizeof(int));
      delete [] data;
      }
      break;
    default:
      assert("ERROR: cannot serialize data of given type" && false);
      cerr << "Canot serialize data of type="
           << dataArray->GetDataType() << endl;
    }
}
<|endoftext|>


<commit_before>/*
 * unap.cpp
 *
 *  Created on: Apr 2, 2013
 *      Author: nikita.karnauhov@gmail.com
 */

#include "unap.h"
#include "formats.h"
#include "exception.h"

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netdb.h>
#include <poll.h>

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <random>

unsigned int UNAP::s_cSeed = 0;
std::default_random_engine UNAP::s_randomEngine = std::default_random_engine();

UNAP::UNAP() :
    strHost("127.0.0.1"), nPort(26751), nMTU(1500), m_nSockWorker(0), m_status(usStopped),
    m_nSocket(-1)
{
    if (s_cSeed == 0) {
        try {
            std::random_device rd;
            s_cSeed = rd();
        } catch (...) {
            s_cSeed = Clock::now().time_since_epoch().count();
        }

        s_randomEngine.seed(s_cSeed);
    }

    _reset(true);
    _init_descriptors();
}

UNAP::~UNAP() {
    if (m_nSocket >= -1)
        close(m_nSocket);
}

UNAP::Status UNAP::get_status() const {
    return m_status;
}

void UNAP::start() {
    _reset(false);
    m_status = usRunning;
    m_startTime = Clock::now();
    m_worker = std::thread(_make_worker());
}

void UNAP::stop() {
    if (m_status & usRunning)
        _send_stop();

    m_status = usStopped;

    if (m_worker.joinable())
        m_worker.join();
}

snd_pcm_sframes_t UNAP::get_buffer_pointer() const {
    if (!m_bPrepared)
        return 0;

    const snd_pcm_sframes_t frames = _estimate_frames();
    snd_pcm_sframes_t nPointer = std::min(frames, m_nPointer)%get_buffer_size();
    std::lock_guard<std::mutex> lock(m_mutex);

    if (nPointer == 0 && m_queue.empty() && m_nPointer > 0 && frames > 0)
        nPointer = get_buffer_size(); // Nothing more to play, buffer must have ran out.

    return nPointer;
}

snd_pcm_sframes_t UNAP::transfer(const char *_pData, size_t _cOffset, size_t _cSize) {
    assert(m_bPrepared);

    std::lock_guard<std::mutex> lock(m_mutex);

    size_t cSizeBytes = std::min<size_t>(_cSize, get_buffer_size() - m_nAvail);

    _cSize = cSizeBytes;
    cSizeBytes *= get_bytes_per_frame();

    if (cSizeBytes == 0)
        return 0;

    char *pStart = m_pBuffer.get();
    char *pDest = m_queue.empty() ? m_pBuffer.get() : m_queue.back().second;
    const char *pSrc = _pData + _cOffset*get_bytes_per_frame();
    const size_t cBufferBytes = get_buffer_size()*get_bytes_per_frame();

    if (pDest < pStart + cBufferBytes) {
        const size_t cPart = std::min(cSizeBytes, cBufferBytes - (pDest - pStart));
        memcpy(pDest, pSrc, cPart);
        m_queue.emplace_back(pDest, pDest + cPart);
        cSizeBytes -= cPart;
        pSrc += cPart;
        assert(m_queue.back().second > m_queue.back().first);
    }

    if (cSizeBytes > 0) {
        assert(cSizeBytes < cBufferBytes);
        memcpy(pStart, pSrc, cSizeBytes);
        m_queue.emplace_back(pStart, pStart + cSizeBytes);
        assert(m_queue.back().second > m_queue.back().first);
    }

    m_nAvail += _cSize;

    return _cSize;
}

void UNAP::prepare() {
    _reset(true);
    m_nAvail = 0;
    m_strFormat = get_format_name(get_format());
    m_cBitsPerSample = snd_pcm_format_physical_width(get_format());
    assert(get_bytes_per_frame() > 0);
    assert(get_buffer_size() > 0);
    std::unique_ptr<char[]> pBuffer(new char[get_buffer_size()*get_bytes_per_frame()]);
    m_pBuffer = std::move(pBuffer);
    m_bPrepared = true;
}

void UNAP::drain() {
    assert(m_bPrepared);
    m_status = usStopping;
    if (m_worker.joinable())
        m_worker.join();
}

void UNAP::pause() {
    assert(m_bPrepared && m_status == usRunning);
    m_nLastFrames = _estimate_frames();
    m_status = usPaused;
    m_startTime = TimePoint();
}

void UNAP::unpause() {
    m_status = usRunning;
    m_startTime = Clock::now();
}

snd_pcm_sframes_t UNAP::get_unplayed_frames() const {
    return m_nAvail; // TODO m_nPosition - estimateFrames
}

void UNAP::_reset(bool _bResetStreamParams) {
    m_nPointer = 0;
    m_nLastFrames = 0;
    m_startTime = TimePoint();
    m_cStreamId = s_randomEngine();

    if (_bResetStreamParams) {
        m_nAvail = 0;
        m_strFormat = "";
        m_cBitsPerSample = 0;
        m_queue.clear();
        m_bPrepared = false;
    }
}

void UNAP::_init_descriptors() {
    int fds[2];

    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0)
        throw SystemError("socketpair()");

    for (int fd : fds) {
        int fl;

        if ((fl = fcntl(fd, F_GETFL)) < 0)
            throw SystemError("fcntl()");

        if (fl & O_NONBLOCK)
            break;

        if (fcntl(fd, F_SETFL, fl | O_NONBLOCK) < 0)
            throw SystemError("fcntl()");
    }

    poll_fd = fds[0];
    m_nSockWorker = fds[1];
    poll_events = POLLIN;
}

snd_pcm_sframes_t UNAP::_estimate_frames() const {
    if (m_status == usPaused)
        return m_nLastFrames;
    DurationMS ms(std::chrono::duration_cast<DurationMS>(Clock::now() - m_startTime));
    return m_nLastFrames + ms.count()*(get_rate()/1000.0);
}

std::function<void(void)> UNAP::_make_worker() {
    return [&]() {
        if (!m_nSockWorker)
            return;

        Status prev = usRunning;

        while (m_status & usRunning) {
            if (prev == usRunning && m_status == usPaused)
                _send_pause();
            else if (prev == usPaused && m_status == usRunning)
                _send_unpause();

            if (!m_queue.empty()) {
                std::lock_guard<std::mutex> lock(m_mutex);

                while (!m_queue.empty())
                    _send_data();
            } else if (m_bPrepared && m_status == UNAP::usStopping && _estimate_frames() >= m_nPointer) {
                _send_stop();
                m_status = UNAP::usStopped;
            }

            char buf[1] = {0};
            write(m_nSockWorker, buf, 1);
            prev = m_status;
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    };
}

void UNAP::_prepare_packet(unap::Packet &_packet, unap::Packet_Kind _kind,
        uint64_t _nTimestamp)
{
    _packet.set_version(1);
    _packet.set_stream(m_cStreamId);
    _packet.set_kind(_kind);
    _packet.set_channels(get_channel_count());
    _packet.set_rate(get_rate());
    _packet.set_format(m_strFormat);
    _packet.set_timestamp(_nTimestamp);

    if (_kind != unap::Packet_Kind_DATA)
        _packet.set_samples("");
}

void UNAP::_send_buffer(const void *_pBuf, size_t _cSize) {
    for (size_t cRetry = 0; cRetry < 5; ++cRetry) {
        if (send(m_nSocket, _pBuf, _cSize, 0) >= 0)
            break;

        if (errno != ECONNREFUSED)
            throw SystemError("send()");

        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }
}

void UNAP::_send_packet(const unap::Packet &_packet) {
    auto pBuf = std::unique_ptr<char[]>(new char[this->nMTU]);
    assert(_packet.ByteSize() <= this->nMTU);
    _packet.SerializeToArray((void *)pBuf.get(), this->nMTU);
    _send_buffer((const void *)pBuf.get(), _packet.ByteSize());
}

void UNAP::_send_stop() {
    unap::Packet packet;
    _prepare_packet(packet, unap::Packet_Kind_STOP, _estimate_frames());
    _send_packet(packet);
}

void UNAP::_send_pause() {
    unap::Packet packet;
    _prepare_packet(packet, unap::Packet_Kind_PAUSE, _estimate_frames());
    _send_packet(packet);
}

void UNAP::_send_unpause() {
    unap::Packet packet;
    _prepare_packet(packet, unap::Packet_Kind_UNPAUSE, m_nLastFrames);
    _send_packet(packet);
}

void UNAP::_send_data() {
    unap::Packet packet;

    assert(m_queue.front().second > m_queue.front().first);
    assert(m_bPrepared);
    _prepare_packet(packet, unap::Packet_Kind_DATA, m_nPointer);

    const size_t cHeaderSize = packet.ByteSize() + 4; // Account for data length field.
    const size_t cFrameSize = get_bytes_per_frame();
    const size_t cTotal = ((this->nMTU - cHeaderSize)/cFrameSize)*cFrameSize;
    size_t cBytes = cTotal;
    auto pBuf = std::unique_ptr<char[]>(new char[this->nMTU]); // Reuse as serialization buffer.
    char *pPos = pBuf.get();

    while (!m_queue.empty() && cBytes > 0) {
        char *pSource = m_queue.front().first;
        char *pEnd = m_queue.front().second;
        const size_t cAvailable = pEnd - pSource;

        if (cAvailable > 0) {
            const size_t c = std::min(cAvailable, (cBytes/cFrameSize)*cFrameSize);

            // FIXME c may equal zero.
            memcpy(pPos, pSource, c);

            pSource += c;
            pPos += c;
            cBytes -= c;
        }

        m_queue.front().first = pSource;

        assert(m_queue.front().second >= m_queue.front().first);

        if (pSource == pEnd)
            m_queue.pop_front();
    }

    packet.set_samples((const void *)pBuf.get(), cTotal - cBytes);
    m_nPointer += (cTotal - cBytes)/get_bytes_per_frame();
    m_nAvail -= (cTotal - cBytes)/get_bytes_per_frame();

    // Send.
    assert(packet.ByteSize() <= this->nMTU);
    packet.SerializeToArray((void *)pBuf.get(), this->nMTU);
    _send_buffer((const void *)pBuf.get(), packet.ByteSize());
}

void UNAP::connect() {
    struct sockaddr_in name;

    if (m_nSocket >= 0)
        close(m_nSocket);

    m_nSocket = socket(PF_INET, SOCK_DGRAM, 0);

    if (m_nSocket < 0)
        throw SystemError("socket()");

    name.sin_family = AF_INET;
    name.sin_port = htons(this->nPort);

    struct hostent *pHost = gethostbyname(this->strHost.c_str());

    if (!pHost)
        throw SystemError("gethostbyname()");

    name.sin_addr = *(struct in_addr *)pHost->h_addr;

    if (::connect(m_nSocket, (struct sockaddr *)&name, sizeof(name)) < 0)
        throw SystemError("connect()");
}

const std::vector<unsigned int> &UNAP::get_format_values() {
    m_formatValues.clear();

    for (const std::string &strFormat : formats) {
        auto iFormat = g_formats.find(strFormat);

        if (iFormat != g_formats.end())
            m_formatValues.push_back(iFormat->second);
    }

    return m_formatValues;
}

unsigned int UNAP::get_channel_count() const {
    return this->channels;
}

snd_pcm_uframes_t UNAP::get_buffer_size() const {
    return this->buffer_size;
}

snd_pcm_uframes_t UNAP::get_period_size() const {
    return this->buffer_size;
}

size_t UNAP::get_bytes_per_frame() const {
    return get_channel_count()*m_cBitsPerSample/8;
}

snd_pcm_format_t UNAP::get_format() const {
    return this->format;
}

unsigned int UNAP::get_rate() const {
    return this->rate;
}
<commit_msg>Add sanity check.<commit_after>/*
 * unap.cpp
 *
 *  Created on: Apr 2, 2013
 *      Author: nikita.karnauhov@gmail.com
 */

#include "unap.h"
#include "formats.h"
#include "exception.h"

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netdb.h>
#include <poll.h>

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <random>

unsigned int UNAP::s_cSeed = 0;
std::default_random_engine UNAP::s_randomEngine = std::default_random_engine();

UNAP::UNAP() :
    strHost("127.0.0.1"), nPort(26751), nMTU(1500), m_nSockWorker(0), m_status(usStopped),
    m_nSocket(-1)
{
    if (s_cSeed == 0) {
        try {
            std::random_device rd;
            s_cSeed = rd();
        } catch (...) {
            s_cSeed = Clock::now().time_since_epoch().count();
        }

        s_randomEngine.seed(s_cSeed);
    }

    _reset(true);
    _init_descriptors();
}

UNAP::~UNAP() {
    if (m_nSocket >= -1)
        close(m_nSocket);
}

UNAP::Status UNAP::get_status() const {
    return m_status;
}

void UNAP::start() {
    _reset(false);
    m_status = usRunning;
    m_startTime = Clock::now();
    m_worker = std::thread(_make_worker());
}

void UNAP::stop() {
    if (m_status & usRunning)
        _send_stop();

    m_status = usStopped;

    if (m_worker.joinable())
        m_worker.join();
}

snd_pcm_sframes_t UNAP::get_buffer_pointer() const {
    if (!m_bPrepared)
        return 0;

    const snd_pcm_sframes_t frames = _estimate_frames();
    snd_pcm_sframes_t nPointer = std::min(frames, m_nPointer)%get_buffer_size();
    std::lock_guard<std::mutex> lock(m_mutex);

    if (nPointer == 0 && m_queue.empty() && m_nPointer > 0 && frames > 0)
        nPointer = get_buffer_size(); // Nothing more to play, buffer must have ran out.

    return nPointer;
}

snd_pcm_sframes_t UNAP::transfer(const char *_pData, size_t _cOffset, size_t _cSize) {
    assert(m_bPrepared);

    std::lock_guard<std::mutex> lock(m_mutex);

    size_t cSizeBytes = std::min<size_t>(_cSize, get_buffer_size() - m_nAvail);

    _cSize = cSizeBytes;
    cSizeBytes *= get_bytes_per_frame();

    if (cSizeBytes == 0)
        return 0;

    char *pStart = m_pBuffer.get();
    char *pDest = m_queue.empty() ? m_pBuffer.get() : m_queue.back().second;
    const char *pSrc = _pData + _cOffset*get_bytes_per_frame();
    const size_t cBufferBytes = get_buffer_size()*get_bytes_per_frame();

    if (pDest < pStart + cBufferBytes) {
        const size_t cPart = std::min(cSizeBytes, cBufferBytes - (pDest - pStart));
        memcpy(pDest, pSrc, cPart);
        m_queue.emplace_back(pDest, pDest + cPart);
        cSizeBytes -= cPart;
        pSrc += cPart;
        assert(m_queue.back().second > m_queue.back().first);
    }

    if (cSizeBytes > 0) {
        assert(cSizeBytes < cBufferBytes);
        memcpy(pStart, pSrc, cSizeBytes);
        m_queue.emplace_back(pStart, pStart + cSizeBytes);
        assert(m_queue.back().second > m_queue.back().first);
    }

    m_nAvail += _cSize;

    return _cSize;
}

void UNAP::prepare() {
    _reset(true);
    m_nAvail = 0;
    m_strFormat = get_format_name(get_format());
    m_cBitsPerSample = snd_pcm_format_physical_width(get_format());
    assert(get_bytes_per_frame() > 0);
    assert(get_buffer_size() > 0);
    std::unique_ptr<char[]> pBuffer(new char[get_buffer_size()*get_bytes_per_frame()]);
    m_pBuffer = std::move(pBuffer);
    m_bPrepared = true;
}

void UNAP::drain() {
    assert(m_bPrepared);
    m_status = usStopping;
    if (m_worker.joinable())
        m_worker.join();
}

void UNAP::pause() {
    assert(m_bPrepared && m_status == usRunning);
    m_nLastFrames = _estimate_frames();
    m_status = usPaused;
    m_startTime = TimePoint();
}

void UNAP::unpause() {
    m_status = usRunning;
    m_startTime = Clock::now();
}

snd_pcm_sframes_t UNAP::get_unplayed_frames() const {
    return m_nAvail; // TODO m_nPosition - estimateFrames
}

void UNAP::_reset(bool _bResetStreamParams) {
    m_nPointer = 0;
    m_nLastFrames = 0;
    m_startTime = TimePoint();
    m_cStreamId = s_randomEngine();

    if (_bResetStreamParams) {
        m_nAvail = 0;
        m_strFormat = "";
        m_cBitsPerSample = 0;
        m_queue.clear();
        m_bPrepared = false;
    }
}

void UNAP::_init_descriptors() {
    int fds[2];

    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0)
        throw SystemError("socketpair()");

    for (int fd : fds) {
        int fl;

        if ((fl = fcntl(fd, F_GETFL)) < 0)
            throw SystemError("fcntl()");

        if (fl & O_NONBLOCK)
            break;

        if (fcntl(fd, F_SETFL, fl | O_NONBLOCK) < 0)
            throw SystemError("fcntl()");
    }

    poll_fd = fds[0];
    m_nSockWorker = fds[1];
    poll_events = POLLIN;
}

snd_pcm_sframes_t UNAP::_estimate_frames() const {
    if (m_status == usPaused)
        return m_nLastFrames;
    DurationMS ms(std::chrono::duration_cast<DurationMS>(Clock::now() - m_startTime));
    return m_nLastFrames + ms.count()*(get_rate()/1000.0);
}

std::function<void(void)> UNAP::_make_worker() {
    return [&]() {
        if (!m_nSockWorker)
            return;

        Status prev = usRunning;

        while (m_status & usRunning) {
            if (prev == usRunning && m_status == usPaused)
                _send_pause();
            else if (prev == usPaused && m_status == usRunning)
                _send_unpause();

            if (!m_queue.empty()) {
                std::lock_guard<std::mutex> lock(m_mutex);

                while (!m_queue.empty())
                    _send_data();
            } else if (m_bPrepared && m_status == UNAP::usStopping && _estimate_frames() >= m_nPointer) {
                _send_stop();
                m_status = UNAP::usStopped;
            }

            char buf[1] = {0};
            write(m_nSockWorker, buf, 1);
            prev = m_status;
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    };
}

void UNAP::_prepare_packet(unap::Packet &_packet, unap::Packet_Kind _kind,
        uint64_t _nTimestamp)
{
    _packet.set_version(1);
    _packet.set_stream(m_cStreamId);
    _packet.set_kind(_kind);
    _packet.set_channels(get_channel_count());
    _packet.set_rate(get_rate());
    _packet.set_format(m_strFormat);
    _packet.set_timestamp(_nTimestamp);

    if (_kind != unap::Packet_Kind_DATA)
        _packet.set_samples("");
}

void UNAP::_send_buffer(const void *_pBuf, size_t _cSize) {
    for (size_t cRetry = 0; cRetry < 5; ++cRetry) {
        if (send(m_nSocket, _pBuf, _cSize, 0) >= 0)
            break;

        if (errno != ECONNREFUSED)
            throw SystemError("send()");

        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }
}

void UNAP::_send_packet(const unap::Packet &_packet) {
    auto pBuf = std::unique_ptr<char[]>(new char[this->nMTU]);
    assert(_packet.ByteSize() <= this->nMTU);
    _packet.SerializeToArray((void *)pBuf.get(), this->nMTU);
    _send_buffer((const void *)pBuf.get(), _packet.ByteSize());
}

void UNAP::_send_stop() {
    unap::Packet packet;
    _prepare_packet(packet, unap::Packet_Kind_STOP, _estimate_frames());
    _send_packet(packet);
}

void UNAP::_send_pause() {
    unap::Packet packet;
    _prepare_packet(packet, unap::Packet_Kind_PAUSE, _estimate_frames());
    _send_packet(packet);
}

void UNAP::_send_unpause() {
    unap::Packet packet;
    _prepare_packet(packet, unap::Packet_Kind_UNPAUSE, m_nLastFrames);
    _send_packet(packet);
}

void UNAP::_send_data() {
    unap::Packet packet;

    assert(m_queue.front().second > m_queue.front().first);
    assert(m_bPrepared);
    _prepare_packet(packet, unap::Packet_Kind_DATA, m_nPointer);

    const size_t cHeaderSize = packet.ByteSize() + 4; // Account for data length field.
    const size_t cFrameSize = get_bytes_per_frame();
    const size_t cTotal = ((this->nMTU - cHeaderSize)/cFrameSize)*cFrameSize;
    size_t cBytes = cTotal;
    auto pBuf = std::unique_ptr<char[]>(new char[this->nMTU]); // Reuse as serialization buffer.
    char *pPos = pBuf.get();

    while (!m_queue.empty() && cBytes > 0) {
        char *pSource = m_queue.front().first;
        char *pEnd = m_queue.front().second;
        const size_t cAvailable = pEnd - pSource;

        if (cAvailable > 0) {
            const size_t c = std::min(cAvailable, (cBytes/cFrameSize)*cFrameSize);

            if (c == 0)
                throw LogicError("Queue element size isn't mulptiple of frame size");

            memcpy(pPos, pSource, c);

            pSource += c;
            pPos += c;
            cBytes -= c;
        }

        m_queue.front().first = pSource;

        assert(m_queue.front().second >= m_queue.front().first);

        if (pSource == pEnd)
            m_queue.pop_front();
    }

    packet.set_samples((const void *)pBuf.get(), cTotal - cBytes);
    m_nPointer += (cTotal - cBytes)/get_bytes_per_frame();
    m_nAvail -= (cTotal - cBytes)/get_bytes_per_frame();

    // Send.
    assert(packet.ByteSize() <= this->nMTU);
    packet.SerializeToArray((void *)pBuf.get(), this->nMTU);
    _send_buffer((const void *)pBuf.get(), packet.ByteSize());
}

void UNAP::connect() {
    struct sockaddr_in name;

    if (m_nSocket >= 0)
        close(m_nSocket);

    m_nSocket = socket(PF_INET, SOCK_DGRAM, 0);

    if (m_nSocket < 0)
        throw SystemError("socket()");

    name.sin_family = AF_INET;
    name.sin_port = htons(this->nPort);

    struct hostent *pHost = gethostbyname(this->strHost.c_str());

    if (!pHost)
        throw SystemError("gethostbyname()");

    name.sin_addr = *(struct in_addr *)pHost->h_addr;

    if (::connect(m_nSocket, (struct sockaddr *)&name, sizeof(name)) < 0)
        throw SystemError("connect()");
}

const std::vector<unsigned int> &UNAP::get_format_values() {
    m_formatValues.clear();

    for (const std::string &strFormat : formats) {
        auto iFormat = g_formats.find(strFormat);

        if (iFormat != g_formats.end())
            m_formatValues.push_back(iFormat->second);
    }

    return m_formatValues;
}

unsigned int UNAP::get_channel_count() const {
    return this->channels;
}

snd_pcm_uframes_t UNAP::get_buffer_size() const {
    return this->buffer_size;
}

snd_pcm_uframes_t UNAP::get_period_size() const {
    return this->buffer_size;
}

size_t UNAP::get_bytes_per_frame() const {
    return get_channel_count()*m_cBitsPerSample/8;
}

snd_pcm_format_t UNAP::get_format() const {
    return this->format;
}

unsigned int UNAP::get_rate() const {
    return this->rate;
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-13 14:52:01 +0200 (Mi, 13. Mai 2009) $
Version:   $Revision: 17230 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

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

=========================================================================*/

#include "mitkNavigationDataToNavigationDataFilter.h"
#include "mitkNavigationData.h"

#include "mitkTestingMacros.h"

/**Documentation
* \brief test class to be able to instantiate the normally abstract (private constructor) mitk::NavigationDataToNavigationDataFilter
*/
class NavigationDataToNavigationDataFilterTestClass : public mitk::NavigationDataToNavigationDataFilter
{
public:
  mitkClassMacro(NavigationDataToNavigationDataFilterTestClass, NavigationDataToNavigationDataFilter);
  itkNewMacro(Self);
};

/**Documentation
 *  test for the class "NavigationDataToNavigationDataFilter".
 */
int mitkNavigationDataToNavigationDataFilterTest(int /* argc */, char* /*argv*/[])
{
  MITK_TEST_BEGIN("NavigationDataToNavigationDataFilter")

  // let's create an object of our class
  mitk::NavigationDataToNavigationDataFilter::Pointer myFilter = NavigationDataToNavigationDataFilterTestClass::New().GetPointer(); // create testing subclass, but treat it like the real NavigationDataToNavigationDataFilter

  MITK_TEST_CONDITION_REQUIRED(myFilter.IsNotNull(),"Testing instantiation");

  /* create helper objects: navigation data with position as origin, zero quaternion, zero error and data valid */
  mitk::NavigationData::PositionType initialPos;
  mitk::FillVector3D(initialPos, 1.0, 2.0, 3.0);
  mitk::NavigationData::OrientationType initialOri(0.1, 0.2, 0.3, 0.4);
  mitk::ScalarType initialError(22.22);
  bool initialValid(true);
  mitk::NavigationData::Pointer nd0 = mitk::NavigationData::New();
  nd0->SetPosition(initialPos);
  nd0->SetOrientation(initialOri);
  nd0->SetPositionAccuracy(initialError);
  nd0->SetDataValid(initialValid);

  MITK_TEST_CONDITION(myFilter->GetOutput() == NULL, "testing GetOutput()");

  myFilter->SetInput(nd0);
  MITK_TEST_CONDITION(myFilter->GetInput() == nd0, "testing Set-/GetInput()");
  MITK_TEST_CONDITION(myFilter->GetInput(0) == nd0, "testing Set-/GetInput(0)");
  MITK_TEST_CONDITION(myFilter->GetOutput() != NULL, "testing GetOutput() after SetInput()");
  MITK_TEST_CONDITION(myFilter->GetOutput(0) != NULL, "testing GetOutput() after SetInput()");
  MITK_TEST_CONDITION(myFilter->GetOutput(0) != nd0, "testing GetOutput() different object than input");

  mitk::NavigationData::Pointer nd1 = mitk::NavigationData::New();
  nd1->Graft(nd0);
  nd1->SetDataValid(false);
  myFilter->SetInput(1, nd1);
  MITK_TEST_CONDITION(myFilter->GetInput(1) == nd1, "testing Set-/GetInput(1)");
  MITK_TEST_CONDITION(myFilter->GetInput(0) == nd0, "testing Set-/GetInput(0) again");
  MITK_TEST_CONDITION(myFilter->GetOutput(1) != NULL, "testing GetOutput() after SetInput()");
  MITK_TEST_CONDITION(myFilter->GetOutput(0) != myFilter->GetOutput(1), "testing GetOutput(0) different object than GetOutput(1)");

  myFilter->SetInput(10, nd1);
  MITK_TEST_CONDITION(myFilter->GetNumberOfInputs() == 11, "testing SetInput(10) produces 11 outputs");
  MITK_TEST_CONDITION(myFilter->GetInput(10) == nd1, "testing Set-/GetInput(10)");

  myFilter->SetInput(10, NULL);
  MITK_TEST_CONDITION(myFilter->GetNumberOfInputs() == 10, "testing SetInput(10, NULL) removes output with index 10");

  myFilter->SetInput(1, NULL);
  MITK_TEST_CONDITION(myFilter->GetNumberOfInputs() == 10, "testing SetInput(1, NULL) does not change number of outputs");

  // always end with this!
  MITK_TEST_END();
}
<commit_msg>test cases extended<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-13 14:52:01 +0200 (Mi, 13. Mai 2009) $
Version:   $Revision: 17230 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

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

=========================================================================*/

#include "mitkNavigationDataToNavigationDataFilter.h"
#include "mitkNavigationData.h"

#include "mitkTestingMacros.h"

/**Documentation
* \brief test class to be able to instantiate the normally abstract (private constructor) mitk::NavigationDataToNavigationDataFilter
*/
class NavigationDataToNavigationDataFilterTestClass : public mitk::NavigationDataToNavigationDataFilter
{
public:
  mitkClassMacro(NavigationDataToNavigationDataFilterTestClass, NavigationDataToNavigationDataFilter);
  itkNewMacro(Self);
};

/**Documentation
 *  test for the class "NavigationDataToNavigationDataFilter".
 */
int mitkNavigationDataToNavigationDataFilterTest(int /* argc */, char* /*argv*/[])
{
  MITK_TEST_BEGIN("NavigationDataToNavigationDataFilter")

  // let's create an object of our class
  mitk::NavigationDataToNavigationDataFilter::Pointer myFilter = NavigationDataToNavigationDataFilterTestClass::New().GetPointer(); // create testing subclass, but treat it like the real NavigationDataToNavigationDataFilter

  MITK_TEST_CONDITION_REQUIRED(myFilter.IsNotNull(),"Testing instantiation");

  /* create helper objects: navigation data with position as origin, zero quaternion, zero error and data valid */
  mitk::NavigationData::PositionType initialPos;
  mitk::FillVector3D(initialPos, 1.0, 2.0, 3.0);
  mitk::NavigationData::OrientationType initialOri(0.1, 0.2, 0.3, 0.4);
  mitk::ScalarType initialError(22.22);
  bool initialValid(true);
  mitk::NavigationData::Pointer nd0 = mitk::NavigationData::New();
  nd0->SetPosition(initialPos);
  nd0->SetOrientation(initialOri);
  nd0->SetPositionAccuracy(initialError);
  nd0->SetDataValid(initialValid);
  nd0->SetName("testName");

  MITK_TEST_CONDITION(myFilter->GetOutput() == NULL, "testing GetOutput()");

  MITK_TEST_CONDITION(myFilter->GetInput() == NULL, "testing GetInput() without SetInput()");
  MITK_TEST_CONDITION(myFilter->GetInput(0) == NULL, "testing GetInput(0) without SetInput()");

  myFilter->SetInput(nd0);
  MITK_TEST_CONDITION(myFilter->GetInput() == nd0, "testing Set-/GetInput()");
  MITK_TEST_CONDITION(myFilter->GetInput(0) == nd0, "testing Set-/GetInput(0)");
  MITK_TEST_CONDITION(myFilter->GetOutput() != NULL, "testing GetOutput() after SetInput()");
  MITK_TEST_CONDITION(myFilter->GetOutput(0) != NULL, "testing GetOutput() after SetInput()");
  MITK_TEST_CONDITION(myFilter->GetOutput(0) != nd0, "testing GetOutput() different object than input");

  // check getInput() string input
  MITK_TEST_CONDITION(myFilter->GetInput("invalidName") == NULL, "testing GetInput(string) invalid string");
  MITK_TEST_CONDITION(myFilter->GetInput("testName") == nd0, "testing GetInput(string) valid string");

  // check getInputIndex() string input
  bool throwsException = false;
  try {
    myFilter->GetInputIndex("invalidName");
  }
  catch(std::invalid_argument e) {
    throwsException = true;
  }
  MITK_TEST_CONDITION_REQUIRED(throwsException, "testing GetInputIndex(string) invalid string");

  MITK_TEST_CONDITION(myFilter->GetInputIndex("testName") == 0, "testing GetInputIndex(string) valid string");

  mitk::NavigationData::Pointer nd1 = mitk::NavigationData::New();
  nd1->Graft(nd0);
  nd1->SetDataValid(false);
  myFilter->SetInput(1, nd1);
  MITK_TEST_CONDITION(myFilter->GetInput(1) == nd1, "testing Set-/GetInput(1)");
  MITK_TEST_CONDITION(myFilter->GetInput(0) == nd0, "testing Set-/GetInput(0) again");
  MITK_TEST_CONDITION(myFilter->GetOutput(1) != NULL, "testing GetOutput() after SetInput()");
  MITK_TEST_CONDITION(myFilter->GetOutput(0) != myFilter->GetOutput(1), "testing GetOutput(0) different object than GetOutput(1)");

  myFilter->SetInput(10, nd1);
  MITK_TEST_CONDITION(myFilter->GetNumberOfInputs() == 11, "testing SetInput(10) produces 11 outputs");
  MITK_TEST_CONDITION(myFilter->GetInput(10) == nd1, "testing Set-/GetInput(10)");

  myFilter->SetInput(10, NULL);
  MITK_TEST_CONDITION(myFilter->GetNumberOfInputs() == 10, "testing SetInput(10, NULL) removes output with index 10");

  myFilter->SetInput(1, NULL);
  MITK_TEST_CONDITION(myFilter->GetNumberOfInputs() == 10, "testing SetInput(1, NULL) does not change number of outputs");

  // always end with this!
  MITK_TEST_END();
}
<|endoftext|>


<commit_before>#pragma once

#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>

#if defined(ENABLE_LLVM) && !defined(NDEBUG) && !defined(EMSCRIPTEN)
#include <llvm/IR/Constants.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Value.h>
#include <llvm/IR/ValueSymbolTable.h>
#include <llvm/AsmParser/Parser.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/SourceMgr.h>
#endif

#include "definitions.hpp"

namespace processwarp {
  namespace Util {
    /**
     * Convert instruction code to readable string.
     * @param code Instruction code.
     * @return Converted string.
     */
    std::string code2str(instruction_t code);

    /**
     * Convert integer to decimal string.
     * @param v Integer.
     * @return Converted string.
     */
    template<class T> std::string num2dec_str(T v) {
      return std::to_string(v);
    }

    /**
     * Convert integer to hex string.
     * @param v Integer.
     * @return Converted string.
     */
    template<class T> std::string num2hex_str(T v) {
      std::ostringstream os;
      os << std::hex << std::setfill('0') << std::setw(sizeof(T) * 2) << v;
      return os.str();
    }

    template<> std::string num2hex_str<uint8_t>(uint8_t v);

    inline std::string numptr2str(const void* ptr, unsigned int size) {
      longest_uint_t buffer;
      std::memcpy(&buffer, ptr, size);
      std::ostringstream os;
      os << std::hex << std::setfill('0') << std::setw(size * 2) << buffer;
      return os.str();
    }

    /**
     * Convert hex formated string to integer.
     * @param str Hex formated string.
     * @return Converted integer.
     */
    template<class T> T hex_str2num(const std::string& str) {
      std::istringstream is(str);
      T v;
      is >> std::hex >> v;
      return v;
    }

    template<> uint8_t hex_str2num<uint8_t>(const std::string& str);

    /**
     * Convert address string to vaddr_t.
     * @param str address string.
     * @return Converted address.
     */
    inline vaddr_t str2vaddr(const std::string& str) {
      return hex_str2num<vaddr_t>(str);
    }

    /**
     * Converted address vaddr_t to string.
     * @param addr address vaddr_t.
     * @return Converted address.
     */
    inline std::string vaddr2str(vaddr_t addr) {
      return num2hex_str<vaddr_t>(addr);
    }

    /**
     * Show alert to fix function when NDEBUG isn't defined.
     * @param mesg Message to show.
     */
#ifdef NDEBUG
#define fixme(mesg) //
#else
#define fixme(mesg) Util::_fixme(__LINE__, __FILE__, mesg);
#endif
    void _fixme(long line, const char* file, std::string mesg);

    /**
     * Show debug message when NEBUG isn't defined.
     * @param mesg Message to show (format is the same to printf).
     */
#ifdef NDEBUG
#define print_debug(...) //
#else  // NDEBUG
#ifndef EMSCRIPTEN
#define print_debug(...) {						\
      fprintf(stderr, "\x1b[36mdebug\x1b[39m [%d@" __FILE__ "] ", __LINE__); \
      fprintf(stderr, "" __VA_ARGS__);					\
    }
#else  // EMSCRIPTEN
#define print_debug(...) {						\
      fprintf(stderr, "debug [%d@" __FILE__ "] ", __LINE__); \
      fprintf(stderr, "" __VA_ARGS__);					\
    }
#endif // EMSCRIPTEN
#endif // NDEBUG

#if !defined(ENABLE_LLVM) || defined(NDEBUG) || defined(EMSCRIPTEN)
#define save_llvm_instruction(I) //
#define print_llvm_instruction() //
#else
    extern const llvm::Instruction* llvm_instruction;
#define save_llvm_instruction(I) Util::llvm_instruction = (I)
#define print_llvm_instruction() Util::llvm_instruction->dump();
#endif
  }
}
<commit_msg>avoid compile error on memcpy<commit_after>#pragma once

#include <cstring>

#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>

#if defined(ENABLE_LLVM) && !defined(NDEBUG) && !defined(EMSCRIPTEN)
#include <llvm/IR/Constants.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Value.h>
#include <llvm/IR/ValueSymbolTable.h>
#include <llvm/AsmParser/Parser.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/SourceMgr.h>
#endif

#include "definitions.hpp"

namespace processwarp {
  namespace Util {
    /**
     * Convert instruction code to readable string.
     * @param code Instruction code.
     * @return Converted string.
     */
    std::string code2str(instruction_t code);

    /**
     * Convert integer to decimal string.
     * @param v Integer.
     * @return Converted string.
     */
    template<class T> std::string num2dec_str(T v) {
      return std::to_string(v);
    }

    /**
     * Convert integer to hex string.
     * @param v Integer.
     * @return Converted string.
     */
    template<class T> std::string num2hex_str(T v) {
      std::ostringstream os;
      os << std::hex << std::setfill('0') << std::setw(sizeof(T) * 2) << v;
      return os.str();
    }

    template<> std::string num2hex_str<uint8_t>(uint8_t v);

    inline std::string numptr2str(const void* ptr, unsigned int size) {
      longest_uint_t buffer;
      std::memcpy(&buffer, ptr, size);
      std::ostringstream os;
      os << std::hex << std::setfill('0') << std::setw(size * 2) << buffer;
      return os.str();
    }

    /**
     * Convert hex formated string to integer.
     * @param str Hex formated string.
     * @return Converted integer.
     */
    template<class T> T hex_str2num(const std::string& str) {
      std::istringstream is(str);
      T v;
      is >> std::hex >> v;
      return v;
    }

    template<> uint8_t hex_str2num<uint8_t>(const std::string& str);

    /**
     * Convert address string to vaddr_t.
     * @param str address string.
     * @return Converted address.
     */
    inline vaddr_t str2vaddr(const std::string& str) {
      return hex_str2num<vaddr_t>(str);
    }

    /**
     * Converted address vaddr_t to string.
     * @param addr address vaddr_t.
     * @return Converted address.
     */
    inline std::string vaddr2str(vaddr_t addr) {
      return num2hex_str<vaddr_t>(addr);
    }

    /**
     * Show alert to fix function when NDEBUG isn't defined.
     * @param mesg Message to show.
     */
#ifdef NDEBUG
#define fixme(mesg) //
#else
#define fixme(mesg) Util::_fixme(__LINE__, __FILE__, mesg);
#endif
    void _fixme(long line, const char* file, std::string mesg);

    /**
     * Show debug message when NEBUG isn't defined.
     * @param mesg Message to show (format is the same to printf).
     */
#ifdef NDEBUG
#define print_debug(...) //
#else  // NDEBUG
#ifndef EMSCRIPTEN
#define print_debug(...) {						\
      fprintf(stderr, "\x1b[36mdebug\x1b[39m [%d@" __FILE__ "] ", __LINE__); \
      fprintf(stderr, "" __VA_ARGS__);					\
    }
#else  // EMSCRIPTEN
#define print_debug(...) {						\
      fprintf(stderr, "debug [%d@" __FILE__ "] ", __LINE__); \
      fprintf(stderr, "" __VA_ARGS__);					\
    }
#endif // EMSCRIPTEN
#endif // NDEBUG

#if !defined(ENABLE_LLVM) || defined(NDEBUG) || defined(EMSCRIPTEN)
#define save_llvm_instruction(I) //
#define print_llvm_instruction() //
#else
    extern const llvm::Instruction* llvm_instruction;
#define save_llvm_instruction(I) Util::llvm_instruction = (I)
#define print_llvm_instruction() Util::llvm_instruction->dump();
#endif
  }
}
<|endoftext|>


<commit_before>/*
The MIT License

Copyright (c) 2008 Dennis Mllegaard Pedersen <dennis@moellegaard.dk>

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

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

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

ServerListView::ServerListView(const Query& query, long sort) : serverList(NULL), version(0) {
	this->query = query;
	this->currentSortMode = sort;
	wxLogDebug(_T("ServerListView() (%lx - version = %d - query = %s"), (long int)this, this->version, query.get().c_str());
}

<commit_msg>Quell shadows warning<commit_after>/*
The MIT License

Copyright (c) 2008 Dennis Mllegaard Pedersen <dennis@moellegaard.dk>

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

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

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

ServerListView::ServerListView(const Query& thequery, long sort) : serverList(NULL), version(0) {
	this->query = thequery;
	this->currentSortMode = sort;
	wxLogDebug(_T("ServerListView() (%lx - version = %d - query = %s"), (long int)this, this->version, query.get().c_str());
}

<|endoftext|>


<commit_before><commit_msg>cppcheck: zerodiv<commit_after><|endoftext|>