<commit_before>
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Linker/Linker.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Transforms/Scalar.h"

#include <memory>
#include <string>

#include "DynamicCallCounter.h"
#include "StaticCallCounter.h"

#include "config.h"

using namespace llvm;
using std::string;
using std::unique_ptr;
using std::vector;
using llvm::sys::ExecuteAndWait;
using llvm::sys::findProgramByName;
using llvm::legacy::PassManager;

enum class AnalysisType {
  STATIC,
  DYNAMIC,
};

static cl::OptionCategory callCounterCategory{"call counter options"};

static cl::opt<string> inPath{cl::Positional,
                              cl::desc{"<Module to analyze>"},
                              cl::value_desc{"bitcode filename"},
                              cl::init(""),
                              cl::Required,
                              cl::cat{callCounterCategory}};

static cl::opt<AnalysisType> analysisType{
    cl::desc{"Select analyis type:"},
    cl::values(clEnumValN(AnalysisType::STATIC,
                          "static",
                          "Count static direct calls."),
               clEnumValN(AnalysisType::DYNAMIC,
                          "dynamic",
                          "Count dynamic direct calls.")
               ),
    cl::Required,
    cl::cat{callCounterCategory}};

static cl::opt<string> outFile{"o",
                               cl::desc{"Filename of the instrumented program"},
                               cl::value_desc{"filename"},
                               cl::init(""),
                               cl::cat{callCounterCategory}};

static cl::opt<char> optLevel{
    "O",
    cl::desc{"Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O2')"},
    cl::Prefix,
    cl::ZeroOrMore,
    cl::init('2'),
    cl::cat{callCounterCategory}};

static cl::list<string> libPaths{"L",
                                 cl::Prefix,
                                 cl::desc{"Specify a library search path"},
                                 cl::value_desc{"directory"},
                                 cl::cat{callCounterCategory}};

static cl::list<string> libraries{"l",
                                  cl::Prefix,
                                  cl::desc{"Specify libraries to link against"},
                                  cl::value_desc{"library prefix"},
                                  cl::cat{callCounterCategory}};

static void
compile(Module& m, StringRef outputPath) {
  string err;

  Triple triple        = Triple(m.getTargetTriple());
  Target const* target = TargetRegistry::lookupTarget(MArch, triple, err);
  if (!target) {
    report_fatal_error("Unable to find target:\n " + err);
  }

  CodeGenOpt::Level level = CodeGenOpt::Default;
  switch (optLevel) {
    default:
      report_fatal_error("Invalid optimization level.\n");
    // No fall through
    case '0': level = CodeGenOpt::None; break;
    case '1': level = CodeGenOpt::Less; break;
    case '2': level = CodeGenOpt::Default; break;
    case '3': level = CodeGenOpt::Aggressive; break;
  }

  string FeaturesStr;
  TargetOptions options = InitTargetOptionsFromCodeGenFlags();
  unique_ptr<TargetMachine> machine(
      target->createTargetMachine(triple.getTriple(),
                                  MCPU,
                                  FeaturesStr,
                                  options,
                                  getRelocModel(),
                                  CMModel,
                                  level));
  assert(machine.get() && "Could not allocate target machine!");

  if (FloatABIForCalls != FloatABI::Default) {
    options.FloatABIType = FloatABIForCalls;
  }

  std::error_code errc;
  auto out =
      std::make_unique<tool_output_file>(outputPath, errc, sys::fs::F_None);
  if (!out) {
    report_fatal_error("Unable to create file:\n " + errc.message());
  }

  // Build up all of the passes that we want to do to the module.
  legacy::PassManager pm;

  // Add target specific info and transforms
  TargetLibraryInfoImpl tlii(triple);
  pm.add(new TargetLibraryInfoWrapperPass(tlii));

  m.setDataLayout(machine->createDataLayout());

  {  // Bound this scope
    raw_pwrite_stream* os(&out->os());

    FileType = TargetMachine::CGFT_ObjectFile;
    std::unique_ptr<buffer_ostream> bos;
    if (!out->os().supportsSeeking()) {
      bos = std::make_unique<buffer_ostream>(*os);
      os  = bos.get();
    }

    // Ask the target to add backend passes as necessary.
    if (machine->addPassesToEmitFile(pm, *os, FileType)) {
      report_fatal_error("target does not support generation "
                         "of this file type!\n");
    }

    // Before executing passes, print the final values of the LLVM options.
    cl::PrintOptionValues();

    pm.run(m);
  }

  // Keep the output binary if we've been successful to this point.
  out->keep();
}

static void
link(StringRef objectFile, StringRef outputFile) {
  auto clang = findProgramByName("clang++");
  string opt("-O");
  opt += optLevel;

  if (!clang) {
    report_fatal_error("Unable to find clang.");
  }
  vector<string> args{clang.get(), opt, "-o", outputFile, objectFile};

  for (auto& libPath : libPaths) {
    args.push_back("-L" + libPath);
  }

  for (auto& library : libraries) {
    args.push_back("-l" + library);
  }

  vector<char const*> charArgs;
  for (auto& arg : args) {
    charArgs.push_back(arg.c_str());
  }
  charArgs.push_back(nullptr);

  for (auto& arg : args) {
    outs() << arg.c_str() << " ";
  }
  outs() << "\n";

  string err;
  if (-1 == ExecuteAndWait(
                clang.get(), &charArgs[0], nullptr, nullptr, 0, 0, &err)) {
    report_fatal_error("Unable to link output file.");
  }
}

static void
generateBinary(Module& m, StringRef outputFilename) {
  // Compiling to native should allow things to keep working even when the
  // version of clang on the system and the version of LLVM used to compile
  // the tool don't quite match up.
  string objectFile = outputFilename.str() + ".o";
  compile(m, objectFile);
  link(objectFile, outputFilename);
}

static void
saveModule(Module const& m, StringRef filename) {
  std::error_code errc;
  raw_fd_ostream out(filename.data(), errc, sys::fs::F_None);

  if (errc) {
    report_fatal_error("error saving llvm module to '" + filename + "': \n"
                       + errc.message());
  }
  WriteBitcodeToFile(&m, out);
}

static void
prepareLinkingPaths(SmallString<32> invocationPath) {
  // First search the directory of the binary for the library, in case it is
  // all bundled together.
  sys::path::remove_filename(invocationPath);
  if (!invocationPath.empty()) {
    libPaths.push_back(invocationPath.str());
  }
// If the builder doesn't plan on installing it, we still need to get to the
// runtime library somehow, so just build in the path to the temporary one.
#ifdef CMAKE_INSTALL_PREFIX
  libPaths.push_back(CMAKE_INSTALL_PREFIX "/lib");
#elif defined(CMAKE_TEMP_LIBRARY_PATH)
  libPaths.push_back(CMAKE_TEMP_LIBRARY_PATH);
#elif defined(TEMP_LIBRARY_PATH)
  // This is a bit of a hack
  libPaths.push_back(TEMP_LIBRARY_PATH "/Debug+Asserts/lib/");
  libPaths.push_back(TEMP_LIBRARY_PATH "/Release+Asserts/lib/");
  libPaths.push_back(TEMP_LIBRARY_PATH "/Debug/lib/");
  libPaths.push_back(TEMP_LIBRARY_PATH "/Release/lib/");
#endif
  libraries.push_back(RUNTIME_LIB);
  libraries.push_back("rt");
}

static void
instrumentForDynamicCount(Module& m) {
  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();
  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

  if (outFile.getValue() == "") {
    errs() << "-o command line option must be specified.\n";
    exit(-1);
  }

  // Build up all of the passes that we want to run on the module.
  legacy::PassManager pm;
  pm.add(new callcounter::DynamicCallCounter());
  pm.add(createVerifierPass());
  pm.run(m);

  generateBinary(m, outFile);
  saveModule(m, outFile + ".callcounter.bc");
}

struct StaticCountPrinter : public ModulePass {
  static char ID;
  raw_ostream& out;

  explicit StaticCountPrinter(raw_ostream& out) : ModulePass(ID), out(out) {}

  bool
  runOnModule(Module& m) override {
    getAnalysis<callcounter::StaticCallCounter>().print(out, &m);
    return false;
  }

  void
  getAnalysisUsage(AnalysisUsage& au) const override {
    au.addRequired<callcounter::StaticCallCounter>();
    au.setPreservesAll();
  }
};

char StaticCountPrinter::ID = 0;

static void
countStaticCalls(Module& m) {
  // Build up all of the passes that we want to run on the module.
  legacy::PassManager pm;
  pm.add(new callcounter::StaticCallCounter());
  pm.add(new StaticCountPrinter(outs()));
  pm.run(m);
}

int
main(int argc, char** argv) {
  // This boilerplate provides convenient stack traces and clean LLVM exit
  // handling. It also initializes the built in support for convenient
  // command line option handling.
  sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj shutdown;
  cl::HideUnrelatedOptions(callCounterCategory);
  cl::ParseCommandLineOptions(argc, argv);

  // Construct an IR file from the filename passed on the command line.
  SMDiagnostic err;
  LLVMContext context;
  unique_ptr<Module> module = parseIRFile(inPath.getValue(), err, context);

  if (!module.get()) {
    errs() << "Error reading bitcode file: " << inPath << "\n";
    err.print(argv[0], errs());
    return -1;
  }

  if (AnalysisType::DYNAMIC == analysisType) {
    prepareLinkingPaths(StringRef(argv[0]));
    instrumentForDynamicCount(*module);
  } else {
    countStaticCalls(*module);
  }

  return 0;
}
<commit_msg>Update to llvm 6.0<commit_after>
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/CommandFlags.def"
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Linker/Linker.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"

#include <memory>
#include <string>

#include "DynamicCallCounter.h"
#include "StaticCallCounter.h"

#include "config.h"

using namespace llvm;
using std::string;
using std::unique_ptr;
using std::vector;
using llvm::sys::ExecuteAndWait;
using llvm::sys::findProgramByName;
using llvm::legacy::PassManager;

enum class AnalysisType {
  STATIC,
  DYNAMIC,
};

static cl::OptionCategory callCounterCategory{"call counter options"};

static cl::opt<string> inPath{cl::Positional,
                              cl::desc{"<Module to analyze>"},
                              cl::value_desc{"bitcode filename"},
                              cl::init(""),
                              cl::Required,
                              cl::cat{callCounterCategory}};

static cl::opt<AnalysisType> analysisType{
    cl::desc{"Select analyis type:"},
    cl::values(clEnumValN(AnalysisType::STATIC,
                          "static",
                          "Count static direct calls."),
               clEnumValN(AnalysisType::DYNAMIC,
                          "dynamic",
                          "Count dynamic direct calls.")
               ),
    cl::Required,
    cl::cat{callCounterCategory}};

