<commit_before>//===- unittest/ProfileData/CoverageMappingTest.cpp -------------------------=//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ProfileData/CoverageMapping.h"
#include "llvm/ProfileData/CoverageMappingReader.h"
#include "llvm/ProfileData/CoverageMappingWriter.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"

#include <sstream>

using namespace llvm;
using namespace coverage;

static ::testing::AssertionResult NoError(std::error_code EC) {
  if (!EC)
    return ::testing::AssertionSuccess();
  return ::testing::AssertionFailure() << "error " << EC.value()
                                       << ": " << EC.message();
}

namespace llvm {
namespace coverage {
void PrintTo(const Counter &C, ::std::ostream *os) {
  if (C.isZero())
    *os << "Zero";
  else if (C.isExpression())
    *os << "Expression " << C.getExpressionID();
  else
    *os << "Counter " << C.getCounterID();
}

void PrintTo(const CoverageSegment &S, ::std::ostream *os) {
  *os << "CoverageSegment(" << S.Line << ", " << S.Col << ", ";
  if (S.HasCount)
    *os << S.Count << ", ";
  *os << (S.IsRegionEntry ? "true" : "false") << ")";
}
}
}

namespace {

struct OneFunctionCoverageReader : CoverageMappingReader {
  StringRef Name;
  uint64_t Hash;
  std::vector<StringRef> Filenames;
  ArrayRef<CounterMappingRegion> Regions;
  bool Done;

  OneFunctionCoverageReader(StringRef Name, uint64_t Hash,
                            ArrayRef<StringRef> Filenames,
                            ArrayRef<CounterMappingRegion> Regions)
      : Name(Name), Hash(Hash), Filenames(Filenames), Regions(Regions),
        Done(false) {}

  std::error_code readNextRecord(CoverageMappingRecord &Record) override {
    if (Done)
      return instrprof_error::eof;
    Done = true;

    Record.FunctionName = Name;
    Record.FunctionHash = Hash;
    Record.Filenames = Filenames;
    Record.Expressions = {};
    Record.MappingRegions = Regions;
    return instrprof_error::success;
  }
};

struct CoverageMappingTest : ::testing::Test {
  StringMap<unsigned> Files;
  unsigned NextFile;
  std::vector<CounterMappingRegion> InputCMRs;

  std::vector<StringRef> OutputFiles;
  std::vector<CounterExpression> OutputExpressions;
  std::vector<CounterMappingRegion> OutputCMRs;

  InstrProfWriter ProfileWriter;
  std::unique_ptr<IndexedInstrProfReader> ProfileReader;

  std::unique_ptr<CoverageMapping> LoadedCoverage;

  void SetUp() override {
    NextFile = 0;
    ProfileWriter.setOutputSparse(false);
  }

  unsigned getFile(StringRef Name) {
    auto R = Files.find(Name);
    if (R != Files.end())
      return R->second;
    Files[Name] = NextFile;
    return NextFile++;
  }

  void addCMR(Counter C, StringRef File, unsigned LS, unsigned CS, unsigned LE,
              unsigned CE) {
    InputCMRs.push_back(
        CounterMappingRegion::makeRegion(C, getFile(File), LS, CS, LE, CE));
  }

  void addExpansionCMR(StringRef File, StringRef ExpandedFile, unsigned LS,
                       unsigned CS, unsigned LE, unsigned CE) {
    InputCMRs.push_back(CounterMappingRegion::makeExpansion(
        getFile(File), getFile(ExpandedFile), LS, CS, LE, CE));
  }

  std::string writeCoverageRegions() {
    SmallVector<unsigned, 8> FileIDs;
    for (const auto &E : Files)
      FileIDs.push_back(E.getValue());
    std::string Coverage;
    llvm::raw_string_ostream OS(Coverage);
    CoverageMappingWriter(FileIDs, None, InputCMRs).write(OS);
    return OS.str();
  }

  void readCoverageRegions(std::string Coverage) {
    SmallVector<StringRef, 8> Filenames;
    for (const auto &E : Files)
      Filenames.push_back(E.getKey());
    RawCoverageMappingReader Reader(Coverage, Filenames, OutputFiles,
                                    OutputExpressions, OutputCMRs);
    ASSERT_TRUE(NoError(Reader.read()));
  }

  void readProfCounts() {
    auto Profile = ProfileWriter.writeBuffer();
    auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
    ASSERT_TRUE(NoError(ReaderOrErr.getError()));
    ProfileReader = std::move(ReaderOrErr.get());
  }

  void loadCoverageMapping(StringRef FuncName, uint64_t Hash,
                           bool EmitFilenames = true) {
    std::string Regions = writeCoverageRegions();
    readCoverageRegions(Regions);

    SmallVector<StringRef, 8> Filenames;
    if (EmitFilenames)
      for (const auto &E : Files)
        Filenames.push_back(E.getKey());
    OneFunctionCoverageReader CovReader(FuncName, Hash, Filenames, OutputCMRs);
    auto CoverageOrErr = CoverageMapping::load(CovReader, *ProfileReader);
    ASSERT_TRUE(NoError(CoverageOrErr.getError()));
    LoadedCoverage = std::move(CoverageOrErr.get());
  }
};

struct MaybeSparseCoverageMappingTest
    : public CoverageMappingTest,
      public ::testing::WithParamInterface<bool> {
  void SetUp() {
    CoverageMappingTest::SetUp();
    ProfileWriter.setOutputSparse(GetParam());
  }
};

TEST_P(MaybeSparseCoverageMappingTest, basic_write_read) {
  addCMR(Counter::getCounter(0), "foo", 1, 1, 1, 1);
  addCMR(Counter::getCounter(1), "foo", 2, 1, 2, 2);
  addCMR(Counter::getZero(),     "foo", 3, 1, 3, 4);
  addCMR(Counter::getCounter(2), "foo", 4, 1, 4, 8);
  addCMR(Counter::getCounter(3), "bar", 1, 2, 3, 4);
  std::string Coverage = writeCoverageRegions();
  readCoverageRegions(Coverage);

  size_t N = makeArrayRef(InputCMRs).size();
  ASSERT_EQ(N, OutputCMRs.size());
  for (size_t I = 0; I < N; ++I) {
    ASSERT_EQ(InputCMRs[I].Count,      OutputCMRs[I].Count);
    ASSERT_EQ(InputCMRs[I].FileID,     OutputCMRs[I].FileID);
    ASSERT_EQ(InputCMRs[I].startLoc(), OutputCMRs[I].startLoc());
    ASSERT_EQ(InputCMRs[I].endLoc(),   OutputCMRs[I].endLoc());
    ASSERT_EQ(InputCMRs[I].Kind,       OutputCMRs[I].Kind);
  }
}

TEST_P(MaybeSparseCoverageMappingTest, expansion_gets_first_counter) {
  addCMR(Counter::getCounter(1), "foo", 10, 1, 10, 2);
  // This starts earlier in "foo", so the expansion should get its counter.
  addCMR(Counter::getCounter(2), "foo", 1, 1, 20, 1);
  addExpansionCMR("bar", "foo", 3, 3, 3, 3);
  std::string Coverage = writeCoverageRegions();
  readCoverageRegions(Coverage);

  ASSERT_EQ(CounterMappingRegion::ExpansionRegion, OutputCMRs[2].Kind);
  ASSERT_EQ(Counter::getCounter(2), OutputCMRs[2].Count);
  ASSERT_EQ(3U, OutputCMRs[2].LineStart);
}

TEST_P(MaybeSparseCoverageMappingTest, basic_coverage_iteration) {
  InstrProfRecord Record("func", 0x1234, {30, 20, 10, 0});
  ProfileWriter.addRecord(std::move(Record));
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
  addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1);
  addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(7U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 1, 20, true),  Segments[0]);
  ASSERT_EQ(CoverageSegment(4, 7, 30, false), Segments[1]);
  ASSERT_EQ(CoverageSegment(5, 8, 10, true),  Segments[2]);
  ASSERT_EQ(CoverageSegment(9, 1, 30, false), Segments[3]);
  ASSERT_EQ(CoverageSegment(9, 9, false),     Segments[4]);
  ASSERT_EQ(CoverageSegment(10, 10, 0, true), Segments[5]);
  ASSERT_EQ(CoverageSegment(11, 11, false),   Segments[6]);
}

TEST_P(MaybeSparseCoverageMappingTest, uncovered_function) {
  readProfCounts();

  addCMR(Counter::getZero(), "file1", 1, 2, 3, 4);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(2U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 2, 0, true), Segments[0]);
  ASSERT_EQ(CoverageSegment(3, 4, false),   Segments[1]);
}

TEST_P(MaybeSparseCoverageMappingTest, uncovered_function_with_mapping) {
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(3U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 1, 0, true),  Segments[0]);
  ASSERT_EQ(CoverageSegment(4, 7, 0, false), Segments[1]);
  ASSERT_EQ(CoverageSegment(9, 9, false),    Segments[2]);
}

TEST_P(MaybeSparseCoverageMappingTest, combine_regions) {
  InstrProfRecord Record("func", 0x1234, {10, 20, 30});
  ProfileWriter.addRecord(std::move(Record));
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
  addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(4U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
  ASSERT_EQ(CoverageSegment(3, 3, 50, true), Segments[1]);
  ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
  ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
}

TEST_P(MaybeSparseCoverageMappingTest, dont_combine_expansions) {
  InstrProfRecord Record1("func", 0x1234, {10, 20});
  InstrProfRecord Record2("func", 0x1234, {0, 0});
  ProfileWriter.addRecord(std::move(Record1));
  ProfileWriter.addRecord(std::move(Record2));
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
  addCMR(Counter::getCounter(1), "include1", 6, 6, 7, 7);
  addExpansionCMR("file1", "include1", 3, 3, 4, 4);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(4U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
  ASSERT_EQ(CoverageSegment(3, 3, 20, true), Segments[1]);
  ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
  ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
}

TEST_P(MaybeSparseCoverageMappingTest, strip_filename_prefix) {
  InstrProfRecord Record("file1:func", 0x1234, {0});
  ProfileWriter.addRecord(std::move(Record));
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  loadCoverageMapping("file1:func", 0x1234);

  std::vector<std::string> Names;
  for (const auto &Func : LoadedCoverage->getCoveredFunctions())
    Names.push_back(Func.Name);
  ASSERT_EQ(1U, Names.size());
  ASSERT_EQ("func", Names[0]);
}

TEST_P(MaybeSparseCoverageMappingTest, strip_unknown_filename_prefix) {
  InstrProfRecord Record("<unknown>:func", 0x1234, {0});
  ProfileWriter.addRecord(std::move(Record));
  readProfCounts();

  addCMR(Counter::getCounter(0), "", 1, 1, 9, 9);
  loadCoverageMapping("<unknown>:func", 0x1234, /*EmitFilenames=*/false);

  std::vector<std::string> Names;
  for (const auto &Func : LoadedCoverage->getCoveredFunctions())
    Names.push_back(Func.Name);
  ASSERT_EQ(1U, Names.size());
  ASSERT_EQ("func", Names[0]);
}

INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseCoverageMappingTest,
                        ::testing::Bool());

} // end anonymous namespace
<commit_msg>[Coverage] Update testing methods to support more than two files<commit_after>//===- unittest/ProfileData/CoverageMappingTest.cpp -------------------------=//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ProfileData/CoverageMapping.h"
#include "llvm/ProfileData/CoverageMappingReader.h"
#include "llvm/ProfileData/CoverageMappingWriter.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"