static cl::opt<string> outFile{"o",
                               cl::desc{"Filename of the instrumented program"},
                               cl::value_desc{"filename"},
                               cl::init(""),
                               cl::cat{callCounterCategory}};

static cl::opt<char> optLevel{
    "O",
    cl::desc{"Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O2')"},
    cl::Prefix,
    cl::ZeroOrMore,
    cl::init('2'),
    cl::cat{callCounterCategory}};

static cl::list<string> libPaths{"L",
                                 cl::Prefix,
                                 cl::desc{"Specify a library search path"},
                                 cl::value_desc{"directory"},
                                 cl::cat{callCounterCategory}};

static cl::list<string> libraries{"l",
                                  cl::Prefix,
                                  cl::desc{"Specify libraries to link against"},
                                  cl::value_desc{"library prefix"},
                                  cl::cat{callCounterCategory}};

static void
compile(Module& m, StringRef outputPath) {
  string err;

  Triple triple        = Triple(m.getTargetTriple());
  Target const* target = TargetRegistry::lookupTarget(MArch, triple, err);
  if (!target) {
    report_fatal_error("Unable to find target:\n " + err);
  }

  CodeGenOpt::Level level = CodeGenOpt::Default;
  switch (optLevel) {
    default:
      report_fatal_error("Invalid optimization level.\n");
    // No fall through
    case '0': level = CodeGenOpt::None; break;
    case '1': level = CodeGenOpt::Less; break;
    case '2': level = CodeGenOpt::Default; break;
    case '3': level = CodeGenOpt::Aggressive; break;
  }

  string FeaturesStr;
  TargetOptions options = InitTargetOptionsFromCodeGenFlags();
  unique_ptr<TargetMachine> machine(
      target->createTargetMachine(triple.getTriple(),
                                  MCPU,
                                  FeaturesStr,
                                  options,
                                  getRelocModel(),
                                  CMModel.getValue(),
                                  level));
  assert(machine.get() && "Could not allocate target machine!");

  if (FloatABIForCalls != FloatABI::Default) {
    options.FloatABIType = FloatABIForCalls;
  }

  std::error_code errc;
  auto out =
      std::make_unique<ToolOutputFile>(outputPath, errc, sys::fs::F_None);
  if (!out) {
    report_fatal_error("Unable to create file:\n " + errc.message());
  }

  // Build up all of the passes that we want to do to the module.
  legacy::PassManager pm;

  // Add target specific info and transforms
  TargetLibraryInfoImpl tlii(triple);
  pm.add(new TargetLibraryInfoWrapperPass(tlii));

  m.setDataLayout(machine->createDataLayout());

  {  // Bound this scope
    raw_pwrite_stream* os(&out->os());

    FileType = TargetMachine::CGFT_ObjectFile;
    std::unique_ptr<buffer_ostream> bos;
    if (!out->os().supportsSeeking()) {
      bos = std::make_unique<buffer_ostream>(*os);
      os  = bos.get();
    }

    // Ask the target to add backend passes as necessary.
    if (machine->addPassesToEmitFile(pm, *os, FileType)) {
      report_fatal_error("target does not support generation "
                         "of this file type!\n");
    }

    // Before executing passes, print the final values of the LLVM options.
    cl::PrintOptionValues();

    pm.run(m);
  }

  // Keep the output binary if we've been successful to this point.
  out->keep();
}

static void
link(StringRef objectFile, StringRef outputFile) {
  auto clang = findProgramByName("clang++");
  string opt("-O");
  opt += optLevel;

  if (!clang) {
    report_fatal_error("Unable to find clang.");
  }
  vector<string> args{clang.get(), opt, "-o", outputFile, objectFile};

  for (auto& libPath : libPaths) {
    args.push_back("-L" + libPath);
  }

  for (auto& library : libraries) {
    args.push_back("-l" + library);
  }

  vector<char const*> charArgs;
  for (auto& arg : args) {
    charArgs.push_back(arg.c_str());
  }
  charArgs.push_back(nullptr);

  for (auto& arg : args) {
    outs() << arg.c_str() << " ";
  }
  outs() << "\n";

  string err;
  if (-1 == ExecuteAndWait(
                clang.get(), &charArgs[0], nullptr, {}, 0, 0, &err)) {
    report_fatal_error("Unable to link output file.");
  }
}

static void
generateBinary(Module& m, StringRef outputFilename) {
  // Compiling to native should allow things to keep working even when the
  // version of clang on the system and the version of LLVM used to compile
  // the tool don't quite match up.
  string objectFile = outputFilename.str() + ".o";
  compile(m, objectFile);
  link(objectFile, outputFilename);
}

static void
saveModule(Module const& m, StringRef filename) {
  std::error_code errc;
  raw_fd_ostream out(filename.data(), errc, sys::fs::F_None);

  if (errc) {
    report_fatal_error("error saving llvm module to '" + filename + "': \n"
                       + errc.message());
  }
  WriteBitcodeToFile(&m, out);
}

static void
prepareLinkingPaths(SmallString<32> invocationPath) {
  // First search the directory of the binary for the library, in case it is
  // all bundled together.
  sys::path::remove_filename(invocationPath);
  if (!invocationPath.empty()) {
    libPaths.push_back(invocationPath.str());
  }
// If the builder doesn't plan on installing it, we still need to get to the
// runtime library somehow, so just build in the path to the temporary one.
#ifdef CMAKE_INSTALL_PREFIX
  libPaths.push_back(CMAKE_INSTALL_PREFIX "/lib");
#elif defined(CMAKE_TEMP_LIBRARY_PATH)
  libPaths.push_back(CMAKE_TEMP_LIBRARY_PATH);
#elif defined(TEMP_LIBRARY_PATH)
  // This is a bit of a hack
  libPaths.push_back(TEMP_LIBRARY_PATH "/Debug+Asserts/lib/");
  libPaths.push_back(TEMP_LIBRARY_PATH "/Release+Asserts/lib/");
  libPaths.push_back(TEMP_LIBRARY_PATH "/Debug/lib/");
  libPaths.push_back(TEMP_LIBRARY_PATH "/Release/lib/");
#endif
  libraries.push_back(RUNTIME_LIB);
  libraries.push_back("rt");
}

static void
instrumentForDynamicCount(Module& m) {
  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();
  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

  if (outFile.getValue() == "") {
    errs() << "-o command line option must be specified.\n";
    exit(-1);
  }

  // Build up all of the passes that we want to run on the module.
  legacy::PassManager pm;
  pm.add(new callcounter::DynamicCallCounter());
  pm.add(createVerifierPass());
  pm.run(m);

  generateBinary(m, outFile);
  saveModule(m, outFile + ".callcounter.bc");
}

struct StaticCountPrinter : public ModulePass {
  static char ID;
  raw_ostream& out;

  explicit StaticCountPrinter(raw_ostream& out) : ModulePass(ID), out(out) {}

  bool
  runOnModule(Module& m) override {
    getAnalysis<callcounter::StaticCallCounter>().print(out, &m);
    return false;
  }

  void
  getAnalysisUsage(AnalysisUsage& au) const override {
    au.addRequired<callcounter::StaticCallCounter>();
    au.setPreservesAll();
  }
};

char StaticCountPrinter::ID = 0;

static void
countStaticCalls(Module& m) {
  // Build up all of the passes that we want to run on the module.
  legacy::PassManager pm;
  pm.add(new callcounter::StaticCallCounter());
  pm.add(new StaticCountPrinter(outs()));
  pm.run(m);
}