#include <sstream>

using namespace llvm;
using namespace coverage;

static ::testing::AssertionResult NoError(std::error_code EC) {
  if (!EC)
    return ::testing::AssertionSuccess();
  return ::testing::AssertionFailure() << "error " << EC.value()
                                       << ": " << EC.message();
}

namespace llvm {
namespace coverage {
void PrintTo(const Counter &C, ::std::ostream *os) {
  if (C.isZero())
    *os << "Zero";
  else if (C.isExpression())
    *os << "Expression " << C.getExpressionID();
  else
    *os << "Counter " << C.getCounterID();
}

void PrintTo(const CoverageSegment &S, ::std::ostream *os) {
  *os << "CoverageSegment(" << S.Line << ", " << S.Col << ", ";
  if (S.HasCount)
    *os << S.Count << ", ";
  *os << (S.IsRegionEntry ? "true" : "false") << ")";
}
}
}

namespace {

struct OneFunctionCoverageReader : CoverageMappingReader {
  StringRef Name;
  uint64_t Hash;
  std::vector<StringRef> Filenames;
  ArrayRef<CounterMappingRegion> Regions;
  bool Done;

  OneFunctionCoverageReader(StringRef Name, uint64_t Hash,
                            ArrayRef<StringRef> Filenames,
                            ArrayRef<CounterMappingRegion> Regions)
      : Name(Name), Hash(Hash), Filenames(Filenames), Regions(Regions),
        Done(false) {}

  std::error_code readNextRecord(CoverageMappingRecord &Record) override {
    if (Done)
      return instrprof_error::eof;
    Done = true;

    Record.FunctionName = Name;
    Record.FunctionHash = Hash;
    Record.Filenames = Filenames;
    Record.Expressions = {};
    Record.MappingRegions = Regions;
    return instrprof_error::success;
  }
};

struct CoverageMappingTest : ::testing::Test {
  StringMap<unsigned> Files;
  std::vector<CounterMappingRegion> InputCMRs;

  std::vector<StringRef> OutputFiles;
  std::vector<CounterExpression> OutputExpressions;
  std::vector<CounterMappingRegion> OutputCMRs;

  InstrProfWriter ProfileWriter;
  std::unique_ptr<IndexedInstrProfReader> ProfileReader;

  std::unique_ptr<CoverageMapping> LoadedCoverage;

  void SetUp() override {
    ProfileWriter.setOutputSparse(false);
  }

  unsigned getFile(StringRef Name) {
    auto R = Files.find(Name);
    if (R != Files.end())
      return R->second;
    unsigned Index = Files.size();
    Files.emplace_second(Name, Index);
    return Index;
  }

  void addCMR(Counter C, StringRef File, unsigned LS, unsigned CS, unsigned LE,
              unsigned CE) {
    InputCMRs.push_back(
        CounterMappingRegion::makeRegion(C, getFile(File), LS, CS, LE, CE));
  }

  void addExpansionCMR(StringRef File, StringRef ExpandedFile, unsigned LS,
                       unsigned CS, unsigned LE, unsigned CE) {
    InputCMRs.push_back(CounterMappingRegion::makeExpansion(
        getFile(File), getFile(ExpandedFile), LS, CS, LE, CE));
  }

  std::string writeCoverageRegions() {
    SmallVector<unsigned, 8> FileIDs(Files.size());
    for (unsigned I = 0; I < FileIDs.size(); ++I)
      FileIDs[I] = I;
    std::string Coverage;
    llvm::raw_string_ostream OS(Coverage);
    CoverageMappingWriter(FileIDs, None, InputCMRs).write(OS);
    return OS.str();
  }

  void readCoverageRegions(std::string Coverage) {
    SmallVector<StringRef, 8> Filenames(Files.size());
    for (const auto &E : Files)
      Filenames[E.getValue()] = E.getKey();
    RawCoverageMappingReader Reader(Coverage, Filenames, OutputFiles,
                                    OutputExpressions, OutputCMRs);
    ASSERT_TRUE(NoError(Reader.read()));
  }

  void readProfCounts() {
    auto Profile = ProfileWriter.writeBuffer();
    auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
    ASSERT_TRUE(NoError(ReaderOrErr.getError()));
    ProfileReader = std::move(ReaderOrErr.get());
  }

  void loadCoverageMapping(StringRef FuncName, uint64_t Hash,
                           bool EmitFilenames = true) {
    std::string Regions = writeCoverageRegions();
    readCoverageRegions(Regions);

    SmallVector<StringRef, 8> Filenames;
    if (EmitFilenames) {
      Filenames.resize(Files.size());
      for (const auto &E : Files)
        Filenames[E.getValue()] = E.getKey();
    }
    OneFunctionCoverageReader CovReader(FuncName, Hash, Filenames, OutputCMRs);
    auto CoverageOrErr = CoverageMapping::load(CovReader, *ProfileReader);
    ASSERT_TRUE(NoError(CoverageOrErr.getError()));
    LoadedCoverage = std::move(CoverageOrErr.get());
  }
};

struct MaybeSparseCoverageMappingTest
    : public CoverageMappingTest,
      public ::testing::WithParamInterface<bool> {
  void SetUp() {
    CoverageMappingTest::SetUp();
    ProfileWriter.setOutputSparse(GetParam());
  }
};

TEST_P(MaybeSparseCoverageMappingTest, basic_write_read) {
  addCMR(Counter::getCounter(0), "foo", 1, 1, 1, 1);
  addCMR(Counter::getCounter(1), "foo", 2, 1, 2, 2);
  addCMR(Counter::getZero(),     "foo", 3, 1, 3, 4);
  addCMR(Counter::getCounter(2), "foo", 4, 1, 4, 8);
  addCMR(Counter::getCounter(3), "bar", 1, 2, 3, 4);
  std::string Coverage = writeCoverageRegions();
  readCoverageRegions(Coverage);

  size_t N = makeArrayRef(InputCMRs).size();
  ASSERT_EQ(N, OutputCMRs.size());
  for (size_t I = 0; I < N; ++I) {
    ASSERT_EQ(InputCMRs[I].Count,      OutputCMRs[I].Count);
    ASSERT_EQ(InputCMRs[I].FileID,     OutputCMRs[I].FileID);
    ASSERT_EQ(InputCMRs[I].startLoc(), OutputCMRs[I].startLoc());
    ASSERT_EQ(InputCMRs[I].endLoc(),   OutputCMRs[I].endLoc());
    ASSERT_EQ(InputCMRs[I].Kind,       OutputCMRs[I].Kind);
  }
}

TEST_P(MaybeSparseCoverageMappingTest,
       correct_deserialize_for_more_than_two_files) {
  const char *FileNames[] = {"bar", "baz", "foo"};
  static const unsigned N = array_lengthof(FileNames);

  for (unsigned I = 0; I < N; ++I)
    // Use LineStart to hold the index of the file name
    // in order to preserve that information during possible sorting of CMRs.
    addCMR(Counter::getCounter(0), FileNames[I], I, 1, I, 1);

  std::string Coverage = writeCoverageRegions();
  readCoverageRegions(Coverage);

  ASSERT_EQ(N, OutputCMRs.size());
  ASSERT_EQ(N, OutputFiles.size());

  for (unsigned I = 0; I < N; ++I) {
    ASSERT_GT(N, OutputCMRs[I].FileID);
    ASSERT_GT(N, OutputCMRs[I].LineStart);
    EXPECT_EQ(FileNames[OutputCMRs[I].LineStart],
              OutputFiles[OutputCMRs[I].FileID]);
  }
}

TEST_P(MaybeSparseCoverageMappingTest, load_coverage_for_more_than_two_files) {
  InstrProfRecord Record("func", 0x1234, {0});
  ProfileWriter.addRecord(std::move(Record));
  readProfCounts();

  const char *FileNames[] = {"bar", "baz", "foo"};
  static const unsigned N = array_lengthof(FileNames);

  for (unsigned I = 0; I < N; ++I)
    // Use LineStart to hold the index of the file name
    // in order to preserve that information during possible sorting of CMRs.
    addCMR(Counter::getCounter(0), FileNames[I], I, 1, I, 1);

  loadCoverageMapping("func", 0x1234);

  for (unsigned I = 0; I < N; ++I) {
    CoverageData Data = LoadedCoverage->getCoverageForFile(FileNames[I]);
    ASSERT_TRUE(!Data.empty());
    EXPECT_EQ(I, Data.begin()->Line);
  }
}

TEST_P(MaybeSparseCoverageMappingTest, expansion_gets_first_counter) {
  addCMR(Counter::getCounter(1), "foo", 10, 1, 10, 2);
  // This starts earlier in "foo", so the expansion should get its counter.
  addCMR(Counter::getCounter(2), "foo", 1, 1, 20, 1);
  addExpansionCMR("bar", "foo", 3, 3, 3, 3);
  std::string Coverage = writeCoverageRegions();
  readCoverageRegions(Coverage);

  ASSERT_EQ(CounterMappingRegion::ExpansionRegion, OutputCMRs[2].Kind);
  ASSERT_EQ(Counter::getCounter(2), OutputCMRs[2].Count);
  ASSERT_EQ(3U, OutputCMRs[2].LineStart);
}

TEST_P(MaybeSparseCoverageMappingTest, basic_coverage_iteration) {
  InstrProfRecord Record("func", 0x1234, {30, 20, 10, 0});
  ProfileWriter.addRecord(std::move(Record));
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
  addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1);
  addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(7U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 1, 20, true),  Segments[0]);
  ASSERT_EQ(CoverageSegment(4, 7, 30, false), Segments[1]);
  ASSERT_EQ(CoverageSegment(5, 8, 10, true),  Segments[2]);
  ASSERT_EQ(CoverageSegment(9, 1, 30, false), Segments[3]);
  ASSERT_EQ(CoverageSegment(9, 9, false),     Segments[4]);
  ASSERT_EQ(CoverageSegment(10, 10, 0, true), Segments[5]);
  ASSERT_EQ(CoverageSegment(11, 11, false),   Segments[6]);
}

TEST_P(MaybeSparseCoverageMappingTest, uncovered_function) {
  readProfCounts();

  addCMR(Counter::getZero(), "file1", 1, 2, 3, 4);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(2U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 2, 0, true), Segments[0]);
  ASSERT_EQ(CoverageSegment(3, 4, false),   Segments[1]);
}

TEST_P(MaybeSparseCoverageMappingTest, uncovered_function_with_mapping) {
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(3U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 1, 0, true),  Segments[0]);
  ASSERT_EQ(CoverageSegment(4, 7, 0, false), Segments[1]);
  ASSERT_EQ(CoverageSegment(9, 9, false),    Segments[2]);
}

TEST_P(MaybeSparseCoverageMappingTest, combine_regions) {
  InstrProfRecord Record("func", 0x1234, {10, 20, 30});
  ProfileWriter.addRecord(std::move(Record));
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
  addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(4U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
  ASSERT_EQ(CoverageSegment(3, 3, 50, true), Segments[1]);
  ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
  ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
}

TEST_P(MaybeSparseCoverageMappingTest, dont_combine_expansions) {
  InstrProfRecord Record1("func", 0x1234, {10, 20});
  InstrProfRecord Record2("func", 0x1234, {0, 0});
  ProfileWriter.addRecord(std::move(Record1));
  ProfileWriter.addRecord(std::move(Record2));
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
  addCMR(Counter::getCounter(1), "include1", 6, 6, 7, 7);
  addExpansionCMR("file1", "include1", 3, 3, 4, 4);
  loadCoverageMapping("func", 0x1234);

  CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
  ASSERT_EQ(4U, Segments.size());
  ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
  ASSERT_EQ(CoverageSegment(3, 3, 20, true), Segments[1]);
  ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
  ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
}

TEST_P(MaybeSparseCoverageMappingTest, strip_filename_prefix) {
  InstrProfRecord Record("file1:func", 0x1234, {0});
  ProfileWriter.addRecord(std::move(Record));
  readProfCounts();

  addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
  loadCoverageMapping("file1:func", 0x1234);

  std::vector<std::string> Names;
  for (const auto &Func : LoadedCoverage->getCoveredFunctions())
    Names.push_back(Func.Name);
  ASSERT_EQ(1U, Names.size());
  ASSERT_EQ("func", Names[0]);
}

TEST_P(MaybeSparseCoverageMappingTest, strip_unknown_filename_prefix) {
  InstrProfRecord Record("<unknown>:func", 0x1234, {0});
  ProfileWriter.addRecord(std::move(Record));
  readProfCounts();

  addCMR(Counter::getCounter(0), "", 1, 1, 9, 9);
  loadCoverageMapping("<unknown>:func", 0x1234, /*EmitFilenames=*/false);

  std::vector<std::string> Names;
  for (const auto &Func : LoadedCoverage->getCoveredFunctions())
    Names.push_back(Func.Name);
  ASSERT_EQ(1U, Names.size());
  ASSERT_EQ("func", Names[0]);
}

INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseCoverageMappingTest,
                        ::testing::Bool());

} // end anonymous namespace
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//  Software Guide : BeginCommandLineArgs
//    OUTPUTS: {mapProjectionExample-output.txt}
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// Map projection is an important issue when working with satellite
// images. In the orthorectification process, converting between
// geographic and cartographic coordinates is a key step. In this
// process, everything is integrated and you don't need to know the
// details.
//
// However, sometimes, you need to go hands-on and find out the
// nitty-gritty details.  This example shows you how to play with map
// projections in OTB and how to convert coordinates. In most cases,
// the underlying work is done by OSSIM.
//
// First, we start by including the otbMapProjections header. In this
// file, over 30 projections are defined and ready to use. It is easy
// to add new one.
//
// The otbGenericMapProjection enables you to instantiate a map
// projection from a WKT (Well Known Text) string, which is popular
// with OGR for example.
//
// Software Guide : EndLatex

#include <fstream>
#include <iomanip>

// Software Guide : BeginCodeSnippet
#include "otbSpatialReference.h"
#include "otbGenericMapProjection.h"
// Software Guide : EndCodeSnippet

int main(int argc, char* argv[])
{
  if (argc < 2)
    {
    std::cout << argv[0] << " <outputfile> "  << std::endl;

    return EXIT_FAILURE;
    }

  // Software Guide : BeginLatex
  //
  // We retrieve the command line parameters and put them in the
  // correct variables. The transforms are going to work with an
  // \doxygen{itk}{Point}.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  const char * outFileName = argv[1];

  itk::Point<double, 2> point;
  point[0] = 1.4835345;
  point[1] = 43.55968261;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The output of this program will be saved in a text file. We also want
  // to make sure that the precision of the digits will be enough.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::ofstream file;
  file.open(outFileName);
  file << std::setprecision(15);
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We can now instantiate our first map projection. Here, it is a
  // UTM projection. We also need to provide the information about
  // the zone and the hemisphere for the projection. These are
  // specific to the UTM projection.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::GenericMapProjection<otb::TransformDirection::FORWARD> MapProjectionType;
  otb::SpatialReference utmSRS = otb::SpatialReference::FromUTM(31,otb::SpatialReference::hemisphere::north);
  MapProjectionType::Pointer utmProjection = MapProjectionType::New();
  utmProjection->SetWkt(utmSRS.ToWkt());
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The TransformPoint() method returns the coordinates of the point in the
  // new projection.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  file << "Forward UTM projection: " << std::endl;
  file << point << " -> ";
  file << utmProjection->TransformPoint(point);
  file << std::endl << std::endl;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We follow the same path for the Lambert93 projection:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  // EPSG:2154 is the EPSG code for lambert 93
  otb::SpatialReference lamb93SRS = otb::SpatialReference::FromDescription("EPSG:3154");
  MapProjectionType::Pointer lambertProjection = MapProjectionType::New();
  lambertProjection->SetWkt(lamb93SRS.ToWkt());

  file << "Forward Lambert93 projection: " << std::endl;
  file << point << " -> ";
  file << lambertProjection->TransformPoint(point);
  file << std::endl << std::endl;

  // Software Guide : BeginLatex
  //
  // And of course, we don't forget to close the file:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  file.close();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The final output of the program should be:
  //
  //  \begin{verbatim}
  //   Forward UTM projection:
  //       [1.4835345, 43.55968261] -> [377522.448427013, 4824086.71129131]
  //
  //   Forward Lambert93 projection:
  //      [1.4835345, 43.55968261] -> [577437.889798954, 6274578.791561]
  //
  //   \end{verbatim}
  //
  // Software Guide : EndLatex

  return EXIT_SUCCESS;
}
<commit_msg>BUG: update example typo<commit_after>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//  Software Guide : BeginCommandLineArgs
//    OUTPUTS: {mapProjectionExample-output.txt}
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// Map projection is an important issue when working with satellite
// images. In the orthorectification process, converting between
// geographic and cartographic coordinates is a key step. In this
// process, everything is integrated and you don't need to know the
// details.
//
// However, sometimes, you need to go hands-on and find out the
// nitty-gritty details.  This example shows you how to play with map
// projections in OTB and how to convert coordinates. In most cases,
// the underlying work is done by OSSIM.
//
// First, we start by including the otbMapProjections header. In this
// file, over 30 projections are defined and ready to use. It is easy
// to add new one.
//
// The otbGenericMapProjection enables you to instantiate a map
// projection from a WKT (Well Known Text) string, which is popular
// with OGR for example.
//
// Software Guide : EndLatex

#include <fstream>
#include <iomanip>

// Software Guide : BeginCodeSnippet
#include "otbSpatialReference.h"
#include "otbGenericMapProjection.h"
// Software Guide : EndCodeSnippet