int
main(int argc, char** argv) {
  // This boilerplate provides convenient stack traces and clean LLVM exit
  // handling. It also initializes the built in support for convenient
  // command line option handling.
  sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj shutdown;
  cl::HideUnrelatedOptions(callCounterCategory);
  cl::ParseCommandLineOptions(argc, argv);

  // Construct an IR file from the filename passed on the command line.
  SMDiagnostic err;
  LLVMContext context;
  unique_ptr<Module> module = parseIRFile(inPath.getValue(), err, context);

  if (!module.get()) {
    errs() << "Error reading bitcode file: " << inPath << "\n";
    err.print(argv[0], errs());
    return -1;
  }

  if (AnalysisType::DYNAMIC == analysisType) {
    prepareLinkingPaths(StringRef(argv[0]));
    instrumentForDynamicCount(*module);
  } else {
    countStaticCalls(*module);
  }

  return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************************
    garlic-player: SMIL Player for Digital Signage
    Copyright (C) 2016 Nikolaos Saghiadinos <ns@smil-control.com>
    This file is part of the garlic-player source code

    This program is free software: you can redistribute it and/or  modify
    it under the terms of the GNU Affero General Public License, version 3,
    as published by the Free Software Foundation.

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*************************************************************************************/

#include "configuration.h"
#include <QXmlStreamReader>
#include <QString>
#include <memory>
#include <mutex>

/**
 * @brief TConfiguration::TConfiguration
 * @param UserConfig
 */
TConfiguration::TConfiguration(QSettings *UserConfig, QObject *parent) : QObject(parent)
{
    setUserConfig(UserConfig);
    determineUuid();
    determinePlayerName();
    determineOS();
    setTimeZone(QTimeZone::systemTimeZoneId());
    // ugly workaround from https://stackoverflow.com/questions/21976264/qt-isodate-formatted-date-time-including-timezone
    // cause otherwise we get no time zone in date string
    setStartTime(QDateTime::currentDateTime().toOffsetFromUtc(QDateTime::currentDateTime().offsetFromUtc()).toString(Qt::ISODate));
    determineUserAgent();
}

QString TConfiguration::getLastPlayedIndexPath()
{
    return getUserConfigByKey("last_played_index_path");
}

void TConfiguration::setLastPlayedIndexPath(const QString &value)
{
    setUserConfigByKey("last_played_index_path", value);
}

QSettings *TConfiguration::getUserConfig() const
{
    return UserConfig;
}

void TConfiguration::setUserConfig(QSettings *value)
{
    UserConfig = value;
}

QString TConfiguration::getUserConfigByKey(QString key)
{
    return UserConfig->value(key, "").toString();
}

void TConfiguration::setUserConfigByKey(QString key, QString value)
{
    UserConfig->setValue(key, value);
}

QString TConfiguration::getPlayerName() const
{
    return player_name;
}

void TConfiguration::setPlayerName(const QString &value)
{
    player_name = value;
    setUserConfigByKey("player_name", value);
}

QString TConfiguration::getUuid() const
{
    return uuid;
}

void TConfiguration::setUuid(const QString &value)
{
    uuid = value;
    setUserConfigByKey("uuid", value);
}

QString TConfiguration::getUserAgent() const
{
   return user_agent;
}

void TConfiguration::setUserAgent(const QString &value)
{
    user_agent = value;
}

QString TConfiguration::getIndexUri()
{
    return index_uri;
}

void TConfiguration::setIndexUri(const QString &value)
{
    index_uri = value;
}

void TConfiguration::determineIndexUri(QString path)
{
    if (path != "")
    {
        setUserConfigByKey("index_uri", path);
        setIndexUri(path);
    }
    else if (getUserConfigByKey("index_uri") != "") // get from intern config
    {
        setIndexUri(getUserConfigByKey("index_uri"));
    }
    else
    {
        checkConfigXML();
    }

    if (index_uri != "" && index_uri.mid(0, 4) != "http"  && index_uri.mid(0, 3) != "ftp" && index_uri.mid(0, 1) != "/") // https is includered in http!
    {
       setUserConfigByKey("index_uri", base_path+index_uri);
       setIndexUri( base_path+index_uri);
    }
    determineIndexPath();
}

void TConfiguration::setIndexPath(const QString &value)
{
    index_path = value;
}

void TConfiguration::determineIndexPath()
{
    if (index_uri.mid(0, 4) == "http" || index_uri.mid(0, 3) == "ftp")
    {
        QUrl url(index_uri);
        setIndexPath(url.adjusted(QUrl::RemoveFilename |
                                  QUrl::RemoveQuery |
                                  QUrl::RemoveFragment |
                                  QUrl::RemovePort).toString());
        if (index_path.mid(index_path.length()-1, 1) != "/")
            setIndexPath(index_path+"/");

    }
    else
    {
        QFileInfo fi(index_uri);
        setIndexPath(fi.path()+"/");
    }
}

QString TConfiguration::getIndexPath()
{
    return index_path;
}

QString TConfiguration::getOS() const
{
    return os;
}

void TConfiguration::setOS(const QString &value)
{
    os = value;
}

QString TConfiguration::getBasePath() const
{
    return base_path;
}

void TConfiguration::setBasePath(const QString &value)
{
    base_path = value;
}

void TConfiguration::determineBasePath(QString absolute_path_to_bin)
{
    if (absolute_path_to_bin.contains("/bin"))
        setBasePath(absolute_path_to_bin.mid(0, absolute_path_to_bin.length()-3)); // "/" is set when xyz/bin
    else
        setBasePath(absolute_path_to_bin);

    if (base_path.mid(base_path.length()-1, 1) != "/")
        setBasePath(base_path+"/");
}

/**
 * @brief TConfiguration::getPaths returns paths.
 *        Values can be config, var, media or base
 * @param path_name
 * @return
 */
QString TConfiguration::getPaths(QString path_name)
{
    QString ret = base_path;
    if (path_name == "cache")
        ret = cache_dir;
    else if (path_name == "logs")
        ret = log_dir;

    return ret;
}

void TConfiguration::createDirectories()
{
#if defined Q_OS_WIN32  // QStandardPaths::CacheLocation in windows 7 is set to appdir (bin), which should not be writable after installation in Program Files
    cache_dir = QStandardPaths::locate(QStandardPaths::AppLocalDataLocation, QString(), QStandardPaths::LocateDirectory) +  getAppName() + "/cache/";
    log_dir   = QStandardPaths::locate(QStandardPaths::AppLocalDataLocation, QString(), QStandardPaths::LocateDirectory) +  getAppName() + "/logs/";
#else
    cache_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
    log_dir   = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/logs/";
#endif
    createDirectoryIfNotExist(cache_dir);
    createDirectoryIfNotExist(log_dir);
}

void TConfiguration::determineUserAgent()
{
    setUserAgent("GAPI/1.0 (UUID:"+getUuid()+"; NAME:"+getPlayerName()+") garlic-"+getOS()+"/"+getVersion()+" (MODEL:Garlic)");
}

void TConfiguration::checkConfigXML()
{
    QFile file(base_path+"config.xml");
    if (file.exists() && file.open(QIODevice::ReadOnly))
    {
        QXmlStreamReader reader(&file);
        while (!reader.atEnd())
        {
             reader.readNext();
             if (reader.isStartElement())
             {
                 if (reader.name() == "prop" && reader.attributes().value("name") == "content.serverUrl")
                 {
                     setUserConfigByKey("index_uri", reader.attributes().value("value").toString());
                     setIndexUri(reader.attributes().value("value").toString());
                 }
             }
         }
        file.rename(base_path+"config.xml", base_path+"config_readed.xml");
    }
}

QString TConfiguration::getStartTime() const
{
    return start_time;
}

void TConfiguration::setStartTime(const QString &value)
{
    start_time = value;
}

QString TConfiguration::getTimeZone() const
{
    return time_zone;
}

void TConfiguration::setTimeZone(const QString &value)
{
    time_zone = value;
}

void TConfiguration::createDirectoryIfNotExist(QString path)
{
    QDir dir;
    dir.setPath(path);
    if (!dir.exists() && !dir.mkpath("."))
        qCritical(SmilParser) << "Failed to create " << dir.path() << "\r";
    return;
}

void TConfiguration::determineUuid()
{
    setUuid(getUserConfigByKey("uuid"));
    if (getUuid() == "")
    {
        setUuid(QUuid::createUuid().toString().mid(1, 36));
        UserConfig->setValue("uuid", getUuid());
    }
}

void TConfiguration::determinePlayerName()
{
    setPlayerName(getUserConfigByKey("player_name"));
    if (getPlayerName() == "")
    {
        setPlayerName(getUuid().mid(24,12));
        UserConfig->setValue("player_name", getPlayerName());
    }
}

void TConfiguration::determineOS()
{
#if defined  Q_OS_ANDROID
    setOS("android");
#elif defined Q_OS_BSD4
    setOS("bsd4");
#elif defined Q_OS_DARWIN
    setOS("darwin");
#elif defined Q_OS_FREEBSD
    setOS("freebsd");
#elif defined Q_OS_HURD
    setOS("hurd");
#elif defined Q_OS_IOS
    setOS("ios");
#elif defined Q_OS_LINUX
    setOS("linux");
#elif defined Q_OS_NETBSD
    setOS("netbsd");
#elif defined Q_OS_OPENBSD
    setOS("openbsd");
#elif defined Q_OS_OSX
    setOS("osx");
#elif defined Q_OS_WIN32
    setOS("windows");
#elif defined Q_OS_WINPHONE
    setOS("winphone");
#elif defined Q_OS_WINRT
    setOS("winrt");
#else
    setOS("unknown");
#endif
}

<commit_msg>bugfixes<commit_after>/*************************************************************************************
    garlic-player: SMIL Player for Digital Signage
    Copyright (C) 2016 Nikolaos Saghiadinos <ns@smil-control.com>
    This file is part of the garlic-player source code

    This program is free software: you can redistribute it and/or  modify
    it under the terms of the GNU Affero General Public License, version 3,
    as published by the Free Software Foundation.

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*************************************************************************************/

#include "configuration.h"
#include <QXmlStreamReader>
#include <QString>
#include <memory>
#include <mutex>

/**
 * @brief TConfiguration::TConfiguration
 * @param UserConfig
 */
TConfiguration::TConfiguration(QSettings *UserConfig, QObject *parent) : QObject(parent)
{
    setUserConfig(UserConfig);
    determineUuid();
    determinePlayerName();
    determineOS();
    setTimeZone(QTimeZone::systemTimeZoneId());
    // ugly workaround from https://stackoverflow.com/questions/21976264/qt-isodate-formatted-date-time-including-timezone
    // cause otherwise we get no time zone in date string
    setStartTime(QDateTime::currentDateTime().toOffsetFromUtc(QDateTime::currentDateTime().offsetFromUtc()).toString(Qt::ISODate));
    determineUserAgent();
}

QString TConfiguration::getLastPlayedIndexPath()
{
    return getUserConfigByKey("last_played_index_path");
}

void TConfiguration::setLastPlayedIndexPath(const QString &value)
{
    setUserConfigByKey("last_played_index_path", value);
}

QSettings *TConfiguration::getUserConfig() const
{
    return UserConfig;
}

void TConfiguration::setUserConfig(QSettings *value)
{
    UserConfig = value;
}

QString TConfiguration::getUserConfigByKey(QString key)
{
    return UserConfig->value(key, "").toString();
}

void TConfiguration::setUserConfigByKey(QString key, QString value)
{
    UserConfig->setValue(key, value);
}

QString TConfiguration::getPlayerName() const
{
    return player_name;
}

void TConfiguration::setPlayerName(const QString &value)
{
    player_name = value;
    setUserConfigByKey("player_name", value);
}

QString TConfiguration::getUuid() const
{
    return uuid;
}

void TConfiguration::setUuid(const QString &value)
{
    uuid = value;
    setUserConfigByKey("uuid", value);
}

QString TConfiguration::getUserAgent() const
{
   return user_agent;
}

void TConfiguration::setUserAgent(const QString &value)
{
    user_agent = value;
}

QString TConfiguration::getIndexUri()
{
    return index_uri;
}

void TConfiguration::setIndexUri(const QString &value)
{
    index_uri = value;
}

void TConfiguration::determineIndexUri(QString path)
{
    if (path != "")
    {
        setUserConfigByKey("index_uri", path);
        setIndexUri(path);
    }
    else if (getUserConfigByKey("index_uri") != "") // get from intern config
    {
        setIndexUri(getUserConfigByKey("index_uri"));
    }
    else
    {
        checkConfigXML();
    }

    if (index_uri != "" && index_uri.mid(0, 4) != "http"  && index_uri.mid(0, 3) != "ftp" && index_uri.mid(0, 1) != "/") // https is includered in http!
    {
       setUserConfigByKey("index_uri", base_path+index_uri);
       setIndexUri( base_path+index_uri);
    }
    determineIndexPath();
}

void TConfiguration::setIndexPath(const QString &value)
{
    index_path = value;
}

void TConfiguration::determineIndexPath()
{
    if (index_uri.mid(0, 4) == "http" || index_uri.mid(0, 3) == "ftp")
    {
        QUrl url(index_uri);
        setIndexPath(url.adjusted(QUrl::RemoveFilename |
                                  QUrl::RemoveQuery |
                                  QUrl::RemoveFragment |
                                  QUrl::RemovePort).toString());
        if (index_path.mid(index_path.length()-1, 1) != "/")
            setIndexPath(index_path+"/");

    }
    else
    {
        QFileInfo fi(index_uri);
        setIndexPath(fi.path()+"/");
    }
}

QString TConfiguration::getIndexPath()
{
    return index_path;
}

QString TConfiguration::getOS() const
{
    return os;
}

void TConfiguration::setOS(const QString &value)
{
    os = value;
}

QString TConfiguration::getBasePath() const
{
    return base_path;
}

void TConfiguration::setBasePath(const QString &value)
{
    base_path = value;
}

void TConfiguration::determineBasePath(QString absolute_path_to_bin)
{
    if (absolute_path_to_bin.contains("/bin"))
        setBasePath(absolute_path_to_bin.mid(0, absolute_path_to_bin.length()-3)); // "/" is set when xyz/bin
    else
        setBasePath(absolute_path_to_bin);

    if (base_path.mid(base_path.length()-1, 1) != "/")
        setBasePath(base_path+"/");
}

/**
 * @brief TConfiguration::getPaths returns paths.
 *        Values can be config, var, media or base
 * @param path_name
 * @return
 */
QString TConfiguration::getPaths(QString path_name)
{
    QString ret = base_path;
    if (path_name == "cache")
        ret = cache_dir;
    else if (path_name == "logs")
        ret = log_dir;

    return ret;
}

void TConfiguration::createDirectories()
{
#if defined Q_OS_WIN32  // QStandardPaths::CacheLocation in windows 7 is set to appdir (bin), which should not be writable after installation in Program Files
    cache_dir = QStandardPaths::locate(QStandardPaths::AppLocalDataLocation, QString(), QStandardPaths::LocateDirectory) +  getAppName() + "/cache/";
    log_dir   = QStandardPaths::locate(QStandardPaths::AppLocalDataLocation, QString(), QStandardPaths::LocateDirectory) +  getAppName() + "/logs/";
#else
    cache_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+ "/";
    log_dir   = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/logs/";
#endif
    createDirectoryIfNotExist(cache_dir);
    createDirectoryIfNotExist(log_dir);
}

void TConfiguration::determineUserAgent()
{
    setUserAgent("GAPI/1.0 (UUID:"+getUuid()+"; NAME:"+getPlayerName()+") garlic-"+getOS()+"/"+getVersion()+" (MODEL:Garlic)");
}

void TConfiguration::checkConfigXML()
{
    QFile file(base_path+"config.xml");
    if (file.exists() && file.open(QIODevice::ReadOnly))
    {
        QXmlStreamReader reader(&file);
        while (!reader.atEnd())
        {
             reader.readNext();
             if (reader.isStartElement())
             {
                 if (reader.name() == "prop" && reader.attributes().value("name") == "content.serverUrl")
                 {
                     setUserConfigByKey("index_uri", reader.attributes().value("value").toString());
                     setIndexUri(reader.attributes().value("value").toString());
                 }
             }
         }
        file.rename(base_path+"config.xml", base_path+"config_readed.xml");
    }
}

QString TConfiguration::getStartTime() const
{
    return start_time;
}

void TConfiguration::setStartTime(const QString &value)
{
    start_time = value;
}

QString TConfiguration::getTimeZone() const
{
    return time_zone;
}

void TConfiguration::setTimeZone(const QString &value)
{
    time_zone = value;
}

void TConfiguration::createDirectoryIfNotExist(QString path)
{
    QDir dir;
    dir.setPath(path);
    if (!dir.exists() && !dir.mkpath("."))
        qCritical(SmilParser) << "Failed to create " << dir.path() << "\r";
    return;
}

void TConfiguration::determineUuid()
{
    setUuid(getUserConfigByKey("uuid"));
    if (getUuid() == "")
    {
        setUuid(QUuid::createUuid().toString().mid(1, 36));
        UserConfig->setValue("uuid", getUuid());
    }
}

void TConfiguration::determinePlayerName()
{
    setPlayerName(getUserConfigByKey("player_name"));
    if (getPlayerName() == "")
    {
        setPlayerName(getUuid().mid(24,12));
        UserConfig->setValue("player_name", getPlayerName());
    }
}

void TConfiguration::determineOS()
{
#if defined  Q_OS_ANDROID
    setOS("android");
#elif defined Q_OS_BSD4
    setOS("bsd4");
#elif defined Q_OS_DARWIN
    setOS("darwin");
#elif defined Q_OS_FREEBSD
    setOS("freebsd");
#elif defined Q_OS_HURD
    setOS("hurd");
#elif defined Q_OS_IOS
    setOS("ios");
#elif defined Q_OS_LINUX
    setOS("linux");
#elif defined Q_OS_NETBSD
    setOS("netbsd");
#elif defined Q_OS_OPENBSD
    setOS("openbsd");
#elif defined Q_OS_OSX
    setOS("osx");
#elif defined Q_OS_WIN32
    setOS("windows");
#elif defined Q_OS_WINPHONE
    setOS("winphone");
#elif defined Q_OS_WINRT
    setOS("winrt");
#else
    setOS("unknown");
#endif
}

<|endoftext|>


<commit_before><commit_msg>coverity#705269 Missing break in switch<commit_after><|endoftext|>


<commit_before>#ifndef AP_MOVING_OBJECT
#define AP_MOVING_OBJECT

#include <Ogre.h>

#include "net/NetObject.h"
#include "net/Serializable.h"
#include "RectBoundaries.hpp"

namespace ap {

class MovableState : public net::Serializable {
    public:
    Ogre::Vector3       location;
    Ogre::Quaternion    orientation;
    Ogre::Vector3       velocity;

    MovableState(Ogre::Vector3  startingVelocity);
    ~MovableState() { /* Do nothing */ }
    int serialize(uint8 *buffer, int start, int buflength) const;
    int unserialize(uint8 *buffer, int start);
};

class MovableControl : public net::Serializable {
    public:
    float               accelerationFwd;
    float               velocityCWiseTurning;

    MovableControl();
    ~MovableControl() { /* Do nothing */ }
    int serialize(uint8 *buffer, int start, int buflength) const;
    int unserialize(uint8 *buffer, int start);
};

class MovingObject : public net::NetObject {
    public:
    MovingObject(float nFriction = 0.05f, Ogre::Vector3 startingSpeed = Ogre::Vector3::ZERO);
    virtual ~MovingObject();

    void setWorldBoundaries(float top, float bottom, float left, float right);

    void setMaxSpeed(float speed);
    void setVelocity(Ogre::Vector3 velocity);
    Ogre::Vector3 getVelocity() const { return state.velocity; };

    void setPosition(Ogre::Vector3 pos) { state.location = pos; };

    void addForwardAcceleration(float amount);
    void addClockwiseTurningSpeed(float amountRad);

    void setForwardAcceleration(float amount) { control.accelerationFwd = amount; }
    void setClockwiseTurningSpeed(float amount) { control.velocityCWiseTurning = amount; }

    Ogre::Vector3 getFacing() const;

    Ogre::SceneNode* getOwnerNode() const { return pOwnerNode; }
    void setOwnerNode(Ogre::SceneNode *node) { pOwnerNode = node; }
    bool hasOwnerNode() const { return (!pOwnerNode); }

    void update(unsigned long msSinceLast);

    //NetObject serialization
    int serialize(uint8 *buffer, int start, int buflength) const;
    int unserialize(uint8 *buffer, int start);
    NetObject *create(int id);

    private:
    Ogre::Vector3       initialFacing;
    MovableState        state;
    MovableControl      control;
    float               friction;

    RectBoundaries      worldBoundaries;
    float               maxSpeedSquared;

    Ogre::SceneNode     *pOwnerNode;

    void updateVelocity(unsigned long msSinceLast);
    void updateFacing(unsigned long msSinceLast);
    void updatePosition(unsigned long msSinceLast);
};

} // namespace ap

#endif
<commit_msg>Fixed hasOwnerNode()-method, used to be negated for some reason.<commit_after>#ifndef AP_MOVING_OBJECT
#define AP_MOVING_OBJECT

#include <Ogre.h>

#include "net/NetObject.h"
#include "net/Serializable.h"
#include "RectBoundaries.hpp"

namespace ap {

class MovableState : public net::Serializable {
    public:
    Ogre::Vector3       location;
    Ogre::Quaternion    orientation;
    Ogre::Vector3       velocity;

    MovableState(Ogre::Vector3  startingVelocity);
    ~MovableState() { /* Do nothing */ }
    int serialize(uint8 *buffer, int start, int buflength) const;
    int unserialize(uint8 *buffer, int start);
};

class MovableControl : public net::Serializable {
    public:
    float               accelerationFwd;
    float               velocityCWiseTurning;

    MovableControl();
    ~MovableControl() { /* Do nothing */ }
    int serialize(uint8 *buffer, int start, int buflength) const;
    int unserialize(uint8 *buffer, int start);
};

class MovingObject : public net::NetObject {
    public:
    MovingObject(float nFriction = 0.05f, Ogre::Vector3 startingSpeed = Ogre::Vector3::ZERO);
    virtual ~MovingObject();

    void setWorldBoundaries(float top, float bottom, float left, float right);

    void setMaxSpeed(float speed);
    void setVelocity(Ogre::Vector3 velocity);
    Ogre::Vector3 getVelocity() const { return state.velocity; };

    void setPosition(Ogre::Vector3 pos) { state.location = pos; };

    void addForwardAcceleration(float amount);
    void addClockwiseTurningSpeed(float amountRad);

    void setForwardAcceleration(float amount) { control.accelerationFwd = amount; }
    void setClockwiseTurningSpeed(float amount) { control.velocityCWiseTurning = amount; }

    Ogre::Vector3 getFacing() const;

    Ogre::SceneNode* getOwnerNode() const { return pOwnerNode; }
    void setOwnerNode(Ogre::SceneNode *node) { pOwnerNode = node; }
    bool hasOwnerNode() const { return pOwnerNode; }

    void update(unsigned long msSinceLast);

    //NetObject serialization
    int serialize(uint8 *buffer, int start, int buflength) const;
    int unserialize(uint8 *buffer, int start);
    NetObject *create(int id);

    private:
    Ogre::Vector3       initialFacing;
    MovableState        state;
    MovableControl      control;
    float               friction;

    RectBoundaries      worldBoundaries;
    float               maxSpeedSquared;

    Ogre::SceneNode     *pOwnerNode;

    void updateVelocity(unsigned long msSinceLast);
    void updateFacing(unsigned long msSinceLast);
    void updatePosition(unsigned long msSinceLast);
};

} // namespace ap

#endif
<|endoftext|>


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

Library:   TubeTK

Copyright 2010 Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

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.

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

#include <iostream>
#include <fstream>
#include <list>
#include <vector>

#include "itkSpatialObjectReader.h"
#include "itkImageFileReader.h"
#include "itkVesselTubeSpatialObject.h"

#include "tubeMessage.h"
#include "tubeCLIFilterWatcher.h"
#include "tubeCLIProgressReporter.h"
#include "itkTimeProbesCollectorBase.h"

#include "ComputeTubeProbabilityCLP.h"

template< unsigned int VDimension >
int DoIt( int argc, char **argv );

// This needs to be declared for tubeCLIHelperFunctions.
template< class TPixel, unsigned int VDimension >
int DoIt( int argc, char **argv ){ return 0; }
#include "tubeCLIHelperFunctions.h"

int main(int argc, char **argv)
{
  PARSE_ARGS;

  itk::ImageIOBase::IOComponentType componentType;
  unsigned int dimension;

  try
    {
    tube::GetImageInformation( inMeanImageFile, componentType, dimension );
    switch( dimension )
      {
      case 2:
        return DoIt< 2 >( argc, argv );
      case 3:
        return DoIt< 3 >( argc, argv );
      default:
        return EXIT_FAILURE;
      }
    }
  catch( const std::exception & exception )
    {
    tube::ErrorMessage( exception.what() );
    return EXIT_FAILURE;
    }
  return EXIT_FAILURE;
}

template< unsigned int VDimension >
int DoIt(int argc, char **argv)
{
  PARSE_ARGS;

  const unsigned int Dimension = VDimension;

  typedef itk::Image< short, Dimension >             ImageType;
  typedef itk::GroupSpatialObject< Dimension >       GroupType;
  typedef itk::ImageFileReader< ImageType >          ImageReaderType;
  typedef itk::SpatialObjectReader< Dimension >      SOReaderType;
  typedef itk::VesselTubeSpatialObject< Dimension >  TubeType;
  typedef typename TubeType::TubePointType           TubePointType;
  typedef typename TubeType::TransformType           TubeTransformType;

  tube::CLIProgressReporter progressReporter(
    "tubeDensityProbability",
    CLPProcessInformation );

  progressReporter.Start();

  /*
   * Read in spatial object file (tubes)
   */
  typename SOReaderType::Pointer soReader = SOReaderType::New();
  soReader->SetFileName( inTubeFile.c_str() );
  soReader->Update();
  typename GroupType::Pointer group = soReader->GetGroup();

  progressReporter.Report(0.1);

  /*
   * Read in ATLAS EMD image
   */
  typename ImageReaderType::Pointer imReader = ImageReaderType::New();
  imReader->SetFileName( inMeanImageFile.c_str() );
  imReader->Update();
  typename ImageType::Pointer meanImage = imReader->GetOutput();

  progressReporter.Report(0.2);

  char childName[] = "Tube";
  typename TubeType::ChildrenListType * tubeList = group->GetChildren(99999, childName);
  typename TubeType::ChildrenListType::const_iterator tubeIt = tubeList->begin();
  TubePointType tubePoint;
  typename TubeTransformType::Pointer tubeTransform;
  std::ofstream writeStream;
  writeStream.open(outFile.c_str(), std::ios::binary | std::ios::out);
  while(tubeIt != tubeList->end()) // Iterate over tubes
    {
    typename TubeType::Pointer tube = dynamic_cast<TubeType *>((*tubeIt).GetPointer());

    tube->RemoveDuplicatePoints();
    tube->ComputeTangentAndNormals();

    itk::Point<double, Dimension> pnt;
    itk::Index< Dimension > indx;
    tube->ComputeObjectToWorldTransform();
    tubeTransform = tube->GetIndexToWorldTransform();
    for( unsigned int i=0; i<tube->GetNumberOfPoints() ; i++)
      {
      tubePoint = static_cast<TubePointType>(tube->GetPoints()[i]); // Get point
      pnt = tubePoint.GetPosition(); // Get point's position
      pnt = tubeTransform->TransformPoint(pnt); // Point coords to physical coords
      meanImage->TransformPhysicalPointToIndex(pnt, indx); // Get closest voxel
      writeStream << meanImage->GetPixel(indx) << std::endl; // Write value of ATLAS EMD file at voxel
      }

    ++tubeIt;
    }
  writeStream.close();

  progressReporter.Report(1.0);
  progressReporter.End();

  return 1;
  }
<commit_msg>COMP: ComputeTubeProbability: unused parameter warnings.<commit_after>/*=========================================================================

Library:   TubeTK

Copyright 2010 Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

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.

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

#include <iostream>
#include <fstream>
#include <list>
#include <vector>

#include "itkSpatialObjectReader.h"
#include "itkImageFileReader.h"
#include "itkVesselTubeSpatialObject.h"

#include "tubeMessage.h"
#include "tubeCLIFilterWatcher.h"
#include "tubeCLIProgressReporter.h"
#include "itkTimeProbesCollectorBase.h"

#include "ComputeTubeProbabilityCLP.h"

template< unsigned int VDimension >
int DoIt( int argc, char **argv );

// This needs to be declared for tubeCLIHelperFunctions.
template< class TPixel, unsigned int VDimension >
int DoIt( int itkNotUsed(argc), char **itkNotUsed(argv) ){ return 0; }
#include "tubeCLIHelperFunctions.h"

int main(int argc, char **argv)
{
  PARSE_ARGS;

  itk::ImageIOBase::IOComponentType componentType;
  unsigned int dimension;

  try
    {
    tube::GetImageInformation( inMeanImageFile, componentType, dimension );
    switch( dimension )
      {
      case 2:
        return DoIt< 2 >( argc, argv );
      case 3:
        return DoIt< 3 >( argc, argv );
      default:
        return EXIT_FAILURE;
      }
    }
  catch( const std::exception & exception )
    {
    tube::ErrorMessage( exception.what() );
    return EXIT_FAILURE;
    }
  return EXIT_FAILURE;
}

template< unsigned int VDimension >
int DoIt(int argc, char **argv)
{
  PARSE_ARGS;

  const unsigned int Dimension = VDimension;

  typedef itk::Image< short, Dimension >             ImageType;
  typedef itk::GroupSpatialObject< Dimension >       GroupType;
  typedef itk::ImageFileReader< ImageType >          ImageReaderType;
  typedef itk::SpatialObjectReader< Dimension >      SOReaderType;
  typedef itk::VesselTubeSpatialObject< Dimension >  TubeType;
  typedef typename TubeType::TubePointType           TubePointType;
  typedef typename TubeType::TransformType           TubeTransformType;

  tube::CLIProgressReporter progressReporter(
    "tubeDensityProbability",
    CLPProcessInformation );

  progressReporter.Start();

  /*
   * Read in spatial object file (tubes)
   */
  typename SOReaderType::Pointer soReader = SOReaderType::New();
  soReader->SetFileName( inTubeFile.c_str() );
  soReader->Update();
  typename GroupType::Pointer group = soReader->GetGroup();

  progressReporter.Report(0.1);

  /*
   * Read in ATLAS EMD image
   */
  typename ImageReaderType::Pointer imReader = ImageReaderType::New();
  imReader->SetFileName( inMeanImageFile.c_str() );
  imReader->Update();
  typename ImageType::Pointer meanImage = imReader->GetOutput();

  progressReporter.Report(0.2);

  char childName[] = "Tube";
  typename TubeType::ChildrenListType * tubeList = group->GetChildren(99999, childName);
  typename TubeType::ChildrenListType::const_iterator tubeIt = tubeList->begin();
  TubePointType tubePoint;
  typename TubeTransformType::Pointer tubeTransform;
  std::ofstream writeStream;
  writeStream.open(outFile.c_str(), std::ios::binary | std::ios::out);
  while(tubeIt != tubeList->end()) // Iterate over tubes
    {
    typename TubeType::Pointer tube = dynamic_cast<TubeType *>((*tubeIt).GetPointer());

    tube->RemoveDuplicatePoints();
    tube->ComputeTangentAndNormals();

    itk::Point<double, Dimension> pnt;
    itk::Index< Dimension > indx;
    tube->ComputeObjectToWorldTransform();
    tubeTransform = tube->GetIndexToWorldTransform();
    for( unsigned int i=0; i<tube->GetNumberOfPoints() ; i++)
      {
      tubePoint = static_cast<TubePointType>(tube->GetPoints()[i]); // Get point
      pnt = tubePoint.GetPosition(); // Get point's position
      pnt = tubeTransform->TransformPoint(pnt); // Point coords to physical coords
      meanImage->TransformPhysicalPointToIndex(pnt, indx); // Get closest voxel
      writeStream << meanImage->GetPixel(indx) << std::endl; // Write value of ATLAS EMD file at voxel
      }

    ++tubeIt;
    }
  writeStream.close();

  progressReporter.Report(1.0);
  progressReporter.End();

  return 1;
  }
<|endoftext|>


<commit_before>/**
 * This file is part of the CernVM File System
 */

#include "cvmfs_config.h"
#include "encrypt.h"

#include <fcntl.h>
#include <openssl/evp.h>
#include <openssl/rand.h>

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <ctime>

#include "hash.h"
#include "platform.h"
#include "smalloc.h"
#include "util.h"
#include "util_concurrency.h"

using namespace std;  // NOLINT

namespace cipher {

Key *Key::CreateRandomly(const unsigned size) {
  Key *result = new Key();
  result->size_ = size;
  result->data_ = reinterpret_cast<unsigned char *>(smalloc(size));
  // TODO(jblomer): pin memory in RAM
  int retval = RAND_bytes(result->data_, result->size_);
  if (retval != 1) {
    // Not enough entropy
    delete result;
    result = NULL;
  }
  return result;
}

Key *Key::CreateFromFile(const string &path) {
  int fd = open(path.c_str(), O_RDONLY);
  if (fd < 0)
    return NULL;
  platform_disable_kcache(fd);

  platform_stat64 info;
  int retval = platform_fstat(fd, &info);
  if (retval != 0) {
    close(fd);
    return NULL;
  }
  if ((info.st_size == 0) || (info.st_size > kMaxSize)) {
    close(fd);
    return false;
  }

  Key *result = new Key();
  result->size_ = info.st_size;
  result->data_ = reinterpret_cast<unsigned char *>(smalloc(result->size_));
  int nbytes = read(fd, result->data_, result->size_);
  close(fd);
  if ((nbytes < 0) || (static_cast<unsigned>(nbytes) != result->size_)) {
    delete result;
    result = NULL;
  }
  return result;
}

Key *Key::CreateFromString(const string &key) {
  unsigned size = key.size();
  if ((size == 0) || (size > kMaxSize))
    return NULL;
  UniquePtr<Key> result(new Key());
  result->size_ = size;
  result->data_ = reinterpret_cast<unsigned char *>(smalloc(size));
  memcpy(result->data_, key.data(), size);
  return result.Release();
}

Key::~Key() {
  if (data_) {
    memset(data_, 0, size_);
    free(data_);
  }
}

bool Key::SaveToFile(const std::string &path) {
  int fd = open(path.c_str(), O_WRONLY);
  if (fd < 0)
    return false;
  platform_disable_kcache(fd);

  int nbytes = write(fd, data_, size_);
  close(fd);
  return (nbytes >= 0) && (static_cast<unsigned>(nbytes) == size_);
}

string Key::ToBase64() const {
  return Base64(string(reinterpret_cast<const char *>(data_), size_));
}

//------------------------------------------------------------------------------

MemoryKeyDatabase::MemoryKeyDatabase() {
  lock_ =
    reinterpret_cast<pthread_mutex_t *>(smalloc(sizeof(pthread_mutex_t)));
  int retval = pthread_mutex_init(lock_, NULL);
  assert(retval == 0);
}

MemoryKeyDatabase::~MemoryKeyDatabase() {
  pthread_mutex_destroy(lock_);
  free(lock_);
}

bool MemoryKeyDatabase::StoreNew(const Key *key, string *id) {
  MutexLockGuard mutex_guard(lock_);
  // TODO(jblomer): is this good enough for random keys? Salting? KDF2?
  shash::Any hash(shash::kShake128);
  HashMem(key->data(), key->size(), &hash);
  *id = "H" + hash.ToString();
  map<string, const Key *>::const_iterator i = database_.find(*id);
  if (i != database_.end())
    return false;

  database_[*id] = key;
  return true;
}

const Key *MemoryKeyDatabase::Find(const string &id) {
  MutexLockGuard mutex_guard(lock_);
  map<string, const Key *>::const_iterator i = database_.find(id);
  if (i != database_.end())
    return i->second;
  return NULL;
}

//------------------------------------------------------------------------------

Cipher *Cipher::Create(const Algorithms a) {
  switch (a) {
    case kAes256Cbc:
      return new CipherAes256Cbc();
    case kNone:
      return new CipherNone();
    default:
      abort();
  }
  // Never here
}

bool Cipher::Encrypt(
  const string &plaintext,
  const Key &key,
  string *ciphertext)
{
  ciphertext->clear();
  if (key.size() != key_size())
    return false;

  unsigned char envelope = 0 & 0x0F;
  envelope |= (algorithm() << 4) & 0xF0;
  ciphertext->push_back(envelope);

  *ciphertext += DoEncrypt(plaintext, key);
  return true;
}

bool Cipher::Decrypt(
  const string &ciphertext,
  const Key &key,
  string *plaintext)
{
  plaintext->clear();
  if (ciphertext.size() < 1)
    return false;
  unsigned char envelope = ciphertext[0];
  unsigned char version = envelope & 0x0F;
  if (version != 0)
    return false;
  unsigned char algorithm = (envelope & 0xF0) >> 4;
  if (algorithm > kNone)
    return false;

  UniquePtr<Cipher> cipher(Create(static_cast<Algorithms>(algorithm)));
  if (key.size() != cipher->key_size())
    return false;
  *plaintext += cipher->DoDecrypt(ciphertext.substr(1), key);
  return true;
}

//------------------------------------------------------------------------------

atomic_int64 CipherAes256Cbc::sequence_ = 0;

string CipherAes256Cbc::DoDecrypt(const string &ciphertext, const Key &key) {
  assert(key.size() == kKeySize);
  int retval, retval_2;
  if (ciphertext.size() < kIvSize)
    return "";

  const unsigned char *iv = reinterpret_cast<const unsigned char *>(
    ciphertext.data());

  // See OpenSSL documentation for the size
  unsigned char *plaintext = reinterpret_cast<unsigned char *>(
    smalloc(kBlockSize + ciphertext.size() - kIvSize));
  int plaintext_len;
  int tail_len;
  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init(&ctx);
  retval = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key.data(), iv);
  assert(retval == 1);
  retval = EVP_DecryptUpdate(&ctx,
             plaintext, &plaintext_len,
             reinterpret_cast<const unsigned char *>(
               ciphertext.data() + kIvSize),
             ciphertext.length() - kIvSize);
  if (retval != 1) {
    free(plaintext);
    retval = EVP_CIPHER_CTX_cleanup(&ctx);
    assert(retval == 1);
    return "";
  }
  retval = EVP_DecryptFinal_ex(&ctx, plaintext + plaintext_len, &tail_len);
  retval_2 = EVP_CIPHER_CTX_cleanup(&ctx);
  assert(retval_2 == 1);
  if (retval != 1) {
    free(plaintext);
    return "";
  }