int main(int argc, char* argv[])
{
  if (argc < 2)
    {
    std::cout << argv[0] << " <outputfile> "  << std::endl;

    return EXIT_FAILURE;
    }

  // Software Guide : BeginLatex
  //
  // We retrieve the command line parameters and put them in the
  // correct variables. The transforms are going to work with an
  // \doxygen{itk}{Point}.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  const char * outFileName = argv[1];

  itk::Point<double, 2> point;
  point[0] = 1.4835345;
  point[1] = 43.55968261;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The output of this program will be saved in a text file. We also want
  // to make sure that the precision of the digits will be enough.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::ofstream file;
  file.open(outFileName);
  file << std::setprecision(15);
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We can now instantiate our first map projection. Here, it is a
  // UTM projection. We also need to provide the information about
  // the zone and the hemisphere for the projection. These are
  // specific to the UTM projection.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::GenericMapProjection<otb::TransformDirection::FORWARD> MapProjectionType;
  otb::SpatialReference utmSRS = otb::SpatialReference::FromUTM(31,otb::SpatialReference::hemisphere::north);
  MapProjectionType::Pointer utmProjection = MapProjectionType::New();
  utmProjection->SetWkt(utmSRS.ToWkt());
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The TransformPoint() method returns the coordinates of the point in the
  // new projection.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  file << "Forward UTM projection: " << std::endl;
  file << point << " -> ";
  file << utmProjection->TransformPoint(point);
  file << std::endl << std::endl;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We follow the same path for the Lambert93 projection:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  // EPSG:2154 is the EPSG code for lambert 93
  otb::SpatialReference lamb93SRS = otb::SpatialReference::FromDescription("EPSG:2154");
  MapProjectionType::Pointer lambertProjection = MapProjectionType::New();
  lambertProjection->SetWkt(lamb93SRS.ToWkt());

  file << "Forward Lambert93 projection: " << std::endl;
  file << point << " -> ";
  file << lambertProjection->TransformPoint(point);
  file << std::endl << std::endl;

  // Software Guide : BeginLatex
  //
  // And of course, we don't forget to close the file:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  file.close();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The final output of the program should be:
  //
  //  \begin{verbatim}
  //   Forward UTM projection:
  //       [1.4835345, 43.55968261] -> [377522.448427013, 4824086.71129131]
  //
  //   Forward Lambert93 projection:
  //      [1.4835345, 43.55968261] -> [577437.889798954, 6274578.791561]
  //
  //   \end{verbatim}
  //
  // Software Guide : EndLatex

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// call from command line like, for instance:
// root -l 'acat19.cpp()'

R__LOAD_LIBRARY(libRooFit)

#include <chrono>
#include <iostream>

using namespace RooFit;

////////////////////////////////////////////////////////////////////////////////////////////////////
// timing_flag is used to activate only selected timing statements [1-7]
// num_cpu: -1 is special option -> compare overhead communication protocol (wrt 1 cpu)
// parallel_interleave: 0 = blocks of equal size, 1 = interleave, 2 = simultaneous pdfs mode
//                      { BulkPartition=0, Interleave=1, SimComponents=2, Hybrid=3 }
////////////////////////////////////////////////////////////////////////////////////////////////////

void acat19() {
    TFile *_file0 = TFile::Open("/user/pbos/data_atlas/carsten/comb-5xs-80ifb-v8.root");

    RooWorkspace* w = static_cast<RooWorkspace*>(gDirectory->Get("combWS"));

    RooAbsData *data = w->data("combData");
    auto mc = dynamic_cast<RooStats::ModelConfig *>(w->genobj("ModelConfig"));
    auto global_observables = mc->GetGlobalObservables();
    auto nuisance_parameters = mc->GetNuisanceParameters();
    RooAbsPdf *pdf = w->pdf(mc->GetPdf()->GetName());

    w->var("mu")->setVal(1.5);

    RooAbsReal *nll = pdf->createNLL(*data,
                            RooFit::GlobalObservables(*global_observables),
                            RooFit::Constrain(*nuisance_parameters),
                            RooFit::Offset(kTRUE));

    RooFit::MultiProcess::GradMinimizer m(*nll, 1);

    m.setPrintLevel(-1);
    m.setStrategy(0);
    m.setProfile(false);
    m.optimizeConst(2);
    m.setMinimizerType("Minuit2");
    m.setVerbose(kTRUE);

    auto start = std::chrono::high_resolution_clock::now();
    m.migrad();
    auto end = std::chrono::high_resolution_clock::now();
    auto elapsed_seconds =
        std::chrono::duration_cast<std::chrono::duration<double>>(
            end - start).count();
    std::cout << "migrad: " << elapsed_seconds << "s" << std::endl;
}
<commit_msg>add benchmarking info back in in acat19 script (d'oh)<commit_after>// call from command line like, for instance:
// root -l 'acat19.cpp()'

R__LOAD_LIBRARY(libRooFit)

#include <chrono>
#include <iostream>

using namespace RooFit;

////////////////////////////////////////////////////////////////////////////////////////////////////
// timing_flag is used to activate only selected timing statements [1-7]
// num_cpu: -1 is special option -> compare overhead communication protocol (wrt 1 cpu)
// parallel_interleave: 0 = blocks of equal size, 1 = interleave, 2 = simultaneous pdfs mode
//                      { BulkPartition=0, Interleave=1, SimComponents=2, Hybrid=3 }
////////////////////////////////////////////////////////////////////////////////////////////////////

void acat19() {
    RooMsgService::instance().deleteStream(0);
    RooMsgService::instance().deleteStream(0);

    RooMsgService::instance().addStream(RooFit::DEBUG, RooFit::Topic(RooFit::Benchmarking1));
    RooMsgService::instance().addStream(RooFit::DEBUG, RooFit::Topic(RooFit::Benchmarking2));

    std::size_t seed = 1;
    RooRandom::randomGenerator()->SetSeed(seed);

    TFile *_file0 = TFile::Open("/user/pbos/data_atlas/carsten/comb-5xs-80ifb-v8.root");

    RooWorkspace* w = static_cast<RooWorkspace*>(gDirectory->Get("combWS"));

    RooAbsData *data = w->data("combData");
    auto mc = dynamic_cast<RooStats::ModelConfig *>(w->genobj("ModelConfig"));
    auto global_observables = mc->GetGlobalObservables();
    auto nuisance_parameters = mc->GetNuisanceParameters();
    RooAbsPdf *pdf = w->pdf(mc->GetPdf()->GetName());

    w->var("mu")->setVal(1.5);

    RooAbsReal *nll = pdf->createNLL(*data,
                            RooFit::GlobalObservables(*global_observables),
                            RooFit::Constrain(*nuisance_parameters),
                            RooFit::Offset(kTRUE));

    RooFit::MultiProcess::GradMinimizer m(*nll, 1);

    m.setPrintLevel(-1);
    m.setStrategy(0);
    m.setProfile(false);
    m.optimizeConst(2);
    m.setMinimizerType("Minuit2");
    m.setVerbose(kTRUE);

    auto start = std::chrono::high_resolution_clock::now();
    m.migrad();
    auto end = std::chrono::high_resolution_clock::now();
    auto elapsed_seconds =
        std::chrono::duration_cast<std::chrono::duration<double>>(
            end - start).count();
    std::cout << "migrad: " << elapsed_seconds << "s" << std::endl;
}
<|endoftext|>


<commit_before>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2016-2017 Raffaello D. Di Napoli

This file is part of Lofty.

Lofty is free software: you can redistribute it and/or modify it under the terms of version 2.1 of the GNU
Lesser General Public License as published by the Free Software Foundation.

Lofty is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more details.
------------------------------------------------------------------------------------------------------------*/

#include <lofty.hxx>
#include <lofty/testing/test_case.hxx>
#include <lofty/text.hxx>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace lofty { namespace test {

LOFTY_TESTING_TEST_CASE_FUNC(
   io_text_istream_scan_0_captures,
   "lofty::io::text::istream::scan() – no captures"
) {
   LOFTY_TRACE_FUNC(this);

   // Syntax errors.
   LOFTY_TESTING_ASSERT_THROWS(text::syntax_error, io::text::str_istream(str::empty).scan(LOFTY_SL("+")));
   LOFTY_TESTING_ASSERT_THROWS(text::syntax_error, io::text::str_istream(str::empty).scan(LOFTY_SL("(")));

   // No captures.
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(str::empty).scan(str::empty));
   //? LOFTY_TESTING_ASSERT_DOES_NOT_THROW(io::text::str_istream(LOFTY_SL("x")).scan(str::empty));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("x")).scan(LOFTY_SL("x")));
   //? LOFTY_TESTING_ASSERT_DOES_NOT_THROW(io::text::str_istream(LOFTY_SL("xx")).scan(LOFTY_SL("x")));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("x")).scan(LOFTY_SL("x+")));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("x")).scan(LOFTY_SL("^x$")));
   //? LOFTY_TESTING_ASSERT_DOES_NOT_THROW(io::text::str_istream(LOFTY_SL("xx")).scan(LOFTY_SL("^x$")));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("x")).scan(LOFTY_SL("^x+$")));
}

}} //namespace lofty::test

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace lofty { namespace test {

LOFTY_TESTING_TEST_CASE_FUNC(
   io_text_istream_scan_1_capture,
   "lofty::io::text::istream::scan() – one capture"
) {
   LOFTY_TRACE_FUNC(this);

   str captured1;
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("a")).scan(LOFTY_SL("^()$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("a"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("xb")).scan(LOFTY_SL("^x()$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("b"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("cx")).scan(LOFTY_SL("^()x$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("c"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("xdx")).scan(LOFTY_SL("^x()x$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("d"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("(e)")).scan(LOFTY_SL("^\\(()\\)$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("e"));

   int captured2;
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("31")).scan(LOFTY_SL("^()$"), &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, 31);
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("20")).scan(LOFTY_SL("^(x)$"), &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, 32);
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("0x21")).scan(LOFTY_SL("^(#)$"), &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, 33);
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("0x22")).scan(LOFTY_SL("^(#x)$"), &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, 34);
}

}} //namespace lofty::test

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace lofty { namespace test {

LOFTY_TESTING_TEST_CASE_FUNC(
   io_text_istream_scan_competing_str_with_format,
   "lofty::io::text::istream::scan() – competing string captures with format"
) {
   LOFTY_TRACE_FUNC(this);

   str captured1, captured2;

   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("ab")).scan(LOFTY_SL("^(.)(.)$"), &captured1, &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("a"));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, LOFTY_SL("b"));
   // Both formats are greedy, but the first one will consume characters first.
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("abcd")).scan(LOFTY_SL("^(.+)(.+)$"), &captured1, &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("abc"));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, LOFTY_SL("d"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("axb")).scan(LOFTY_SL("^()x()$"), &captured1, &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("a"));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, LOFTY_SL("b"));
}

}} //namespace lofty::test
<commit_msg>Add tests for bracket expressions<commit_after>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2016-2017 Raffaello D. Di Napoli

This file is part of Lofty.

Lofty is free software: you can redistribute it and/or modify it under the terms of version 2.1 of the GNU
Lesser General Public License as published by the Free Software Foundation.

Lofty is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more details.
------------------------------------------------------------------------------------------------------------*/

#include <lofty.hxx>
#include <lofty/testing/test_case.hxx>
#include <lofty/text.hxx>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace lofty { namespace test {

LOFTY_TESTING_TEST_CASE_FUNC(
   io_text_istream_scan_0_captures,
   "lofty::io::text::istream::scan() – no captures"
) {
   LOFTY_TRACE_FUNC(this);

   // Syntax errors.
   LOFTY_TESTING_ASSERT_THROWS(text::syntax_error, io::text::str_istream(str::empty).scan(LOFTY_SL("+")));
   LOFTY_TESTING_ASSERT_THROWS(text::syntax_error, io::text::str_istream(str::empty).scan(LOFTY_SL("(")));

   // No captures.
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(str::empty).scan(str::empty));
   //? LOFTY_TESTING_ASSERT_DOES_NOT_THROW(io::text::str_istream(LOFTY_SL("x")).scan(str::empty));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("x")).scan(LOFTY_SL("x")));
   //? LOFTY_TESTING_ASSERT_DOES_NOT_THROW(io::text::str_istream(LOFTY_SL("xx")).scan(LOFTY_SL("x")));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("x")).scan(LOFTY_SL("x+")));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("x")).scan(LOFTY_SL("^x$")));
   //? LOFTY_TESTING_ASSERT_DOES_NOT_THROW(io::text::str_istream(LOFTY_SL("xx")).scan(LOFTY_SL("^x$")));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("x")).scan(LOFTY_SL("^x+$")));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("a")).scan(LOFTY_SL("^[a]$")));
   LOFTY_TESTING_ASSERT_FALSE(io::text::str_istream(LOFTY_SL("a")).scan(LOFTY_SL("^[b]$")));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("a")).scan(LOFTY_SL("^[^m]$")));
   LOFTY_TESTING_ASSERT_FALSE(io::text::str_istream(LOFTY_SL("m")).scan(LOFTY_SL("^[^m]$")));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("z")).scan(LOFTY_SL("^[^m]$")));
}

}} //namespace lofty::test

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace lofty { namespace test {

LOFTY_TESTING_TEST_CASE_FUNC(
   io_text_istream_scan_1_capture,
   "lofty::io::text::istream::scan() – one capture"
) {
   LOFTY_TRACE_FUNC(this);

   str captured1;
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("a")).scan(LOFTY_SL("^()$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("a"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("xb")).scan(LOFTY_SL("^x()$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("b"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("cx")).scan(LOFTY_SL("^()x$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("c"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("xdx")).scan(LOFTY_SL("^x()x$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("d"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("(e)")).scan(LOFTY_SL("^\\(()\\)$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("e"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("f")).scan(LOFTY_SL("^(f+)$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("f"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("g")).scan(LOFTY_SL("^([a-z]+)$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("g"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("h")).scan(LOFTY_SL("^([^ ]+)$"), &captured1));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("h"));

   int captured2;
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("31")).scan(LOFTY_SL("^()$"), &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, 31);
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("20")).scan(LOFTY_SL("^(x)$"), &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, 32);
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("0x21")).scan(LOFTY_SL("^(#)$"), &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, 33);
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("0x22")).scan(LOFTY_SL("^(#x)$"), &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, 34);
}

}} //namespace lofty::test

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace lofty { namespace test {

LOFTY_TESTING_TEST_CASE_FUNC(
   io_text_istream_scan_competing_str_with_format,
   "lofty::io::text::istream::scan() – competing string captures with format"
) {
   LOFTY_TRACE_FUNC(this);

   str captured1, captured2;

   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("ab")).scan(LOFTY_SL("^(.)(.)$"), &captured1, &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("a"));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, LOFTY_SL("b"));
   // Both formats are greedy, but the first one will consume characters first.
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("abcd")).scan(LOFTY_SL("^(.+)(.+)$"), &captured1, &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("abc"));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, LOFTY_SL("d"));
   LOFTY_TESTING_ASSERT_TRUE(io::text::str_istream(LOFTY_SL("axb")).scan(LOFTY_SL("^()x()$"), &captured1, &captured2));
   LOFTY_TESTING_ASSERT_EQUAL(captured1, LOFTY_SL("a"));
   LOFTY_TESTING_ASSERT_EQUAL(captured2, LOFTY_SL("b"));
}

}} //namespace lofty::test
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ucbstreamhelper.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: mba $ $Date: 2001-07-16 09:28:18 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <unotools/ucblockbytes.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <comphelper/processfactory.hxx>