  plaintext_len += tail_len;
  if (plaintext_len == 0) {
    free(plaintext);
    return "";
  }
  string result(reinterpret_cast<char *>(plaintext), plaintext_len);
  free(plaintext);
  return result;
}

string CipherAes256Cbc::DoEncrypt(const string &plaintext, const Key &key) {
  assert(key.size() == kKeySize);
  int retval;

  shash::Md5 md5(GenerateIv(key));
  // iv size happens to be md5 digest size
  unsigned char *iv = md5.digest;

  // See OpenSSL documentation as for the size.  Additionally, we prepend the
  // initialization vector.
  unsigned char *ciphertext = reinterpret_cast<unsigned char *>(
    smalloc(kIvSize + 2 * kBlockSize + plaintext.size()));
  memcpy(ciphertext, iv, kIvSize);
  int cipher_len;
  int tail_len;
  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init(&ctx);
  retval = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key.data(), iv);
  assert(retval == 1);
  retval = EVP_EncryptUpdate(&ctx,
             ciphertext + kIvSize, &cipher_len,
             reinterpret_cast<const unsigned char *>(plaintext.data()),
             plaintext.length());
  assert(retval == 1);
  retval = EVP_EncryptFinal_ex(&ctx, ciphertext + kIvSize + cipher_len,
                               &tail_len);
  assert(retval == 1);
  retval = EVP_CIPHER_CTX_cleanup(&ctx);
  assert(retval == 1);

  cipher_len += tail_len;
  assert(cipher_len > 0);
  string result(reinterpret_cast<char *>(ciphertext), kIvSize + cipher_len);
  free(ciphertext);
  return result;
}

/**
 * The block size of AES-256-CBC happens to be the same of the MD5 digest
 * (128 bits).  Use the HMAC of the key and time + seqno to make it random and
 * unpredictable.
 */
shash::Md5 CipherAes256Cbc::GenerateIv(const Key &key) {
  uint64_t timestamp = time(NULL);
  uint64_t nonce = timestamp + atomic_xadd64(&sequence_, 1);

  shash::Any hmac(shash::kMd5);
  shash::Hmac(string(reinterpret_cast<const char *>(key.data()), key.size()),
              reinterpret_cast<const unsigned char *>(&nonce), sizeof(nonce),
              &hmac);
  return hmac.CastToMd5();
}

//------------------------------------------------------------------------------

string CipherNone::DoDecrypt(const string &ciphertext, const Key &key) {
  return ciphertext;
}

string CipherNone::DoEncrypt(const string &plaintext, const Key &key) {
  return plaintext;
}

}  // namespace cipher
<commit_msg>another fix for the initialization vector<commit_after>/**
 * This file is part of the CernVM File System
 */

#include "cvmfs_config.h"
#include "encrypt.h"

#include <fcntl.h>
#include <openssl/evp.h>
#include <openssl/rand.h>

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <ctime>

#include "hash.h"
#include "platform.h"
#include "smalloc.h"
#include "util.h"
#include "util_concurrency.h"

using namespace std;  // NOLINT

namespace cipher {

Key *Key::CreateRandomly(const unsigned size) {
  Key *result = new Key();
  result->size_ = size;
  result->data_ = reinterpret_cast<unsigned char *>(smalloc(size));
  // TODO(jblomer): pin memory in RAM
  int retval = RAND_bytes(result->data_, result->size_);
  if (retval != 1) {
    // Not enough entropy
    delete result;
    result = NULL;
  }
  return result;
}

Key *Key::CreateFromFile(const string &path) {
  int fd = open(path.c_str(), O_RDONLY);
  if (fd < 0)
    return NULL;
  platform_disable_kcache(fd);

  platform_stat64 info;
  int retval = platform_fstat(fd, &info);
  if (retval != 0) {
    close(fd);
    return NULL;
  }
  if ((info.st_size == 0) || (info.st_size > kMaxSize)) {
    close(fd);
    return false;
  }

  Key *result = new Key();
  result->size_ = info.st_size;
  result->data_ = reinterpret_cast<unsigned char *>(smalloc(result->size_));
  int nbytes = read(fd, result->data_, result->size_);
  close(fd);
  if ((nbytes < 0) || (static_cast<unsigned>(nbytes) != result->size_)) {
    delete result;
    result = NULL;
  }
  return result;
}

Key *Key::CreateFromString(const string &key) {
  unsigned size = key.size();
  if ((size == 0) || (size > kMaxSize))
    return NULL;
  UniquePtr<Key> result(new Key());
  result->size_ = size;
  result->data_ = reinterpret_cast<unsigned char *>(smalloc(size));
  memcpy(result->data_, key.data(), size);
  return result.Release();
}

Key::~Key() {
  if (data_) {
    memset(data_, 0, size_);
    free(data_);
  }
}

bool Key::SaveToFile(const std::string &path) {
  int fd = open(path.c_str(), O_WRONLY);
  if (fd < 0)
    return false;
  platform_disable_kcache(fd);

  int nbytes = write(fd, data_, size_);
  close(fd);
  return (nbytes >= 0) && (static_cast<unsigned>(nbytes) == size_);
}

string Key::ToBase64() const {
  return Base64(string(reinterpret_cast<const char *>(data_), size_));
}

//------------------------------------------------------------------------------

MemoryKeyDatabase::MemoryKeyDatabase() {
  lock_ =
    reinterpret_cast<pthread_mutex_t *>(smalloc(sizeof(pthread_mutex_t)));
  int retval = pthread_mutex_init(lock_, NULL);
  assert(retval == 0);
}

MemoryKeyDatabase::~MemoryKeyDatabase() {
  pthread_mutex_destroy(lock_);
  free(lock_);
}

bool MemoryKeyDatabase::StoreNew(const Key *key, string *id) {
  MutexLockGuard mutex_guard(lock_);
  // TODO(jblomer): is this good enough for random keys? Salting? KDF2?
  shash::Any hash(shash::kShake128);
  HashMem(key->data(), key->size(), &hash);
  *id = "H" + hash.ToString();
  map<string, const Key *>::const_iterator i = database_.find(*id);
  if (i != database_.end())
    return false;

  database_[*id] = key;
  return true;
}

const Key *MemoryKeyDatabase::Find(const string &id) {
  MutexLockGuard mutex_guard(lock_);
  map<string, const Key *>::const_iterator i = database_.find(id);
  if (i != database_.end())
    return i->second;
  return NULL;
}

//------------------------------------------------------------------------------

Cipher *Cipher::Create(const Algorithms a) {
  switch (a) {
    case kAes256Cbc:
      return new CipherAes256Cbc();
    case kNone:
      return new CipherNone();
    default:
      abort();
  }
  // Never here
}

bool Cipher::Encrypt(
  const string &plaintext,
  const Key &key,
  string *ciphertext)
{
  ciphertext->clear();
  if (key.size() != key_size())
    return false;

  unsigned char envelope = 0 & 0x0F;
  envelope |= (algorithm() << 4) & 0xF0;
  ciphertext->push_back(envelope);

  *ciphertext += DoEncrypt(plaintext, key);
  return true;
}

bool Cipher::Decrypt(
  const string &ciphertext,
  const Key &key,
  string *plaintext)
{
  plaintext->clear();
  if (ciphertext.size() < 1)
    return false;
  unsigned char envelope = ciphertext[0];
  unsigned char version = envelope & 0x0F;
  if (version != 0)
    return false;
  unsigned char algorithm = (envelope & 0xF0) >> 4;
  if (algorithm > kNone)
    return false;

  UniquePtr<Cipher> cipher(Create(static_cast<Algorithms>(algorithm)));
  if (key.size() != cipher->key_size())
    return false;
  *plaintext += cipher->DoDecrypt(ciphertext.substr(1), key);
  return true;
}

//------------------------------------------------------------------------------

atomic_int64 CipherAes256Cbc::sequence_ = 0;

string CipherAes256Cbc::DoDecrypt(const string &ciphertext, const Key &key) {
  assert(key.size() == kKeySize);
  int retval, retval_2;
  if (ciphertext.size() < kIvSize)
    return "";

  const unsigned char *iv = reinterpret_cast<const unsigned char *>(
    ciphertext.data());

  // See OpenSSL documentation for the size
  unsigned char *plaintext = reinterpret_cast<unsigned char *>(
    smalloc(kBlockSize + ciphertext.size() - kIvSize));
  int plaintext_len;
  int tail_len;
  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init(&ctx);
  retval = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key.data(), iv);
  assert(retval == 1);
  retval = EVP_DecryptUpdate(&ctx,
             plaintext, &plaintext_len,
             reinterpret_cast<const unsigned char *>(
               ciphertext.data() + kIvSize),
             ciphertext.length() - kIvSize);
  if (retval != 1) {
    free(plaintext);
    retval = EVP_CIPHER_CTX_cleanup(&ctx);
    assert(retval == 1);
    return "";
  }
  retval = EVP_DecryptFinal_ex(&ctx, plaintext + plaintext_len, &tail_len);
  retval_2 = EVP_CIPHER_CTX_cleanup(&ctx);
  assert(retval_2 == 1);
  if (retval != 1) {
    free(plaintext);
    return "";
  }