#ifndef _COM_SUN_STAR_UCB_COMMANDABORTEDEXCEPTION_HPP_
#include <com/sun/star/ucb/CommandAbortedException.hpp>
#endif

#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HDL_
#include <com/sun/star/ucb/XCommandEnvironment.hdl>
#endif

#ifndef _COM_SUN_STAR_UCB_INSERTCOMMANDARGUMENT_HPP_
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASTREAMER_HPP_
#include <com/sun/star/io/XActiveDataStreamer.hpp>
#endif

#include <ucbhelper/contentbroker.hxx>
#include <ucbhelper/content.hxx>
#include <tools/debug.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;

namespace utl
{

SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode,
        UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron )
{
    return CreateStream( rFileName, eOpenMode, Reference < XInteractionHandler >(), pHandler, bForceSynchron );
}

SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode,
        Reference < XInteractionHandler > xInteractionHandler,
        UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron )
{
    SvStream* pStream = NULL;
    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( pBroker )
    {
        UcbLockBytesRef xLockBytes;
        if ( eOpenMode & STREAM_WRITE )
        {
            sal_Bool bTruncate = ( eOpenMode & STREAM_TRUNC );
            if ( bTruncate )
            {
                try
                {
                    // truncate is implemented with deleting the original file
                    ::ucb::Content aCnt( rFileName, Reference < XCommandEnvironment >() );
                    aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
                }

                catch ( CommandAbortedException& )
                {
                    // couldn't truncate/delete
                }
                catch ( ContentCreationException& )
                {
                }
                catch ( Exception& )
                {
                }
            }

            try
            {
                // make sure that the desired file exists before trying to open
                ::ucb::Content aContent( rFileName, Reference < XCommandEnvironment >() );
                InsertCommandArgument aInsertArg;
                aInsertArg.Data = Reference< XInputStream >();
                aInsertArg.ReplaceExisting = sal_False;
                Any aCmdArg;
                aCmdArg <<= aInsertArg;
                aContent.executeCommand( ::rtl::OUString::createFromAscii( "insert" ), aCmdArg );
            }

            // it is NOT an error when the stream already exists and no truncation was desired
            catch ( CommandAbortedException& )
            {
                // currently never an error is detected !
            }
            catch ( ContentCreationException& )
            {
            }
            catch ( Exception& )
            {
            }
        }

        try
        {
            // create LockBytes using UCB
            ::ucb::Content aContent( rFileName, Reference < XCommandEnvironment >() );
            xLockBytes = UcbLockBytes::CreateLockBytes( aContent.get(), Sequence < PropertyValue >(),
                                                eOpenMode, xInteractionHandler, pHandler );
            if ( xLockBytes.Is() )
            {
                pStream = new SvStream( xLockBytes );
                pStream->SetBufferSize( 4096 );
                pStream->SetError( xLockBytes->GetError() );
            }
        }
        catch ( CommandAbortedException& )
        {
        }
        catch ( ContentCreationException& )
        {
        }
        catch ( Exception& )
        {
        }
    }
    else
        // if no UCB is present at least conventional file io is supported
        pStream = new SvFileStream( rFileName, eOpenMode );

    return pStream;
}

SvStream* UcbStreamHelper::CreateStream( Reference < XInputStream > xStream )
{
    SvStream* pStream = NULL;
    UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream );
    if ( xLockBytes.Is() )
    {
        pStream = new SvStream( xLockBytes );
        pStream->SetBufferSize( 4096 );
        pStream->SetError( xLockBytes->GetError() );
    }

    return pStream;
};

};
<commit_msg>#89377#: OpenMode ReadWrite now handled by UCP<commit_after>/*************************************************************************
 *
 *  $RCSfile: ucbstreamhelper.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: mba $ $Date: 2001-07-16 11:57:22 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <unotools/ucblockbytes.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <comphelper/processfactory.hxx>

#ifndef _COM_SUN_STAR_UCB_COMMANDABORTEDEXCEPTION_HPP_
#include <com/sun/star/ucb/CommandAbortedException.hpp>
#endif

#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HDL_
#include <com/sun/star/ucb/XCommandEnvironment.hdl>
#endif

#ifndef _COM_SUN_STAR_UCB_INSERTCOMMANDARGUMENT_HPP_
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASTREAMER_HPP_
#include <com/sun/star/io/XActiveDataStreamer.hpp>
#endif

#include <ucbhelper/contentbroker.hxx>
#include <ucbhelper/content.hxx>
#include <tools/debug.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;

namespace utl
{

SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode,
        UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron )
{
    return CreateStream( rFileName, eOpenMode, Reference < XInteractionHandler >(), pHandler, bForceSynchron );
}

SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode,
        Reference < XInteractionHandler > xInteractionHandler,
        UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron )
{
    SvStream* pStream = NULL;
    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( pBroker )
    {
        UcbLockBytesRef xLockBytes;
        if ( eOpenMode & STREAM_WRITE )
        {
            sal_Bool bTruncate = ( eOpenMode & STREAM_TRUNC );
            if ( bTruncate )
            {
                try
                {
                    // truncate is implemented with deleting the original file
                    ::ucb::Content aCnt( rFileName, Reference < XCommandEnvironment >() );
                    aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
                }

                catch ( CommandAbortedException& )
                {
                    // couldn't truncate/delete
                }
                catch ( ContentCreationException& )
                {
                }
                catch ( Exception& )
                {
                }
            }
/*
            try
            {
                // make sure that the desired file exists before trying to open
                ::ucb::Content aContent( rFileName, Reference < XCommandEnvironment >() );
                InsertCommandArgument aInsertArg;
                aInsertArg.Data = Reference< XInputStream >();
                aInsertArg.ReplaceExisting = sal_False;
                Any aCmdArg;
                aCmdArg <<= aInsertArg;
                aContent.executeCommand( ::rtl::OUString::createFromAscii( "insert" ), aCmdArg );
            }

            // it is NOT an error when the stream already exists and no truncation was desired
            catch ( CommandAbortedException& )
            {
                // currently never an error is detected !
            }
            catch ( ContentCreationException& )
            {
            }
            catch ( Exception& )
            {
            }
 */
        }

        try
        {
            // create LockBytes using UCB
            ::ucb::Content aContent( rFileName, Reference < XCommandEnvironment >() );
            xLockBytes = UcbLockBytes::CreateLockBytes( aContent.get(), Sequence < PropertyValue >(),
                                                eOpenMode, xInteractionHandler, pHandler );
            if ( xLockBytes.Is() )
            {
                pStream = new SvStream( xLockBytes );
                pStream->SetBufferSize( 4096 );
                pStream->SetError( xLockBytes->GetError() );
            }
        }
        catch ( CommandAbortedException& )
        {
        }
        catch ( ContentCreationException& )
        {
        }
        catch ( Exception& )
        {
        }
    }
    else
        // if no UCB is present at least conventional file io is supported
        pStream = new SvFileStream( rFileName, eOpenMode );

    return pStream;
}

SvStream* UcbStreamHelper::CreateStream( Reference < XInputStream > xStream )
{
    SvStream* pStream = NULL;
    UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream );
    if ( xLockBytes.Is() )
    {
        pStream = new SvStream( xLockBytes );
        pStream->SetBufferSize( 4096 );
        pStream->SetError( xLockBytes->GetError() );
    }

    return pStream;
};

};
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009 Wang Rui
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgQt/GraphicsWindowQt>

namespace osgQt
{

GraphWidget::GraphWidget( const QGLFormat& format, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f )
: QGLWidget(format, parent, shareWidget, f)
{
    setAutoBufferSwap( false );
    setMouseTracking( true );
}

void GraphWidget::setKeyboardModifiers( QInputEvent* event )
{
    int modkey = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier);
    unsigned int mask = 0;
    if ( modkey & Qt::ShiftModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
    if ( modkey & Qt::ControlModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_CTRL;
    if ( modkey & Qt::AltModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_ALT;
    _gw->getEventQueue()->getCurrentEventState()->setModKeyMask( mask );
}

void GraphWidget::resizeEvent( QResizeEvent* event )
{
    const QSize& size = event->size();
    _gw->getEventQueue()->windowResize( 0, 0, size.width(), size.height() );
    _gw->resized( 0, 0, size.width(), size.height() );
}

void GraphWidget::keyPressEvent( QKeyEvent* event )
{
    setKeyboardModifiers( event );
    _gw->getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) *(event->text().toAscii().data()) );
}

void GraphWidget::keyReleaseEvent( QKeyEvent* event )
{
    setKeyboardModifiers( event );
    _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) *(event->text().toAscii().data()) );
}