  plaintext_len += tail_len;
  if (plaintext_len == 0) {
    free(plaintext);
    return "";
  }
  string result(reinterpret_cast<char *>(plaintext), plaintext_len);
  free(plaintext);
  return result;
}

string CipherAes256Cbc::DoEncrypt(const string &plaintext, const Key &key) {
  assert(key.size() == kKeySize);
  int retval;

  shash::Md5 md5(GenerateIv(key));
  // iv size happens to be md5 digest size
  unsigned char *iv = md5.digest;

  // See OpenSSL documentation as for the size.  Additionally, we prepend the
  // initialization vector.
  unsigned char *ciphertext = reinterpret_cast<unsigned char *>(
    smalloc(kIvSize + 2 * kBlockSize + plaintext.size()));
  memcpy(ciphertext, iv, kIvSize);
  int cipher_len;
  int tail_len;
  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init(&ctx);
  retval = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key.data(), iv);
  assert(retval == 1);
  retval = EVP_EncryptUpdate(&ctx,
             ciphertext + kIvSize, &cipher_len,
             reinterpret_cast<const unsigned char *>(plaintext.data()),
             plaintext.length());
  assert(retval == 1);
  retval = EVP_EncryptFinal_ex(&ctx, ciphertext + kIvSize + cipher_len,
                               &tail_len);
  assert(retval == 1);
  retval = EVP_CIPHER_CTX_cleanup(&ctx);
  assert(retval == 1);

  cipher_len += tail_len;
  assert(cipher_len > 0);
  string result(reinterpret_cast<char *>(ciphertext), kIvSize + cipher_len);
  free(ciphertext);
  return result;
}

/**
 * The block size of AES-256-CBC happens to be the same of the MD5 digest
 * (128 bits).  Use the HMAC of the key and time + seqno to make it random and
 * unpredictable.
 */
shash::Md5 CipherAes256Cbc::GenerateIv(const Key &key) {
  uint64_t now = time(NULL);
  struct {
    uint64_t timestamp;
    uint64_t seq;
  } nonce;
  nonce.timestamp = now;
  nonce.seq = atomic_xadd64(&sequence_, 1);

  shash::Any hmac(shash::kMd5);
  shash::Hmac(string(reinterpret_cast<const char *>(key.data()), key.size()),
              reinterpret_cast<const unsigned char *>(&nonce), sizeof(nonce),
              &hmac);
  return hmac.CastToMd5();
}

//------------------------------------------------------------------------------

string CipherNone::DoDecrypt(const string &ciphertext, const Key &key) {
  return ciphertext;
}

string CipherNone::DoEncrypt(const string &plaintext, const Key &key) {
  return plaintext;
}

}  // namespace cipher
<|endoftext|>


<commit_before><commit_msg>Use offapi constants instead of hardcoded magic constant<commit_after><|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2009 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
#endif

#include "Application.h"
#include "Document.h"
#include "DocumentObject.h"
#include "DocumentObserverPython.h"
#include <Base/Interpreter.h>
#include <Base/Console.h>

using namespace App;

std::vector<DocumentObserverPython*> DocumentObserverPython::_instances;

void DocumentObserverPython::addObserver(const Py::Object& obj)
{
    _instances.push_back(new DocumentObserverPython(obj));
}

void DocumentObserverPython::removeObserver(const Py::Object& obj)
{
    DocumentObserverPython* obs=0;
    for (std::vector<DocumentObserverPython*>::iterator it =
        _instances.begin(); it != _instances.end(); ++it) {
        if ((*it)->inst == obj) {
            obs = *it;
            _instances.erase(it);
            break;
        }
    }

    delete obs;
}

DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) : inst(obj)
{
    this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(boost::bind
        (&DocumentObserverPython::slotCreatedDocument, this, _1));
    this->connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind
        (&DocumentObserverPython::slotDeletedDocument, this, _1));
    this->connectApplicationRelabelDocument = App::GetApplication().signalRelabelDocument.connect(boost::bind
        (&DocumentObserverPython::slotRelabelDocument, this, _1));
    this->connectApplicationActivateDocument = App::GetApplication().signalActiveDocument.connect(boost::bind
        (&DocumentObserverPython::slotActivateDocument, this, _1));
    this->connectApplicationUndoDocument = App::GetApplication().signalUndoDocument.connect(boost::bind
        (&DocumentObserverPython::slotUndoDocument, this, _1));
    this->connectApplicationRedoDocument = App::GetApplication().signalRedoDocument.connect(boost::bind
        (&DocumentObserverPython::slotRedoDocument, this, _1));

    this->connectDocumentCreatedObject = App::GetApplication().signalNewObject.connect(boost::bind
        (&DocumentObserverPython::slotCreatedObject, this, _1));
    this->connectDocumentDeletedObject = App::GetApplication().signalDeletedObject.connect(boost::bind
        (&DocumentObserverPython::slotDeletedObject, this, _1));
    this->connectDocumentChangedObject = App::GetApplication().signalChangedObject.connect(boost::bind
        (&DocumentObserverPython::slotChangedObject, this, _1, _2));
}

DocumentObserverPython::~DocumentObserverPython()
{
    this->connectApplicationCreatedDocument.disconnect();
    this->connectApplicationDeletedDocument.disconnect();
    this->connectApplicationRelabelDocument.disconnect();
    this->connectApplicationActivateDocument.disconnect();
    this->connectApplicationUndoDocument.disconnect();
    this->connectApplicationRedoDocument.disconnect();

    this->connectDocumentCreatedObject.disconnect();
    this->connectDocumentDeletedObject.disconnect();
    this->connectDocumentChangedObject.disconnect();
}

void DocumentObserverPython::slotCreatedDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotCreatedDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotCreatedDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotDeletedDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotDeletedDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotDeletedDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotRelabelDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotRelabelDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotRelabelDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotActivateDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotActivateDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotActivateDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotUndoDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotUndoDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotUndoDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotRedoDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotRedoDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotRedoDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotCreatedObject(const App::DocumentObject& Obj)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotCreatedObject"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotCreatedObject")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::DocumentObject&>(Obj).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotDeletedObject(const App::DocumentObject& Obj)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotDeletedObject"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotDeletedObject")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::DocumentObject&>(Obj).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotChangedObject(const App::DocumentObject& Obj,
                                               const App::Property& Prop)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotChangedObject"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotChangedObject")));
            Py::Tuple args(2);
            args.setItem(0, Py::Object(const_cast<App::DocumentObject&>(Obj).getPyObject(), true));
            std::string prop_name = Obj.getPropertyName(&Prop);
            args.setItem(1, Py::String(prop_name));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}
<commit_msg>+ fix crash in DocumentObserverPython if a property has no name (because it's not part of an object)<commit_after>/***************************************************************************
 *   Copyright (c) 2009 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
#endif

#include "Application.h"
#include "Document.h"
#include "DocumentObject.h"
#include "DocumentObserverPython.h"
#include <Base/Interpreter.h>
#include <Base/Console.h>

using namespace App;

std::vector<DocumentObserverPython*> DocumentObserverPython::_instances;

void DocumentObserverPython::addObserver(const Py::Object& obj)
{
    _instances.push_back(new DocumentObserverPython(obj));
}

void DocumentObserverPython::removeObserver(const Py::Object& obj)
{
    DocumentObserverPython* obs=0;
    for (std::vector<DocumentObserverPython*>::iterator it =
        _instances.begin(); it != _instances.end(); ++it) {
        if ((*it)->inst == obj) {
            obs = *it;
            _instances.erase(it);
            break;
        }
    }

    delete obs;
}

DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) : inst(obj)
{
    this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(boost::bind
        (&DocumentObserverPython::slotCreatedDocument, this, _1));
    this->connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind
        (&DocumentObserverPython::slotDeletedDocument, this, _1));
    this->connectApplicationRelabelDocument = App::GetApplication().signalRelabelDocument.connect(boost::bind
        (&DocumentObserverPython::slotRelabelDocument, this, _1));
    this->connectApplicationActivateDocument = App::GetApplication().signalActiveDocument.connect(boost::bind
        (&DocumentObserverPython::slotActivateDocument, this, _1));
    this->connectApplicationUndoDocument = App::GetApplication().signalUndoDocument.connect(boost::bind
        (&DocumentObserverPython::slotUndoDocument, this, _1));
    this->connectApplicationRedoDocument = App::GetApplication().signalRedoDocument.connect(boost::bind
        (&DocumentObserverPython::slotRedoDocument, this, _1));

    this->connectDocumentCreatedObject = App::GetApplication().signalNewObject.connect(boost::bind
        (&DocumentObserverPython::slotCreatedObject, this, _1));
    this->connectDocumentDeletedObject = App::GetApplication().signalDeletedObject.connect(boost::bind
        (&DocumentObserverPython::slotDeletedObject, this, _1));
    this->connectDocumentChangedObject = App::GetApplication().signalChangedObject.connect(boost::bind
        (&DocumentObserverPython::slotChangedObject, this, _1, _2));
}