void GraphWidget::mousePressEvent( QMouseEvent* event )
{
    int button = 0;
    switch ( event->button() )
    {
        case Qt::LeftButton: button = 1; break;
        case Qt::MidButton: button = 2; break;
        case Qt::RightButton: button = 3; break;
        case Qt::NoButton: button = 0; break;
        default: button = 0; break;
    }
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseButtonPress( event->x(), event->y(), button );
}

void GraphWidget::mouseReleaseEvent( QMouseEvent* event )
{
    int button = 0;
    switch ( event->button() )
    {
        case Qt::LeftButton: button = 1; break;
        case Qt::MidButton: button = 2; break;
        case Qt::RightButton: button = 3; break;
        case Qt::NoButton: button = 0; break;
        default: button = 0; break;
    }
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseButtonRelease( event->x(), event->y(), button );
}

void GraphWidget::mouseDoubleClickEvent( QMouseEvent* event )
{
    int button = 0;
    switch ( event->button() )
    {
        case Qt::LeftButton: button = 1; break;
        case Qt::MidButton: button = 2; break;
        case Qt::RightButton: button = 3; break;
        case Qt::NoButton: button = 0; break;
        default: button = 0; break;
    }
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseDoubleButtonPress( event->x(), event->y(), button );
}

void GraphWidget::mouseMoveEvent( QMouseEvent* event )
{
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseMotion( event->x(), event->y() );
}

void GraphWidget::wheelEvent( QWheelEvent* event )
{
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseScroll(
        event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN );
}

GraphicsWindowQt::GraphicsWindowQt( osg::GraphicsContext::Traits* traits )
:   _widget(0),
    _initialized(false),
    _realized(false)
{
    _traits = traits;
    _initialized = init();

    if ( valid() )
    {
        setState( new osg::State );
        getState()->setGraphicsContext(this);

        if ( _traits.valid() && _traits->sharedContext )
        {
            getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
            incrementContextIDUsageCount( getState()->getContextID() );
        }
        else
        {
            getState()->setContextID( osg::GraphicsContext::createNewContextID() );
        }
    }
}

GraphicsWindowQt::~GraphicsWindowQt()
{
    close();
}

bool GraphicsWindowQt::init()
{
    QGLFormat format( QGLFormat::defaultFormat() );
    format.setAlphaBufferSize( _traits->alpha );
    format.setRedBufferSize( _traits->red );
    format.setGreenBufferSize( _traits->green );
    format.setBlueBufferSize( _traits->blue );
    format.setDepthBufferSize( _traits->depth );
    format.setStencilBufferSize( _traits->stencil );
    format.setSampleBuffers( _traits->sampleBuffers );
    format.setSamples( _traits->samples );

    format.setAlpha( _traits->alpha>0 );
    format.setDepth( _traits->depth>0 );
    format.setStencil( _traits->stencil>0 );
    format.setDoubleBuffer( _traits->doubleBuffer );
    format.setSwapInterval( _traits->vsync ? 1 : 0 );
    format.setStereo( _traits->quadBufferStereo ? 1 : 0 );

    WindowData* windowData = _traits.get() ? dynamic_cast<WindowData*>(_traits->inheritedWindowData.get()) : 0;
    _widget = windowData ? windowData->_widget : 0;
    if ( !_widget )
    {
        GraphicsWindowQt* sharedContextQt = dynamic_cast<GraphicsWindowQt*>(_traits->sharedContext);
        QGLWidget* shareWidget = sharedContextQt ? sharedContextQt->getGraphWidget() : 0;

        Qt::WindowFlags flags = Qt::Window|Qt::CustomizeWindowHint;//|Qt::WindowStaysOnTopHint;
        if ( _traits->windowDecoration )
            flags |= Qt::WindowTitleHint|Qt::WindowMinMaxButtonsHint|Qt::WindowSystemMenuHint;

        _widget = new GraphWidget( format, 0, shareWidget, flags );
    }

    _widget->setWindowTitle( _traits->windowName.c_str() );
    _widget->move( _traits->x, _traits->y );
    if ( !_traits->supportsResize ) _widget->setFixedSize( _traits->width, _traits->height );
    else _widget->resize( _traits->width, _traits->height );

    _widget->setFocusPolicy( Qt::WheelFocus );
    _widget->setGraphicsWindow( this );
    useCursor( _traits->useCursor );
    return true;
}

bool GraphicsWindowQt::setWindowRectangleImplementation( int x, int y, int width, int height )
{
    if ( _widget ) _widget->setGeometry( x, y, width, height );
    return _widget!=NULL;
}

void GraphicsWindowQt::getWindowRectangle( int& x, int& y, int& width, int& height )
{
    if ( _widget )
    {
        const QRect& geom = _widget->geometry();
        x = geom.x();
        y = geom.y();
        width = geom.width();
        height = geom.height();
    }
}

bool GraphicsWindowQt::setWindowDecorationImplementation( bool windowDecoration )
{
    Qt::WindowFlags flags = Qt::Window|Qt::CustomizeWindowHint;//|Qt::WindowStaysOnTopHint;
    if ( windowDecoration )
        flags |= Qt::WindowTitleHint|Qt::WindowMinMaxButtonsHint|Qt::WindowSystemMenuHint;
    _traits->windowDecoration = windowDecoration;

    // FIXME: Calling setWindowFlags or reparent widget will recreate the window handle,
    // which makes QGLContext no longer work...How to deal with that?
    //if ( _widget ) _widget->setWindowFlags( flags );
    return false;
}

bool GraphicsWindowQt::getWindowDecoration() const
{
    return _traits->windowDecoration;
}

void GraphicsWindowQt::grabFocus()
{
    if ( _widget )
        _widget->setFocus( Qt::ActiveWindowFocusReason );
}

void GraphicsWindowQt::grabFocusIfPointerInWindow()
{
    if ( _widget->underMouse() )
        _widget->setFocus( Qt::ActiveWindowFocusReason );
}

void GraphicsWindowQt::raiseWindow()
{
    if ( _widget )
        _widget->raise();
}

void GraphicsWindowQt::setWindowName( const std::string& name )
{
    if ( _widget )
        _widget->setWindowTitle( name.c_str() );
}

std::string GraphicsWindowQt::getWindowName()
{
    return _widget ? _widget->windowTitle().toStdString() : "";
}

void GraphicsWindowQt::useCursor( bool cursorOn )
{
    if ( _widget )
    {
        _traits->useCursor = cursorOn;
        if ( !cursorOn ) _widget->setCursor( Qt::BlankCursor );
        else _widget->setCursor( _currentCursor );
    }
}

void GraphicsWindowQt::setCursor( MouseCursor cursor )
{
    if ( cursor==InheritCursor && _widget )
    {
        _widget->unsetCursor();
    }

    switch ( cursor )
    {
    case NoCursor: _currentCursor = Qt::BlankCursor; break;
    case RightArrowCursor: case LeftArrowCursor: _currentCursor = Qt::ArrowCursor; break;
    case InfoCursor: _currentCursor = Qt::SizeAllCursor; break;
    case DestroyCursor: _currentCursor = Qt::ForbiddenCursor; break;
    case HelpCursor: _currentCursor = Qt::WhatsThisCursor; break;
    case CycleCursor: _currentCursor = Qt::ForbiddenCursor; break;
    case SprayCursor: _currentCursor = Qt::SizeAllCursor; break;
    case WaitCursor: _currentCursor = Qt::WaitCursor; break;
    case TextCursor: _currentCursor = Qt::IBeamCursor; break;
    case CrosshairCursor: _currentCursor = Qt::CrossCursor; break;
    case HandCursor: _currentCursor = Qt::OpenHandCursor; break;
    case UpDownCursor: _currentCursor = Qt::SizeVerCursor; break;
    case LeftRightCursor: _currentCursor = Qt::SizeHorCursor; break;
    case TopSideCursor: case BottomSideCursor: _currentCursor = Qt::UpArrowCursor; break;
    case LeftSideCursor: case RightSideCursor: _currentCursor = Qt::SizeHorCursor; break;
    case TopLeftCorner: _currentCursor = Qt::SizeBDiagCursor; break;
    case TopRightCorner: _currentCursor = Qt::SizeFDiagCursor; break;
    case BottomRightCorner: _currentCursor = Qt::SizeBDiagCursor; break;
    case BottomLeftCorner: _currentCursor = Qt::SizeFDiagCursor; break;
    default: break;
    };
    if ( _widget ) _widget->setCursor( _currentCursor );
}

bool GraphicsWindowQt::valid() const
{
    return _widget && _widget->isValid();
}

bool GraphicsWindowQt::realizeImplementation()
{
    if ( !_initialized )
        _initialized = init();

    // A makeCurrent()/doneCurrent() seems to be required for
    // realizing the context(?) before starting drawing
    _widget->makeCurrent();
    _widget->doneCurrent();

    _realized = true;
    return true;
}

bool GraphicsWindowQt::isRealizedImplementation() const
{
    return _realized;
}

void GraphicsWindowQt::closeImplementation()
{
    if ( _widget )
        _widget->close();
}

bool GraphicsWindowQt::makeCurrentImplementation()
{
    _widget->makeCurrent();
    return true;
}

bool GraphicsWindowQt::releaseContextImplementation()
{
    _widget->doneCurrent();
    return true;
}

void GraphicsWindowQt::swapBuffersImplementation()
{
    _widget->swapBuffers();
}

void GraphicsWindowQt::requestWarpPointer( float x, float y )
{
    if ( _widget )
        QCursor::setPos( _widget->mapToGlobal(QPoint((int)x,(int)y)) );
}

}
<commit_msg>From Benjamin Wasty and David Guthrie, "currently, non-alpha-numeric keys are not recognized (except as modifiers) in osgQt, so I added the mapping code from my Qt integration to GraphicsWindowQt (which is based on Delta3D code from David Guthrie - he gave me permission to submit it under OSGPL)."<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009 Wang Rui
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgQt/GraphicsWindowQt>

namespace osgQt
{

class QtKeyboardMap
{

public:
    QtKeyboardMap()
    {
        mKeyMap[Qt::Key_Escape     ] = osgGA::GUIEventAdapter::KEY_Escape;
        mKeyMap[Qt::Key_Delete   ] = osgGA::GUIEventAdapter::KEY_Delete;
        mKeyMap[Qt::Key_Home       ] = osgGA::GUIEventAdapter::KEY_Home;
        mKeyMap[Qt::Key_Enter      ] = osgGA::GUIEventAdapter::KEY_KP_Enter;
        mKeyMap[Qt::Key_End        ] = osgGA::GUIEventAdapter::KEY_End;
        mKeyMap[Qt::Key_Return     ] = osgGA::GUIEventAdapter::KEY_Return;
        mKeyMap[Qt::Key_PageUp     ] = osgGA::GUIEventAdapter::KEY_Page_Up;
        mKeyMap[Qt::Key_PageDown   ] = osgGA::GUIEventAdapter::KEY_Page_Down;
        mKeyMap[Qt::Key_Left       ] = osgGA::GUIEventAdapter::KEY_Left;
        mKeyMap[Qt::Key_Right      ] = osgGA::GUIEventAdapter::KEY_Right;
        mKeyMap[Qt::Key_Up         ] = osgGA::GUIEventAdapter::KEY_Up;
        mKeyMap[Qt::Key_Down       ] = osgGA::GUIEventAdapter::KEY_Down;
        mKeyMap[Qt::Key_Backspace  ] = osgGA::GUIEventAdapter::KEY_BackSpace;
        mKeyMap[Qt::Key_Tab        ] = osgGA::GUIEventAdapter::KEY_Tab;
        mKeyMap[Qt::Key_Space      ] = osgGA::GUIEventAdapter::KEY_Space;
        mKeyMap[Qt::Key_Delete     ] = osgGA::GUIEventAdapter::KEY_Delete;
        mKeyMap[Qt::Key_Alt      ] = osgGA::GUIEventAdapter::KEY_Alt_L;
        mKeyMap[Qt::Key_Shift    ] = osgGA::GUIEventAdapter::KEY_Shift_L;
        mKeyMap[Qt::Key_Control  ] = osgGA::GUIEventAdapter::KEY_Control_L;
        mKeyMap[Qt::Key_Meta     ] = osgGA::GUIEventAdapter::KEY_Meta_L;

        mKeyMap[Qt::Key_F1             ] = osgGA::GUIEventAdapter::KEY_F1;
        mKeyMap[Qt::Key_F2             ] = osgGA::GUIEventAdapter::KEY_F2;
        mKeyMap[Qt::Key_F3             ] = osgGA::GUIEventAdapter::KEY_F3;
        mKeyMap[Qt::Key_F4             ] = osgGA::GUIEventAdapter::KEY_F4;
        mKeyMap[Qt::Key_F5             ] = osgGA::GUIEventAdapter::KEY_F5;
        mKeyMap[Qt::Key_F6             ] = osgGA::GUIEventAdapter::KEY_F6;
        mKeyMap[Qt::Key_F7             ] = osgGA::GUIEventAdapter::KEY_F7;
        mKeyMap[Qt::Key_F8             ] = osgGA::GUIEventAdapter::KEY_F8;
        mKeyMap[Qt::Key_F9             ] = osgGA::GUIEventAdapter::KEY_F9;
        mKeyMap[Qt::Key_F10            ] = osgGA::GUIEventAdapter::KEY_F10;
        mKeyMap[Qt::Key_F11            ] = osgGA::GUIEventAdapter::KEY_F11;
        mKeyMap[Qt::Key_F12            ] = osgGA::GUIEventAdapter::KEY_F12;
        mKeyMap[Qt::Key_F13            ] = osgGA::GUIEventAdapter::KEY_F13;
        mKeyMap[Qt::Key_F14            ] = osgGA::GUIEventAdapter::KEY_F14;
        mKeyMap[Qt::Key_F15            ] = osgGA::GUIEventAdapter::KEY_F15;
        mKeyMap[Qt::Key_F16            ] = osgGA::GUIEventAdapter::KEY_F16;
        mKeyMap[Qt::Key_F17            ] = osgGA::GUIEventAdapter::KEY_F17;
        mKeyMap[Qt::Key_F18            ] = osgGA::GUIEventAdapter::KEY_F18;
        mKeyMap[Qt::Key_F19            ] = osgGA::GUIEventAdapter::KEY_F19;
        mKeyMap[Qt::Key_F20            ] = osgGA::GUIEventAdapter::KEY_F20;

        mKeyMap[Qt::Key_hyphen         ] = '-';
        mKeyMap[Qt::Key_Equal         ] = '=';

        mKeyMap[Qt::Key_division      ] = osgGA::GUIEventAdapter::KEY_KP_Divide;
        mKeyMap[Qt::Key_multiply      ] = osgGA::GUIEventAdapter::KEY_KP_Multiply;
        mKeyMap[Qt::Key_Minus         ] = '-';
        mKeyMap[Qt::Key_Plus          ] = '+';
        //mKeyMap[Qt::Key_H              ] = osgGA::GUIEventAdapter::KEY_KP_Home;
        //mKeyMap[Qt::Key_                    ] = osgGA::GUIEventAdapter::KEY_KP_Up;
        //mKeyMap[92                    ] = osgGA::GUIEventAdapter::KEY_KP_Page_Up;
        //mKeyMap[86                    ] = osgGA::GUIEventAdapter::KEY_KP_Left;
        //mKeyMap[87                    ] = osgGA::GUIEventAdapter::KEY_KP_Begin;
        //mKeyMap[88                    ] = osgGA::GUIEventAdapter::KEY_KP_Right;
        //mKeyMap[83                    ] = osgGA::GUIEventAdapter::KEY_KP_End;
        //mKeyMap[84                    ] = osgGA::GUIEventAdapter::KEY_KP_Down;
        //mKeyMap[85                    ] = osgGA::GUIEventAdapter::KEY_KP_Page_Down;
        mKeyMap[Qt::Key_Insert        ] = osgGA::GUIEventAdapter::KEY_KP_Insert;
        //mKeyMap[Qt::Key_Delete        ] = osgGA::GUIEventAdapter::KEY_KP_Delete;
    }

    ~QtKeyboardMap()
    {
    }

    int remapKey(QKeyEvent* event)
    {
        KeyMap::iterator itr = mKeyMap.find(event->key());
        if (itr == mKeyMap.end())
        {
            return int(*(event->text().toAscii().data()));
        }
        else
            return itr->second;
    }