DocumentObserverPython::~DocumentObserverPython()
{
    this->connectApplicationCreatedDocument.disconnect();
    this->connectApplicationDeletedDocument.disconnect();
    this->connectApplicationRelabelDocument.disconnect();
    this->connectApplicationActivateDocument.disconnect();
    this->connectApplicationUndoDocument.disconnect();
    this->connectApplicationRedoDocument.disconnect();

    this->connectDocumentCreatedObject.disconnect();
    this->connectDocumentDeletedObject.disconnect();
    this->connectDocumentChangedObject.disconnect();
}

void DocumentObserverPython::slotCreatedDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotCreatedDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotCreatedDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotDeletedDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotDeletedDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotDeletedDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotRelabelDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotRelabelDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotRelabelDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotActivateDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotActivateDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotActivateDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotUndoDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotUndoDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotUndoDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotRedoDocument(const App::Document& Doc)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotRedoDocument"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotRedoDocument")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::Document&>(Doc).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotCreatedObject(const App::DocumentObject& Obj)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotCreatedObject"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotCreatedObject")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::DocumentObject&>(Obj).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotDeletedObject(const App::DocumentObject& Obj)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotDeletedObject"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotDeletedObject")));
            Py::Tuple args(1);
            args.setItem(0, Py::Object(const_cast<App::DocumentObject&>(Obj).getPyObject(), true));
            method.apply(args);
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}

void DocumentObserverPython::slotChangedObject(const App::DocumentObject& Obj,
                                               const App::Property& Prop)
{
    Base::PyGILStateLocker lock;
    try {
        if (this->inst.hasAttr(std::string("slotChangedObject"))) {
            Py::Callable method(this->inst.getAttr(std::string("slotChangedObject")));
            Py::Tuple args(2);
            args.setItem(0, Py::Object(const_cast<App::DocumentObject&>(Obj).getPyObject(), true));
            // If a property is touched but not part of a document object then its name is null.
            // In this case the slot function must not be called.
            const char* prop_name = Obj.getPropertyName(&Prop);
            if (prop_name) {
                args.setItem(1, Py::String(prop_name));
                method.apply(args);
            }
        }
    }
    catch (Py::Exception&) {
        Base::PyException e; // extract the Python error text
        e.ReportException();
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include "Myexception.h"
#include "chain.h"

using namespace std;

void chain :: readAndStoreFromFile(char* fileName)
{
	//This function reads integers from the file given by fileName then store them in the chain

	std::ifstream data(filename);
	std::string line;

	while(std::getline(data,line))
		td::stringstream    str(line);
		td::string          text;

		td::getline(str,text,'=');

		double   value;
		tr >> value;
	}

}

void chain :: eraseModuloValue(int theInt)
{
	//This function erases all the entries from the list which are multiple of theInt

}

void chain :: oddAndEvenOrdering()
{
	//This function reorders the list such a way that all odd numbers precede all even numbers.
	//Note that for two odd (even) numbers i and j, the ordering between i and j should be intact after reordering.

}

void chain :: reverse()
{
	//Reverses the list

}

chain :: chain(int initialCapacity)
{
	//Constructor
	if(initialCapacity < 1)
	{
		ostringstream s;
		s << "Initial capacity = " << initialCapacity << " Must be > 0";
		throw illegalParameterValue(s.str());
	}

	firstNode = NULL;
	listSize = 0;

}

chain :: ~chain()
{
	//Destructor. Delete all nodes in chain

	while(firstNode != NULL)
	{
		//delete firstNode
		chainNode* nextNode = firstNode->next;
		delete firstNode;
		firstNode = nextNode;

	}

}

int* chain :: get(int theIndex) const
{
	//Return element whose index is theIndex.
	//Throw illegalIndex exception if no such element.
	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return NULL;
	}

	chainNode* currentNode = firstNode;
	for(int i=0;i<theIndex;i++)
		currentNode = currentNode->next;

	return &currentNode->element;

}

int chain :: indexOf(const int& theElement) const
{
	//Return index of first occurrence of theElement.
	//Return -1 of theElement not in list.

	chainNode* currentNode = firstNode;
	int index = 0;
	while(currentNode != NULL && currentNode->element != theElement)
	{
		//move to the next node
		currentNode = currentNode->next;
		index++;

	}

	//make sure we found matching element
	if(currentNode == NULL)
		return -1;

	else
		return index;

}

void chain :: erase(int theIndex)
{
	//Delete the element whose index is theIndex.
	//Throw illegalIndex exception if no such element.

	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	chainNode* deleteNode;
	if(theIndex == 0)
	{
		//remove first node from chain
		deleteNode = firstNode;
		firstNode = firstNode->next;

	}
	else
	{
		//use p to get to predecessor of desired node
		chainNode* p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		deleteNode = p->next;
		p->next = p->next->next; //remove deleteNode from chain

	}

	listSize--;
	delete deleteNode;

}

void chain :: insert(int theIndex, const int& theElement)
{
	//Insert theElement so that its index is theIndex.
	try{
   		if (theIndex < 0 || theIndex > listSize)
   		{// invalid index

			ostringstream s;
    			s << "index = " << theIndex << " size = " << listSize;
    			throw illegalIndex(s.str());
		}
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	if(theIndex == 0)
		//insert at front
		firstNode = new chainNode(theElement, firstNode);
	else
	{
		chainNode *p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		//insert after p
		p->next = new chainNode(theElement, p->next);

	}

	listSize++;

}

void chain :: output() const
{
	//Put the list into the output.

	for(int i=0;i<listSize;i++)
		cout << *this->get(i) << " ";
	cout<<endl;

}

void chain::checkIndex(int theIndex) const
{
// Verify that theIndex is between 0 and
 // listSize - 1.

   	if (theIndex < 0 || theIndex >= listSize){
		ostringstream s;
    		s << "index = " << theIndex << " size = "
                    << listSize<<", the input index is invalid";
    		throw illegalIndex(s.str());
	}

}
<commit_msg>Update chain.cpp<commit_after>#include <iostream>
#include <sstream>
#include "Myexception.h"
#include "chain.h"

using namespace std;

void chain :: readAndStoreFromFile(char* fileName)
{
	//This function reads integers from the file given by fileName then store them in the chain

	ifstream in;
	in.open(filename.c_str());
	if (!in) return; // file doesn't exist

	int line;
	while(getline(in, line)) {
		insert(1, line);
	}

	/*int line;

	while(std::getline(data, line))
		std::stringstream str(line);
		std::string text;

		std::getline(str,text,'=');

		double value;
		str >> value;
	}*/

}

void chain :: eraseModuloValue(int theInt)
{
	//This function erases all the entries from the list which are multiple of theInt

}

void chain :: oddAndEvenOrdering()
{
	//This function reorders the list such a way that all odd numbers precede all even numbers.
	//Note that for two odd (even) numbers i and j, the ordering between i and j should be intact after reordering.

}

void chain :: reverse()
{
	//Reverses the list

}

chain :: chain(int initialCapacity)
{
	//Constructor
	if(initialCapacity < 1)
	{
		ostringstream s;
		s << "Initial capacity = " << initialCapacity << " Must be > 0";
		throw illegalParameterValue(s.str());
	}

	firstNode = NULL;
	listSize = 0;

}

chain :: ~chain()
{
	//Destructor. Delete all nodes in chain

	while(firstNode != NULL)
	{
		//delete firstNode
		chainNode* nextNode = firstNode->next;
		delete firstNode;
		firstNode = nextNode;

	}

}

int* chain :: get(int theIndex) const
{
	//Return element whose index is theIndex.
	//Throw illegalIndex exception if no such element.
	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return NULL;
	}

	chainNode* currentNode = firstNode;
	for(int i=0;i<theIndex;i++)
		currentNode = currentNode->next;

	return &currentNode->element;

}

int chain :: indexOf(const int& theElement) const
{
	//Return index of first occurrence of theElement.
	//Return -1 of theElement not in list.

	chainNode* currentNode = firstNode;
	int index = 0;
	while(currentNode != NULL && currentNode->element != theElement)
	{
		//move to the next node
		currentNode = currentNode->next;
		index++;

	}

	//make sure we found matching element
	if(currentNode == NULL)
		return -1;

	else
		return index;

}

void chain :: erase(int theIndex)
{
	//Delete the element whose index is theIndex.
	//Throw illegalIndex exception if no such element.

	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	chainNode* deleteNode;
	if(theIndex == 0)
	{
		//remove first node from chain
		deleteNode = firstNode;
		firstNode = firstNode->next;

	}
	else
	{
		//use p to get to predecessor of desired node
		chainNode* p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		deleteNode = p->next;
		p->next = p->next->next; //remove deleteNode from chain

	}

	listSize--;
	delete deleteNode;

}

void chain :: insert(int theIndex, const int& theElement)
{
	//Insert theElement so that its index is theIndex.
	try{
   		if (theIndex < 0 || theIndex > listSize)
   		{// invalid index

			ostringstream s;
    			s << "index = " << theIndex << " size = " << listSize;
    			throw illegalIndex(s.str());
		}
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	if(theIndex == 0)
		//insert at front
		firstNode = new chainNode(theElement, firstNode);
	else
	{
		chainNode *p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		//insert after p
		p->next = new chainNode(theElement, p->next);

	}

	listSize++;

}

void chain :: output() const
{
	//Put the list into the output.

	for(int i=0;i<listSize;i++)
		cout << *this->get(i) << " ";
	cout<<endl;

}

void chain::checkIndex(int theIndex) const
{
// Verify that theIndex is between 0 and
 // listSize - 1.

   	if (theIndex < 0 || theIndex >= listSize){
		ostringstream s;
    		s << "index = " << theIndex << " size = "
                    << listSize<<", the input index is invalid";
    		throw illegalIndex(s.str());
	}

}
<|endoftext|>