    private:
    typedef std::map<unsigned int, int> KeyMap;
    KeyMap mKeyMap;
};

static QtKeyboardMap s_QtKeyboardMap;

GraphWidget::GraphWidget( const QGLFormat& format, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f )
: QGLWidget(format, parent, shareWidget, f)
{
    setAutoBufferSwap( false );
    setMouseTracking( true );
}

void GraphWidget::setKeyboardModifiers( QInputEvent* event )
{
    int modkey = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier);
    unsigned int mask = 0;
    if ( modkey & Qt::ShiftModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
    if ( modkey & Qt::ControlModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_CTRL;
    if ( modkey & Qt::AltModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_ALT;
    _gw->getEventQueue()->getCurrentEventState()->setModKeyMask( mask );
}

void GraphWidget::resizeEvent( QResizeEvent* event )
{
    const QSize& size = event->size();
    _gw->getEventQueue()->windowResize( 0, 0, size.width(), size.height() );
    _gw->resized( 0, 0, size.width(), size.height() );
}

void GraphWidget::keyPressEvent( QKeyEvent* event )
{
    setKeyboardModifiers( event );
    int value = s_QtKeyboardMap.remapKey(event);
    _gw->getEventQueue()->keyPress(value);
}

void GraphWidget::keyReleaseEvent( QKeyEvent* event )
{
    setKeyboardModifiers( event );
    int value = s_QtKeyboardMap.remapKey(event);
    _gw->getEventQueue()->keyRelease(value);
}

void GraphWidget::mousePressEvent( QMouseEvent* event )
{
    int button = 0;
    switch ( event->button() )
    {
        case Qt::LeftButton: button = 1; break;
        case Qt::MidButton: button = 2; break;
        case Qt::RightButton: button = 3; break;
        case Qt::NoButton: button = 0; break;
        default: button = 0; break;
    }
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseButtonPress( event->x(), event->y(), button );
}

void GraphWidget::mouseReleaseEvent( QMouseEvent* event )
{
    int button = 0;
    switch ( event->button() )
    {
        case Qt::LeftButton: button = 1; break;
        case Qt::MidButton: button = 2; break;
        case Qt::RightButton: button = 3; break;
        case Qt::NoButton: button = 0; break;
        default: button = 0; break;
    }
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseButtonRelease( event->x(), event->y(), button );
}

void GraphWidget::mouseDoubleClickEvent( QMouseEvent* event )
{
    int button = 0;
    switch ( event->button() )
    {
        case Qt::LeftButton: button = 1; break;
        case Qt::MidButton: button = 2; break;
        case Qt::RightButton: button = 3; break;
        case Qt::NoButton: button = 0; break;
        default: button = 0; break;
    }
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseDoubleButtonPress( event->x(), event->y(), button );
}

void GraphWidget::mouseMoveEvent( QMouseEvent* event )
{
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseMotion( event->x(), event->y() );
}

void GraphWidget::wheelEvent( QWheelEvent* event )
{
    setKeyboardModifiers( event );
    _gw->getEventQueue()->mouseScroll(
        event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN );
}

GraphicsWindowQt::GraphicsWindowQt( osg::GraphicsContext::Traits* traits )
:   _widget(0),
    _initialized(false),
    _realized(false)
{
    _traits = traits;
    _initialized = init();

    if ( valid() )
    {
        setState( new osg::State );
        getState()->setGraphicsContext(this);

        if ( _traits.valid() && _traits->sharedContext )
        {
            getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
            incrementContextIDUsageCount( getState()->getContextID() );
        }
        else
        {
            getState()->setContextID( osg::GraphicsContext::createNewContextID() );
        }
    }
}

GraphicsWindowQt::~GraphicsWindowQt()
{
    close();
}

bool GraphicsWindowQt::init()
{
    QGLFormat format( QGLFormat::defaultFormat() );
    format.setAlphaBufferSize( _traits->alpha );
    format.setRedBufferSize( _traits->red );
    format.setGreenBufferSize( _traits->green );
    format.setBlueBufferSize( _traits->blue );
    format.setDepthBufferSize( _traits->depth );
    format.setStencilBufferSize( _traits->stencil );
    format.setSampleBuffers( _traits->sampleBuffers );
    format.setSamples( _traits->samples );

    format.setAlpha( _traits->alpha>0 );
    format.setDepth( _traits->depth>0 );
    format.setStencil( _traits->stencil>0 );
    format.setDoubleBuffer( _traits->doubleBuffer );
    format.setSwapInterval( _traits->vsync ? 1 : 0 );
    format.setStereo( _traits->quadBufferStereo ? 1 : 0 );

    WindowData* windowData = _traits.get() ? dynamic_cast<WindowData*>(_traits->inheritedWindowData.get()) : 0;
    _widget = windowData ? windowData->_widget : 0;
    if ( !_widget )
    {
        GraphicsWindowQt* sharedContextQt = dynamic_cast<GraphicsWindowQt*>(_traits->sharedContext);
        QGLWidget* shareWidget = sharedContextQt ? sharedContextQt->getGraphWidget() : 0;

        Qt::WindowFlags flags = Qt::Window|Qt::CustomizeWindowHint;//|Qt::WindowStaysOnTopHint;
        if ( _traits->windowDecoration )
            flags |= Qt::WindowTitleHint|Qt::WindowMinMaxButtonsHint|Qt::WindowSystemMenuHint;

        _widget = new GraphWidget( format, 0, shareWidget, flags );
    }

    _widget->setWindowTitle( _traits->windowName.c_str() );
    _widget->move( _traits->x, _traits->y );
    if ( !_traits->supportsResize ) _widget->setFixedSize( _traits->width, _traits->height );
    else _widget->resize( _traits->width, _traits->height );

    _widget->setFocusPolicy( Qt::WheelFocus );
    _widget->setGraphicsWindow( this );
    useCursor( _traits->useCursor );
    return true;
}

bool GraphicsWindowQt::setWindowRectangleImplementation( int x, int y, int width, int height )
{
    if ( _widget ) _widget->setGeometry( x, y, width, height );
    return _widget!=NULL;
}

void GraphicsWindowQt::getWindowRectangle( int& x, int& y, int& width, int& height )
{
    if ( _widget )
    {
        const QRect& geom = _widget->geometry();
        x = geom.x();
        y = geom.y();
        width = geom.width();
        height = geom.height();
    }
}

bool GraphicsWindowQt::setWindowDecorationImplementation( bool windowDecoration )
{
    Qt::WindowFlags flags = Qt::Window|Qt::CustomizeWindowHint;//|Qt::WindowStaysOnTopHint;
    if ( windowDecoration )
        flags |= Qt::WindowTitleHint|Qt::WindowMinMaxButtonsHint|Qt::WindowSystemMenuHint;
    _traits->windowDecoration = windowDecoration;

    // FIXME: Calling setWindowFlags or reparent widget will recreate the window handle,
    // which makes QGLContext no longer work...How to deal with that?
    //if ( _widget ) _widget->setWindowFlags( flags );
    return false;
}

bool GraphicsWindowQt::getWindowDecoration() const
{
    return _traits->windowDecoration;
}

void GraphicsWindowQt::grabFocus()
{
    if ( _widget )
        _widget->setFocus( Qt::ActiveWindowFocusReason );
}

void GraphicsWindowQt::grabFocusIfPointerInWindow()
{
    if ( _widget->underMouse() )
        _widget->setFocus( Qt::ActiveWindowFocusReason );
}

void GraphicsWindowQt::raiseWindow()
{
    if ( _widget )
        _widget->raise();
}

void GraphicsWindowQt::setWindowName( const std::string& name )
{
    if ( _widget )
        _widget->setWindowTitle( name.c_str() );
}

std::string GraphicsWindowQt::getWindowName()
{
    return _widget ? _widget->windowTitle().toStdString() : "";
}

void GraphicsWindowQt::useCursor( bool cursorOn )
{
    if ( _widget )
    {
        _traits->useCursor = cursorOn;
        if ( !cursorOn ) _widget->setCursor( Qt::BlankCursor );
        else _widget->setCursor( _currentCursor );
    }
}

void GraphicsWindowQt::setCursor( MouseCursor cursor )
{
    if ( cursor==InheritCursor && _widget )
    {
        _widget->unsetCursor();
    }

    switch ( cursor )
    {
    case NoCursor: _currentCursor = Qt::BlankCursor; break;
    case RightArrowCursor: case LeftArrowCursor: _currentCursor = Qt::ArrowCursor; break;
    case InfoCursor: _currentCursor = Qt::SizeAllCursor; break;
    case DestroyCursor: _currentCursor = Qt::ForbiddenCursor; break;
    case HelpCursor: _currentCursor = Qt::WhatsThisCursor; break;
    case CycleCursor: _currentCursor = Qt::ForbiddenCursor; break;
    case SprayCursor: _currentCursor = Qt::SizeAllCursor; break;
    case WaitCursor: _currentCursor = Qt::WaitCursor; break;
    case TextCursor: _currentCursor = Qt::IBeamCursor; break;
    case CrosshairCursor: _currentCursor = Qt::CrossCursor; break;
    case HandCursor: _currentCursor = Qt::OpenHandCursor; break;
    case UpDownCursor: _currentCursor = Qt::SizeVerCursor; break;
    case LeftRightCursor: _currentCursor = Qt::SizeHorCursor; break;
    case TopSideCursor: case BottomSideCursor: _currentCursor = Qt::UpArrowCursor; break;
    case LeftSideCursor: case RightSideCursor: _currentCursor = Qt::SizeHorCursor; break;
    case TopLeftCorner: _currentCursor = Qt::SizeBDiagCursor; break;
    case TopRightCorner: _currentCursor = Qt::SizeFDiagCursor; break;
    case BottomRightCorner: _currentCursor = Qt::SizeBDiagCursor; break;
    case BottomLeftCorner: _currentCursor = Qt::SizeFDiagCursor; break;
    default: break;
    };
    if ( _widget ) _widget->setCursor( _currentCursor );
}

bool GraphicsWindowQt::valid() const
{
    return _widget && _widget->isValid();
}

bool GraphicsWindowQt::realizeImplementation()
{
    if ( !_initialized )
        _initialized = init();

    // A makeCurrent()/doneCurrent() seems to be required for
    // realizing the context(?) before starting drawing
    _widget->makeCurrent();
    _widget->doneCurrent();

    _realized = true;
    return true;
}

bool GraphicsWindowQt::isRealizedImplementation() const
{
    return _realized;
}

void GraphicsWindowQt::closeImplementation()
{
    if ( _widget )
        _widget->close();
}

bool GraphicsWindowQt::makeCurrentImplementation()
{
    _widget->makeCurrent();
    return true;
}

bool GraphicsWindowQt::releaseContextImplementation()
{
    _widget->doneCurrent();
    return true;
}

void GraphicsWindowQt::swapBuffersImplementation()
{
    _widget->swapBuffers();
}

void GraphicsWindowQt::requestWarpPointer( float x, float y )
{
    if ( _widget )
        QCursor::setPos( _widget->mapToGlobal(QPoint((int)x,(int)y)) );
}

}
<|endoftext|>


<commit_before>//===--- CallerAnalysis.cpp - Determine callsites to a function  ----------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SILOptimizer/Analysis/CallerAnalysis.h"

#include "swift/Basic/Fallthrough.h"
#include "swift/SIL/SILModule.h"
#include "swift/SILOptimizer/Utils/Local.h"

using namespace swift;

static SILFunction *getCallee(FullApplySite &Apply) {
  SILValue Callee = Apply.getCallee();
  //  Strip ThinToThickFunctionInst.
  if (auto TTTF = dyn_cast<ThinToThickFunctionInst>(Callee)) {
    Callee = TTTF->getOperand();
  }

  // Find the target function.
  auto *FRI = dyn_cast<FunctionRefInst>(Callee);
  if (!FRI)
    return nullptr;

  return FRI->getReferencedFunction();
}

void CallerAnalysis::processFunctionCallSites(SILFunction *F) {
  // Scan the whole module and search Apply sites.
  for (auto &BB : *F) {
    for (auto &II : BB) {
      if (auto Apply = FullApplySite::isa(&II)) {
        SILFunction *CalleeFn = getCallee(Apply);
        if (!CalleeFn)
          continue;
        // Update the callee information for this fucntion.
        CallerAnalysisFunctionInfo &CallerInfo
                             = CallInfo.FindAndConstruct(F).second;
        CallerInfo.Callees.push_back(CalleeFn);

        // Update the callsite information for the callee.
        CallerAnalysisFunctionInfo &CalleeInfo
                           = CallInfo.FindAndConstruct(CalleeFn).second;
        CalleeInfo.CallSites[F].push_back(Apply);
      }
    }
  }
}

void CallerAnalysis::invalidateExistingCalleeRelation(SILFunction *F) {
  CallerAnalysisFunctionInfo &CallerInfo = CallInfo.FindAndConstruct(F).second;
  for (auto Callee : CallerInfo.Callees) {
    CallerAnalysisFunctionInfo &CalleeInfo = CallInfo.find(Callee)->second;
    CalleeInfo.CallSites[F].clear();
  }
}

//===----------------------------------------------------------------------===//
//                              Main Entry Point
//===----------------------------------------------------------------------===//
SILAnalysis *swift::createCallerAnalysis(SILModule *M) {
  return new CallerAnalysis(M);
}
<commit_msg>[gardening] Fix recently introduced typo: "fucntion" → "function"<commit_after>//===--- CallerAnalysis.cpp - Determine callsites to a function  ----------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SILOptimizer/Analysis/CallerAnalysis.h"

#include "swift/Basic/Fallthrough.h"
#include "swift/SIL/SILModule.h"
#include "swift/SILOptimizer/Utils/Local.h"

using namespace swift;

static SILFunction *getCallee(FullApplySite &Apply) {
  SILValue Callee = Apply.getCallee();
  //  Strip ThinToThickFunctionInst.
  if (auto TTTF = dyn_cast<ThinToThickFunctionInst>(Callee)) {
    Callee = TTTF->getOperand();
  }

  // Find the target function.
  auto *FRI = dyn_cast<FunctionRefInst>(Callee);
  if (!FRI)
    return nullptr;

  return FRI->getReferencedFunction();
}

void CallerAnalysis::processFunctionCallSites(SILFunction *F) {
  // Scan the whole module and search Apply sites.
  for (auto &BB : *F) {
    for (auto &II : BB) {
      if (auto Apply = FullApplySite::isa(&II)) {
        SILFunction *CalleeFn = getCallee(Apply);
        if (!CalleeFn)
          continue;
        // Update the callee information for this function.
        CallerAnalysisFunctionInfo &CallerInfo
                             = CallInfo.FindAndConstruct(F).second;
        CallerInfo.Callees.push_back(CalleeFn);

        // Update the callsite information for the callee.
        CallerAnalysisFunctionInfo &CalleeInfo
                           = CallInfo.FindAndConstruct(CalleeFn).second;
        CalleeInfo.CallSites[F].push_back(Apply);
      }
    }
  }
}

void CallerAnalysis::invalidateExistingCalleeRelation(SILFunction *F) {
  CallerAnalysisFunctionInfo &CallerInfo = CallInfo.FindAndConstruct(F).second;
  for (auto Callee : CallerInfo.Callees) {
    CallerAnalysisFunctionInfo &CalleeInfo = CallInfo.find(Callee)->second;
    CalleeInfo.CallSites[F].clear();
  }
}

//===----------------------------------------------------------------------===//
//                              Main Entry Point
//===----------------------------------------------------------------------===//
SILAnalysis *swift::createCallerAnalysis(SILModule *M) {
  return new CallerAnalysis(M);
}
<|endoftext|>