<commit_before>/**
 *  @file seriesClassification.cpp
 *  RapidLib
 *
 *  @author Michael Zbyszynski
 *  @date 08 Jun 2017
 *  @copyright Copyright © 2017 Goldsmiths. All rights reserved.
 */

#include <vector>
#include <cassert>
#include "seriesClassification.h"
#ifdef EMSCRIPTEN
#include "emscripten/seriesClassificationEmbindings.h"
#endif

#define SEARCH_RADIUS 1

template<typename T>
seriesClassificationTemplate<T>::seriesClassificationTemplate() : hopSize(1), counter(0) {};

template<typename T>
seriesClassificationTemplate<T>::~seriesClassificationTemplate() {};

template<typename T>
bool seriesClassificationTemplate<T>::train(const std::vector<trainingSeriesTemplate<T> > &seriesSet) {
    assert(seriesSet.size() > 0);
    reset();
    vectorLength = int(seriesSet[0].input[0].size()); //TODO: check that all vectors are the same size
    bool trained = true;
    allTrainingSeries = seriesSet;
    minLength = maxLength = int(allTrainingSeries[0].input.size());
    for (int i = 0; i < allTrainingSeries.size(); ++i) {
        //for (auto trainingSeries : allTrainingSeries)
        //Global
        int newLength = int(allTrainingSeries[i].input.size());
        if (newLength < minLength) {
            minLength = newLength;
        }
        if (newLength > maxLength) {
            maxLength = newLength;
        }
        //Per Label
        typename std::map<std::string, minMax<int> >::iterator it = lengthsPerLabel.find(allTrainingSeries[i].label);
        if (it != lengthsPerLabel.end()) {
            int newLength = int(allTrainingSeries[i].input.size());
            if (newLength < it->second.min) {
                it->second.min = newLength;
            }
            if (newLength > it->second.max) {
                it->second.max = newLength;
            }
        } else {
            minMax<int> tempLengths;
            tempLengths.min = tempLengths.max = int(allTrainingSeries[i].input.size());
            lengthsPerLabel[allTrainingSeries[i].label] = tempLengths;
        }
    }
    //TODO: make this size smarter?
    std::vector<T> zeroVector;
    for (int i = 0; i < vectorLength; ++i) {
        zeroVector.push_back(0.0);
    }
    for (int i = 0; i < minLength; ++i ) {
        seriesBuffer.push_back(zeroVector); //set size of continuous buffer
    }
    return trained;
};

template<typename T>
void seriesClassificationTemplate<T>::reset() {
    allCosts.clear();
    allTrainingSeries.clear();
    lengthsPerLabel.clear();
    minLength = -1;
    maxLength = -1;
}

template<typename T>
std::string seriesClassificationTemplate<T>::run(const std::vector<std::vector<T>> &inputSeries) {
    //TODO: Check to see if trained
    int closestSeries = 0;
    allCosts.clear();
    T lowestCost = fastDTW<T>::getCost(inputSeries, allTrainingSeries[0].input, SEARCH_RADIUS);
    allCosts.push_back(lowestCost);

    for (int i = 1; i < allTrainingSeries.size(); ++i) {
        T currentCost = fastDTW<T>::getCost(inputSeries, allTrainingSeries[i].input, SEARCH_RADIUS);
        allCosts.push_back(currentCost);
        if (currentCost < lowestCost) {
            lowestCost = currentCost;
            closestSeries = i;
        }
    }
    return allTrainingSeries[closestSeries].label;
};

template<typename T>
T seriesClassificationTemplate<T>::run(const std::vector<std::vector<T>> &inputSeries, std::string label) {
    //TODO: Check to see if trained
    int closestSeries = 0;
    allCosts.clear();
    T lowestCost = std::numeric_limits<T>::max();
    for (int i = 0; i < allTrainingSeries.size(); ++i) {
        if (allTrainingSeries[i].label == label) {
            T currentCost = fastDTW<T>::getCost(inputSeries, allTrainingSeries[i].input, SEARCH_RADIUS);
            allCosts.push_back(currentCost);
            if (currentCost < lowestCost) {
                lowestCost = currentCost;
                closestSeries = i;
            }
        }
    }
    return lowestCost;
};

template<typename T>
std::string seriesClassificationTemplate<T>::runContinuous(const std::vector<T> &inputVector) {
    seriesBuffer.erase(seriesBuffer.begin());
    seriesBuffer.push_back(inputVector);
    std::string returnString = "none";
    if ((counter % hopSize) == 0 ) {
        returnString = run(seriesBuffer);
        counter = 0;
    }
    ++counter;
    return returnString;
}

template<typename T>
std::vector<T> seriesClassificationTemplate<T>::getCosts() const{
    return allCosts;
}

template<typename T>
int seriesClassificationTemplate<T>::getMinLength() const{
    return minLength;
}

template<typename T>
int seriesClassificationTemplate<T>::getMinLength(std::string label) const {
    int labelMinLength = -1;
    typename std::map<std::string, minMax<int> >::const_iterator it = lengthsPerLabel.find(label);
    if (it != lengthsPerLabel.end()) {
        labelMinLength = it->second.min;
    }
    return labelMinLength;
}

template<typename T>
int seriesClassificationTemplate<T>::getMaxLength() const {
    return maxLength;
}

template<typename T>
int seriesClassificationTemplate<T>::getMaxLength(std::string label) const {
    int labelMaxLength = -1;
    typename std::map<std::string, minMax<int> >::const_iterator it = lengthsPerLabel.find(label);
    if (it != lengthsPerLabel.end()) {
        labelMaxLength = it->second.max;
    }
    return labelMaxLength;
}

template<typename T>
seriesClassificationTemplate<T>::minMax<T> seriesClassificationTemplate<T>::calculateCosts(std::string label) const {
    minMax<T> calculatedMinMax;
    bool foundSeries = false;
    std::vector<T> labelCosts;
    for (int i = 0; i < (allTrainingSeries.size() - 1); ++i) { //these loops are a little different than the two-label case
        if (allTrainingSeries[i].label == label) {
            foundSeries = true;
            for (int j = (i + 1); j < allTrainingSeries.size(); ++j) {
                if (allTrainingSeries[j].label == label) {
                    labelCosts.push_back(fastDTW<T>::getCost(allTrainingSeries[i].input, allTrainingSeries[j].input, SEARCH_RADIUS));
                }
            }
        }
    }
    if (foundSeries) {
        auto minmax_result = std::minmax_element(std::begin(labelCosts), std::end(labelCosts));
        calculatedMinMax.min = *minmax_result.first;
        calculatedMinMax.max = *minmax_result.second;
    } else {
        calculatedMinMax.min = calculatedMinMax.max = 0;
    }
    return calculatedMinMax;
}

template<typename T>
seriesClassificationTemplate<T>::minMax<T> seriesClassificationTemplate<T>::calculateCosts(std::string label1, std::string label2) const {
    minMax<T> calculatedMinMax;
    bool foundSeries = false;
    std::vector<T> labelCosts;
    for (int i = 0; i < (allTrainingSeries.size()); ++i) {
        if (allTrainingSeries[i].label == label1) {
            for (int j = 0; j < allTrainingSeries.size(); ++j) {
                if (allTrainingSeries[j].label == label2) {
                    foundSeries = true;
                    labelCosts.push_back(fastDTW<T>::getCost(allTrainingSeries[i].input, allTrainingSeries[j].input, SEARCH_RADIUS));
                }
            }
        }
    }
    if (foundSeries) {
        auto minmax_result = std::minmax_element(std::begin(labelCosts), std::end(labelCosts));
        calculatedMinMax.min = *minmax_result.first;
        calculatedMinMax.max = *minmax_result.second;
    } else {
        calculatedMinMax.min = calculatedMinMax.max = 0;
    }
    return calculatedMinMax;
}

//explicit instantiation
template class seriesClassificationTemplate<double>;
template class seriesClassificationTemplate<float>;

//
//std::vector<T> seriesClassification::getCosts(const std::vector<trainingExample> &trainingSet) {
//    run(trainingSet);
//    return allCosts;
//}
<commit_msg>silly typo<commit_after>/**
 *  @file seriesClassification.cpp
 *  RapidLib
 *
 *  @author Michael Zbyszynski
 *  @date 08 Jun 2017
 *  @copyright Copyright © 2017 Goldsmiths. All rights reserved.
 */

#include <vector>
#include <cassert>
#include "seriesClassification.h"
#ifdef EMSCRIPTEN
#include "emscripten/seriesClassificationEmbindings.h"
#endif

#define SEARCH_RADIUS 1

template<typename T>
seriesClassificationTemplate<T>::seriesClassificationTemplate() : hopSize(1), counter(0) {};

template<typename T>
seriesClassificationTemplate<T>::~seriesClassificationTemplate() {};

template<typename T>
bool seriesClassificationTemplate<T>::train(const std::vector<trainingSeriesTemplate<T> > &seriesSet) {
    assert(seriesSet.size() > 0);
    reset();
    vectorLength = int(seriesSet[0].input[0].size()); //TODO: check that all vectors are the same size
    bool trained = true;
    allTrainingSeries = seriesSet;
    minLength = maxLength = int(allTrainingSeries[0].input.size());
    for (int i = 0; i < allTrainingSeries.size(); ++i) {
        //for (auto trainingSeries : allTrainingSeries)
        //Global
        int newLength = int(allTrainingSeries[i].input.size());
        if (newLength < minLength) {
            minLength = newLength;
        }
        if (newLength > maxLength) {
            maxLength = newLength;
        }
        //Per Label
        typename std::map<std::string, minMax<int> >::iterator it = lengthsPerLabel.find(allTrainingSeries[i].label);
        if (it != lengthsPerLabel.end()) {
            int newLength = int(allTrainingSeries[i].input.size());
            if (newLength < it->second.min) {
                it->second.min = newLength;
            }
            if (newLength > it->second.max) {
                it->second.max = newLength;
            }
        } else {
            minMax<int> tempLengths;
            tempLengths.min = tempLengths.max = int(allTrainingSeries[i].input.size());
            lengthsPerLabel[allTrainingSeries[i].label] = tempLengths;
        }
    }
    //TODO: make this size smarter?
    std::vector<T> zeroVector;
    for (int i = 0; i < vectorLength; ++i) {
        zeroVector.push_back(0.0);
    }
    for (int i = 0; i < minLength; ++i ) {
        seriesBuffer.push_back(zeroVector); //set size of continuous buffer
    }
    return trained;
};

template<typename T>
void seriesClassificationTemplate<T>::reset() {
    allCosts.clear();
    allTrainingSeries.clear();
    lengthsPerLabel.clear();
    minLength = -1;
    maxLength = -1;
}

template<typename T>
std::string seriesClassificationTemplate<T>::run(const std::vector<std::vector<T>> &inputSeries) {
    //TODO: Check to see if trained
    int closestSeries = 0;
    allCosts.clear();
    T lowestCost = fastDTW<T>::getCost(inputSeries, allTrainingSeries[0].input, SEARCH_RADIUS);
    allCosts.push_back(lowestCost);

    for (int i = 1; i < allTrainingSeries.size(); ++i) {
        T currentCost = fastDTW<T>::getCost(inputSeries, allTrainingSeries[i].input, SEARCH_RADIUS);
        allCosts.push_back(currentCost);
        if (currentCost < lowestCost) {
            lowestCost = currentCost;
            closestSeries = i;
        }
    }
    return allTrainingSeries[closestSeries].label;
};

template<typename T>
T seriesClassificationTemplate<T>::run(const std::vector<std::vector<T>> &inputSeries, std::string label) {
    //TODO: Check to see if trained
    int closestSeries = 0;
    allCosts.clear();
    T lowestCost = std::numeric_limits<T>::max();
    for (int i = 0; i < allTrainingSeries.size(); ++i) {
        if (allTrainingSeries[i].label == label) {
            T currentCost = fastDTW<T>::getCost(inputSeries, allTrainingSeries[i].input, SEARCH_RADIUS);
            allCosts.push_back(currentCost);
            if (currentCost < lowestCost) {
                lowestCost = currentCost;
                closestSeries = i;
            }
        }
    }
    return lowestCost;
};

template<typename T>
std::string seriesClassificationTemplate<T>::runContinuous(const std::vector<T> &inputVector) {
    seriesBuffer.erase(seriesBuffer.begin());
    seriesBuffer.push_back(inputVector);
    std::string returnString = "none";
    if ((counter % hopSize) == 0 ) {
        returnString = run(seriesBuffer);
        counter = 0;
    }
    ++counter;
    return returnString;
}

template<typename T>
std::vector<T> seriesClassificationTemplate<T>::getCosts() const{
    return allCosts;
}

template<typename T>
int seriesClassificationTemplate<T>::getMinLength() const{
    return minLength;
}

template<typename T>
int seriesClassificationTemplate<T>::getMinLength(std::string label) const {
    int labelMinLength = -1;
    typename std::map<std::string, minMax<int> >::const_iterator it = lengthsPerLabel.find(label);
    if (it != lengthsPerLabel.end()) {
        labelMinLength = it->second.min;
    }
    return labelMinLength;
}

template<typename T>
int seriesClassificationTemplate<T>::getMaxLength() const {
    return maxLength;
}

template<typename T>
int seriesClassificationTemplate<T>::getMaxLength(std::string label) const {
    int labelMaxLength = -1;
    typename std::map<std::string, minMax<int> >::const_iterator it = lengthsPerLabel.find(label);
    if (it != lengthsPerLabel.end()) {
        labelMaxLength = it->second.max;
    }
    return labelMaxLength;
}

template<typename T>
seriesClassificationTemplate<T>::minMax<T> seriesClassificationTemplate<T>::calculateCosts(std::string label) const {
    minMax<T> calculatedMinMax;
    bool foundSeries = false;
    std::vector<T> labelCosts;
    for (int i = 0; i < (allTrainingSeries.size() - 1); ++i) { //these loops are a little different than the two-label case
        if (allTrainingSeries[i].label == label) {
            foundSeries = true;
            for (int j = (i + 1); j < allTrainingSeries.size(); ++j) {
                if (allTrainingSeries[j].label == label) {
                    labelCosts.push_back(fastDTW<T>::getCost(allTrainingSeries[i].input, allTrainingSeries[j].input, SEARCH_RADIUS));
                }
            }
        }
    }
    if (foundSeries) {
        auto minmax_result = std::minmax_element(std::begin(labelCosts), std::end(labelCosts));
        calculatedMinMax.min = *minmax_result.first;
        calculatedMinMax.max = *minmax_result.second;
    } else {
        calculatedMinMax.min = calculatedMinMax.max = 0;
    }
    return calculatedMinMax;
}

template<typename T>
seriesClassificationTemplate<T>::minMax<T> seriesClassificationTemplate<T>::calculateCosts(std::string label1, std::string label2) const {
    minMax<T> calculatedMinMax;
    bool foundSeries = false;
    std::vector<T> labelCosts;
    for (int i = 0; i < (allTrainingSeries.size()); ++i) {
        if (allTrainingSeries[i].label == label1) {
            for (int j = 0; j < allTrainingSeries.size(); ++j) {
                if (allTrainingSeries[j].label == label2) {
                    foundSeries = true;
                    labelCosts.push_back(fastDTW<T>::getCost(allTrainingSeries[i].input, allTrainingSeries[j].input, SEARCH_RADIUS));
                }
            }
        }
    }
    if (foundSeries) {
        auto minmax_result = std::minmax_element(std::begin(labelCosts), std::end(labelCosts));
        calculatedMinMax.min = *minmax_result.first;
        calculatedMinMax.max = *minmax_result.second;
    } else {
        calculatedMinMax.min = calculatedMinMax.max = 0;
    }
    return calculatedMinMax;
}

//explicit instantiation
template class seriesClassificationTemplate<double>;
template class seriesClassificationTemplate<float>;

//
//std::vector<T> seriesClassification::getCosts(const std::vector<trainingExample> &trainingSet) {
//    run(trainingSet);
//    return allCosts;
//}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Facebook, Inc.
 *
 * 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 <map>
#include <string>
#include <tuple>
#include <vector>

#include <llvm/DebugInfo/DWARF/DWARFContext.h>
#include <llvm/DebugInfo/DWARF/DWARFDebugLine.h>
#include <llvm/IR/Module.h>
#include <llvm/MC/MCAsmInfo.h>
#include <llvm/MC/MCContext.h>
#include <llvm/MC/MCDisassembler/MCDisassembler.h>
#include <llvm/MC/MCInstPrinter.h>
#include <llvm/MC/MCInstrInfo.h>
#include <llvm/MC/MCObjectFileInfo.h>
#include <llvm/MC/MCRegisterInfo.h>
#include <llvm/Support/TargetRegistry.h>

#include "bcc_debug.h"

namespace ebpf {

// ld_pseudo can only be disassembled properly
// in llvm 6.0, so having this workaround now
// until disto llvm versions catch up
#define WORKAROUND_FOR_LD_PSEUDO

using std::get;
using std::map;
using std::string;
using std::tuple;
using std::vector;
using namespace llvm;
using DWARFLineTable = DWARFDebugLine::LineTable;

void SourceDebugger::adjustInstSize(uint64_t &Size, uint8_t byte0,
                                    uint8_t byte1) {
#ifdef WORKAROUND_FOR_LD_PSEUDO
  bool isLittleEndian = mod_->getDataLayout().isLittleEndian();
  if (byte0 == 0x18 && ((isLittleEndian && (byte1 & 0xf) == 0x1) ||
                        (!isLittleEndian && (byte1 & 0xf0) == 0x10)))
    Size = 16;
#endif
}

vector<string> SourceDebugger::buildLineCache() {
  vector<string> LineCache;
  size_t FileBufSize = mod_src_.size();

  for (uint32_t start = 0, end = start; end < FileBufSize; end++)
    if (mod_src_[end] == '\n' || end == FileBufSize - 1 ||
        (mod_src_[end] == '\r' && mod_src_[end + 1] == '\n')) {
      // Not including the endline
      LineCache.push_back(string(mod_src_.substr(start, end - start)));
      if (mod_src_[end] == '\r')
        end++;
      start = end + 1;
    }

  return LineCache;
}

void SourceDebugger::dumpSrcLine(const vector<string> &LineCache,
                                 const string &FileName, uint32_t Line,
                                 uint32_t &CurrentSrcLine,
                                 llvm::raw_ostream &os) {
  if (Line != 0 && Line != CurrentSrcLine && Line < LineCache.size() &&
      FileName == mod_->getSourceFileName()) {
    os << "; " << StringRef(LineCache[Line - 1]).ltrim()
       << format(
              " // Line"
              "%4" PRIu64 "\n",
              Line);
    CurrentSrcLine = Line;
  }
}

void SourceDebugger::getDebugSections(
    StringMap<std::unique_ptr<MemoryBuffer>> &DebugSections) {
  for (auto section : sections_) {
    if (strncmp(section.first.c_str(), ".debug", 6) == 0) {
      StringRef SecData(reinterpret_cast<const char *>(get<0>(section.second)),
                        get<1>(section.second));
      DebugSections[section.first.substr(1)] =
          MemoryBuffer::getMemBufferCopy(SecData);
    }
  }
}

void SourceDebugger::dump() {
  string Error;
  string TripleStr(mod_->getTargetTriple());
  Triple TheTriple(TripleStr);
  const Target *T = TargetRegistry::lookupTarget(TripleStr, Error);
  if (!T) {
    errs() << "Debug Error: cannot get target\n";
    return;
  }

  std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TripleStr));
  if (!MRI) {
    errs() << "Debug Error: cannot get register info\n";
    return;
  }
  std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TripleStr));
  if (!MAI) {
    errs() << "Debug Error: cannot get assembly info\n";
    return;
  }

  MCObjectFileInfo MOFI;
  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, nullptr);
  MOFI.InitMCObjectFileInfo(TheTriple, false, Ctx, false);
  std::unique_ptr<MCSubtargetInfo> STI(
      T->createMCSubtargetInfo(TripleStr, "", ""));

  std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
  MCInstPrinter *IP = T->createMCInstPrinter(TheTriple, 0, *MAI, *MCII, *MRI);
  if (!IP) {
    errs() << "Debug Error: unable to create instruction printer\n";
    return;
  }

  std::unique_ptr<const MCDisassembler> DisAsm(
      T->createMCDisassembler(*STI, Ctx));
  if (!DisAsm) {
    errs() << "Debug Error: no disassembler\n";
    return;
  }

  // Set up the dwarf debug context
  StringMap<std::unique_ptr<MemoryBuffer>> DebugSections;
  getDebugSections(DebugSections);
  std::unique_ptr<DWARFContext> DwarfCtx =
      DWARFContext::create(DebugSections, 8);
  if (!DwarfCtx) {
    errs() << "Debug Error: dwarf context creation failed\n";
    return;
  }

  // bcc has only one compilation unit
  DWARFCompileUnit *CU = DwarfCtx->getCompileUnitAtIndex(0);
  if (!CU) {
    errs() << "Debug Error: dwarf context failed to get compile unit\n";
    return;
  }

  const DWARFLineTable *LineTable = DwarfCtx->getLineTableForUnit(CU);
  if (!LineTable) {
    errs() << "Debug Error: dwarf context failed to get line table\n";
    return;
  }

  // Build LineCache for later source code printing
  vector<string> LineCache = buildLineCache();

  // Start to disassemble with source code annotation section by section
  for (auto section : sections_)
    if (!strncmp(fn_prefix_.c_str(), section.first.c_str(),
                 fn_prefix_.size())) {
      MCDisassembler::DecodeStatus S;
      MCInst Inst;
      uint64_t Size;
      uint8_t *FuncStart = get<0>(section.second);
      uint64_t FuncSize = get<1>(section.second);
      ArrayRef<uint8_t> Data(FuncStart, FuncSize);
      uint32_t CurrentSrcLine = 0;
      string func_name = section.first.substr(fn_prefix_.size());

      errs() << "Disassembly of section " << section.first << ":\n"
             << func_name << ":\n";

      string src_dbg_str;
      llvm::raw_string_ostream os(src_dbg_str);
      for (uint64_t Index = 0; Index < FuncSize; Index += Size) {
        S = DisAsm->getInstruction(Inst, Size, Data.slice(Index), Index,
                                   nulls(), nulls());
        if (S != MCDisassembler::Success) {
          os << "Debug Error: disassembler failed: " << std::to_string(S)
             << '\n';
          break;
        } else {
          DILineInfo LineInfo;
          LineTable->getFileLineInfoForAddress(
              (uint64_t)FuncStart + Index, CU->getCompilationDir(),
              DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
              LineInfo);

          adjustInstSize(Size, Data[Index], Data[Index + 1]);
          dumpSrcLine(LineCache, LineInfo.FileName, LineInfo.Line,
                      CurrentSrcLine, os);
          os << format("%4" PRIu64 ":", Index >> 3) << '\t';
          dumpBytes(Data.slice(Index, Size), os);
          IP->printInst(&Inst, os, "", *STI);
          os << '\n';
        }
      }
      os.flush();
      errs() << src_dbg_str << '\n';
      src_dbg_fmap_[func_name] = src_dbg_str;
    }
}

}  // namespace ebpf
<commit_msg>fix compilation error with llvm trunk (8.0.0) (#1924)<commit_after>/*
 * Copyright (c) 2017 Facebook, Inc.
 *
 * 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 <map>
#include <string>
#include <tuple>
#include <vector>

#include <llvm/DebugInfo/DWARF/DWARFContext.h>
#include <llvm/DebugInfo/DWARF/DWARFDebugLine.h>
#include <llvm/IR/Module.h>
#include <llvm/MC/MCAsmInfo.h>
#include <llvm/MC/MCContext.h>
#include <llvm/MC/MCDisassembler/MCDisassembler.h>
#include <llvm/MC/MCInstPrinter.h>
#include <llvm/MC/MCInstrInfo.h>
#include <llvm/MC/MCObjectFileInfo.h>
#include <llvm/MC/MCRegisterInfo.h>
#include <llvm/Support/TargetRegistry.h>

#include "bcc_debug.h"

namespace ebpf {

// ld_pseudo can only be disassembled properly
// in llvm 6.0, so having this workaround now
// until disto llvm versions catch up
#define WORKAROUND_FOR_LD_PSEUDO

using std::get;
using std::map;
using std::string;
using std::tuple;
using std::vector;
using namespace llvm;
using DWARFLineTable = DWARFDebugLine::LineTable;

void SourceDebugger::adjustInstSize(uint64_t &Size, uint8_t byte0,
                                    uint8_t byte1) {
#ifdef WORKAROUND_FOR_LD_PSEUDO
  bool isLittleEndian = mod_->getDataLayout().isLittleEndian();
  if (byte0 == 0x18 && ((isLittleEndian && (byte1 & 0xf) == 0x1) ||
                        (!isLittleEndian && (byte1 & 0xf0) == 0x10)))
    Size = 16;
#endif
}

vector<string> SourceDebugger::buildLineCache() {
  vector<string> LineCache;
  size_t FileBufSize = mod_src_.size();

  for (uint32_t start = 0, end = start; end < FileBufSize; end++)
    if (mod_src_[end] == '\n' || end == FileBufSize - 1 ||
        (mod_src_[end] == '\r' && mod_src_[end + 1] == '\n')) {
      // Not including the endline
      LineCache.push_back(string(mod_src_.substr(start, end - start)));
      if (mod_src_[end] == '\r')
        end++;
      start = end + 1;
    }

  return LineCache;
}

void SourceDebugger::dumpSrcLine(const vector<string> &LineCache,
                                 const string &FileName, uint32_t Line,
                                 uint32_t &CurrentSrcLine,
                                 llvm::raw_ostream &os) {
  if (Line != 0 && Line != CurrentSrcLine && Line < LineCache.size() &&
      FileName == mod_->getSourceFileName()) {
    os << "; " << StringRef(LineCache[Line - 1]).ltrim()
       << format(
              " // Line"
              "%4" PRIu64 "\n",
              Line);
    CurrentSrcLine = Line;
  }
}

void SourceDebugger::getDebugSections(
    StringMap<std::unique_ptr<MemoryBuffer>> &DebugSections) {
  for (auto section : sections_) {
    if (strncmp(section.first.c_str(), ".debug", 6) == 0) {
      StringRef SecData(reinterpret_cast<const char *>(get<0>(section.second)),
                        get<1>(section.second));
      DebugSections[section.first.substr(1)] =
          MemoryBuffer::getMemBufferCopy(SecData);
    }
  }
}

void SourceDebugger::dump() {
  string Error;
  string TripleStr(mod_->getTargetTriple());
  Triple TheTriple(TripleStr);
  const Target *T = TargetRegistry::lookupTarget(TripleStr, Error);
  if (!T) {
    errs() << "Debug Error: cannot get target\n";
    return;
  }

  std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TripleStr));
  if (!MRI) {
    errs() << "Debug Error: cannot get register info\n";
    return;
  }
  std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TripleStr));
  if (!MAI) {
    errs() << "Debug Error: cannot get assembly info\n";
    return;
  }

  MCObjectFileInfo MOFI;
  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, nullptr);
  MOFI.InitMCObjectFileInfo(TheTriple, false, Ctx, false);
  std::unique_ptr<MCSubtargetInfo> STI(
      T->createMCSubtargetInfo(TripleStr, "", ""));

  std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
  MCInstPrinter *IP = T->createMCInstPrinter(TheTriple, 0, *MAI, *MCII, *MRI);
  if (!IP) {
    errs() << "Debug Error: unable to create instruction printer\n";
    return;
  }

  std::unique_ptr<const MCDisassembler> DisAsm(
      T->createMCDisassembler(*STI, Ctx));
  if (!DisAsm) {
    errs() << "Debug Error: no disassembler\n";
    return;
  }

  // Set up the dwarf debug context
  StringMap<std::unique_ptr<MemoryBuffer>> DebugSections;
  getDebugSections(DebugSections);
  std::unique_ptr<DWARFContext> DwarfCtx =
      DWARFContext::create(DebugSections, 8);
  if (!DwarfCtx) {
    errs() << "Debug Error: dwarf context creation failed\n";
    return;
  }

  // bcc has only one compilation unit
  // getCompileUnitAtIndex() was gone in llvm 8.0 (https://reviews.llvm.org/D49741)
#if LLVM_MAJOR_VERSION >= 8
  DWARFCompileUnit *CU = cast<DWARFCompileUnit>(DwarfCtx->getUnitAtIndex(0));
#else
  DWARFCompileUnit *CU = DwarfCtx->getCompileUnitAtIndex(0);
#endif
  if (!CU) {
    errs() << "Debug Error: dwarf context failed to get compile unit\n";
    return;
  }

  const DWARFLineTable *LineTable = DwarfCtx->getLineTableForUnit(CU);
  if (!LineTable) {
    errs() << "Debug Error: dwarf context failed to get line table\n";
    return;
  }

  // Build LineCache for later source code printing
  vector<string> LineCache = buildLineCache();

  // Start to disassemble with source code annotation section by section
  for (auto section : sections_)
    if (!strncmp(fn_prefix_.c_str(), section.first.c_str(),
                 fn_prefix_.size())) {
      MCDisassembler::DecodeStatus S;
      MCInst Inst;
      uint64_t Size;
      uint8_t *FuncStart = get<0>(section.second);
      uint64_t FuncSize = get<1>(section.second);
      ArrayRef<uint8_t> Data(FuncStart, FuncSize);
      uint32_t CurrentSrcLine = 0;
      string func_name = section.first.substr(fn_prefix_.size());

      errs() << "Disassembly of section " << section.first << ":\n"
             << func_name << ":\n";

      string src_dbg_str;
      llvm::raw_string_ostream os(src_dbg_str);
      for (uint64_t Index = 0; Index < FuncSize; Index += Size) {
        S = DisAsm->getInstruction(Inst, Size, Data.slice(Index), Index,
                                   nulls(), nulls());
        if (S != MCDisassembler::Success) {
          os << "Debug Error: disassembler failed: " << std::to_string(S)
             << '\n';
          break;
        } else {
          DILineInfo LineInfo;
          LineTable->getFileLineInfoForAddress(
              (uint64_t)FuncStart + Index, CU->getCompilationDir(),
              DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
              LineInfo);

          adjustInstSize(Size, Data[Index], Data[Index + 1]);
          dumpSrcLine(LineCache, LineInfo.FileName, LineInfo.Line,
                      CurrentSrcLine, os);
          os << format("%4" PRIu64 ":", Index >> 3) << '\t';
          dumpBytes(Data.slice(Index, Size), os);
          IP->printInst(&Inst, os, "", *STI);
          os << '\n';
        }
      }
      os.flush();
      errs() << src_dbg_str << '\n';
      src_dbg_fmap_[func_name] = src_dbg_str;
    }
}

}  // namespace ebpf
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: CCP4File.C,v 1.1.4.1 2007/03/25 22:00:16 oliver Exp $
//

#include <BALL/FORMAT/CCP4File.h>

namespace BALL
{
	CCP4File::CCP4File()
		throw()
	: File(),
		swap_bytes_(false),
		offset_symops_(0),
		col_axis_(1),
		row_axis_(2),
		sec_axis_(3)
	{
	}

	CCP4File::CCP4File(const CCP4File& file)
		throw(Exception::FileNotFound)
		:	File(file),
			swap_bytes_(file.swap_bytes_),
			offset_symops_(0),
			col_axis_(1),
			row_axis_(2),
			sec_axis_(3)
	{
	}

	CCP4File::CCP4File(const String& name, File::OpenMode open_mode)
		throw()
		: File(name, open_mode),
			swap_bytes_(false),
			offset_symops_(0),
			col_axis_(1),
			row_axis_(2),
			sec_axis_(3)
	{
		// CCP4Files are always binary
		if ((open_mode & std::ios::binary) == 0)
		{
			open_mode_ = (open_mode | std::ios::binary);
			reopen();
		}
	}

	CCP4File::~CCP4File()
		throw()
	{
		close();
		clear();
	}

	const CCP4File& CCP4File::operator = (const CCP4File& file)
		throw()
	{
		File::operator = (file);
		swap_bytes_ = file.swap_bytes_;
		offset_symops_ = file.offset_symops_;

		col_axis_ = file.col_axis_;
		row_axis_ = file.row_axis_;
		sec_axis_ = file.sec_axis_;
		return *this;
	}

	void CCP4File::clear()
		throw()
	{
		File::clear();
		swap_bytes_= false;
		offset_symops_= 0;
		col_axis_ = 0;
		row_axis_ = 1;
		sec_axis_ = 2;
	}

	bool CCP4File::operator == (const CCP4File& file) const
		throw()
	{
		return (   (File::operator == (file))
						 &&(swap_bytes_    == file.swap_bytes_)
						 &&(offset_symops_== file.offset_symops_)
						 &&(col_axis_== file.col_axis_)
						 &&(row_axis_== file.row_axis_)
						 &&(sec_axis_== file.sec_axis_));
	}

	bool CCP4File::open(const String& name, File::OpenMode open_mode)
		throw(Exception::FileNotFound)
	{
		if (!(open_mode |= std::ios::binary))
		{
			open_mode = open_mode | std::ios::binary;
		}

		if (!File::open(name, open_mode))
		{
			return(false);
		}

		return true;
	}

	bool CCP4File::readHeader()
		throw()
	{
		// first read the complete 1024 bytes of header information
		char header[1024];
		std::fstream::read(header, 1024);

		if (gcount() != 1024)
		{
			Log.error() << "CCP4File::readHeader(): File does not contain a proper CCP4 header. Aborting read." << std::endl;

			return false;
		}
		// Currently only data_mode=2 is allowed, which stores density values as 4-byte float values
		int data_mode = readBinValueasInt_(header, 3);

		if (data_mode != 2)
		{
			// try to change endianness
			swap_bytes_= true;

			data_mode = readBinValueasInt_(header, 3);
			if (data_mode != 2)
			{
				Log.error() << "CCP4File::readHeader(): Corrupt CCP4 header: data mode not supported, only 32-bit float supported" << std::endl;
				return false;
			}
		}

		//check if file claims to have symmetry reocrds stored
		int size_of_symops = readBinValueasInt_(header, 23);
		if (size_of_symops != 0)
		{
			offset_symops_ = size_of_symops;
		}

		// check internal ordering of coordinate axis
		col_axis_ = readBinValueasInt_(header, 16)-1;
		row_axis_ = readBinValueasInt_(header, 17)-1;
		sec_axis_ = readBinValueasInt_(header, 18)-1;

		extent_.x = (float)readBinValueasInt_(header, 0+col_axis_);
		extent_.y = (float)readBinValueasInt_(header, 0+row_axis_);
		extent_.z = (float)readBinValueasInt_(header, 0+sec_axis_);

		start_.x = (float)readBinValueasInt_(header, 4+col_axis_);
		start_.y = (float)readBinValueasInt_(header, 4+row_axis_);
		start_.z = (float)readBinValueasInt_(header, 4+sec_axis_);

		sampling_rate_.x = (float)readBinValueasInt_(header, 7);
		sampling_rate_.y = (float)readBinValueasInt_(header, 8);
		sampling_rate_.z = (float)readBinValueasInt_(header, 9);

		cell_dimension_.x = readBinValueasFloat_(header, 10);
		cell_dimension_.y = readBinValueasFloat_(header, 11);
		cell_dimension_.z = readBinValueasFloat_(header, 12);

		alpha_ = Angle(readBinValueasFloat_(header, 13),false);
		beta_	 = Angle(readBinValueasFloat_(header, 14),false);
		gamma_ = Angle(readBinValueasFloat_(header, 15),false);

		mean_density_ = readBinValueasFloat_(header, 21);
		space_group_ = readBinValueasInt_(header, 22);
		deviation_sigma_ = readBinValueasFloat_(header, 54);

		Log.info() << "Mean : " << mean_density_ << std::endl;
		Log.info() << "Sigma: " << deviation_sigma_ << std::endl;

		// convert from grid space to cartesian coordinates
		Vector3 scaled_axes(cell_dimension_.x/sampling_rate_.x,
												cell_dimension_.y/sampling_rate_.y,
												cell_dimension_.z/sampling_rate_.z);

		Vector3 x_tmp(scaled_axes.x, 0., 0.);

		Vector3 y_tmp(cos(gamma_.toRadian()), sin(gamma_.toRadian()), 0.);
		y_tmp *= scaled_axes.y;

		Vector3 z_tmp( cos(beta_.toRadian()),
									(cos(alpha_.toRadian()) - cos(beta_.toRadian())*cos(gamma_.toRadian())) / sin(gamma_.toRadian()),
									0.);
		z_tmp.z = sqrt(1.0 - z_tmp.x*z_tmp.x - z_tmp.y*z_tmp.y);
		z_tmp *= scaled_axes.z;

		origin_.x = x_tmp.x * start_.x + y_tmp.x * start_.y + z_tmp.x * start_.z;
		origin_.y = y_tmp.y * start_.y + z_tmp.y * start_.z;
		origin_.z = z_tmp.z * start_.z;

		xaxis_.x = x_tmp.x * (extent_.x - 1);
		xaxis_.y = 0.;
		xaxis_.z = 0.;

		yaxis_.x = y_tmp.x * (extent_.y - 1);
		yaxis_.y = y_tmp.y * (extent_.y - 1);
		yaxis_.z = 0.;

		zaxis_.x = z_tmp.x * (extent_.z - 1);
		zaxis_.y = z_tmp.y * (extent_.z - 1);
		zaxis_.z = z_tmp.z * (extent_.z - 1);

		// that's it. we're done
		return true;
	}

	bool CCP4File::readSymmetryRecords()
		throw()
	{
		//check if file has special symmetry records
		int offset = getSize() - int(4*(extent_.x*extent_.y*extent_.z));
		if (offset != offset_symops_)
		{
			if(offset == 0)
			{
				Log.info() << "CCP4File::readSymmetryRecords(): Warning: File claims to have symmetry record, but in fact has not" << std::endl;
				offset_symops_ = 0;
			}
			else if (offset < 0)
			{

				Log.error() << "CCP4File::readSymmetryRecords(): Error: File seems to be truncated" << std::endl;
				return false;
			}
			else if (offset > 0)
			{
				Log.error() << "CCP4File::readSymmetryRecords(): Error: File larger than expected" << std::endl;
				return false;
			}
		}

		if(offset_symops_ != 0)
		{
			char *sym_record = new char[80];
			int sym_lines = 0;
			Log.info() << "CCP4File::readSymmetryRecords(): File has the following symmetry information stored:" << std::endl;
			while (sym_lines < offset_symops_/80)
			{
				std::fstream::read(sym_record, 80);
				Log.info() << "--> " << sym_record << std::endl;
				sym_lines++;
			}
		}
		else
		{
			Log.info() << "CCP4File::readSymmetryRecords(): File has no symmetry records" << std::endl;
		}
		return true;
	}

	int CCP4File::readBinValueasInt_(char* data, Position pos)
		throw()
	{
		int int_value = *((int*)(data + 4*pos));

		if (swap_bytes_)
			swapBytes(int_value);

		return int_value;
	}

	float CCP4File::readBinValueasFloat_(char* data, Position pos)
		throw()
	{
		float float_value = *((float*)(data + 4*pos));

		if (swap_bytes_)
			swapBytes(float_value);

		return float_value;
	}

	bool CCP4File::writeHeader()
		throw()
	{
		// construct a correct header array and write it.
		// TODO: implement
		return false;
	}

	bool CCP4File::read(RegularData3D& density_map)
		throw()
	{

		// first read the header
		if (!readHeader())
		{
			Log.error() << "CCP4File::read(): readHeader() failed. Aborting read." << std::endl;
			return false;
		}

		// then try to read symmetry records if present
		if (!readSymmetryRecords())
		{
			Log.error() << "CCP4File::read(): readSymmteryRecords() failed. Aborting read." << std::endl;
			return false;
		}

		if (int(getSize()) > int(4*(extent_.x*extent_.y*extent_.z)))
		{
			Log.info() << "CCP4File::read(): Warning: datablock bigger than expected. But continueing anyway." << std::endl;
		}

		Size global_index = 0;

		RegularData3D::IndexType size_crs;
		size_crs.x = (Size) extent_[(Position) col_axis_];
		size_crs.y = (Size) extent_[(Position) row_axis_];
		size_crs.z = (Size) extent_[(Position) sec_axis_];

		RegularData3D::IndexType size;
		size.x = (Size) extent_.x;
		size.y = (Size) extent_.y;
		size.z = (Size) extent_.z;

		density_map = RegularData3D(origin_, xaxis_, yaxis_, zaxis_, size);

		density_map.setDimension(Vector3(xaxis_.x, yaxis_.y, zaxis_.z));
		char* rowblock = new char[4*int(size_crs.x)];

		Size crs[3];
		for(crs[2]=0; crs[2] < size_crs.z; crs[2]++)
		{
			for(crs[1]=0; crs[1] < size_crs.y; crs[1]++)
			{
				std::fstream::read(rowblock, 4*(int(size_crs.x)));
				for(crs[0]=0; crs[0] < size_crs.x; crs[0]++)
				{
					global_index = (Size)(crs[col_axis_]+ crs[row_axis_]*size.x + crs[sec_axis_]*size.x*size.y);
					density_map[global_index] = readBinValueasFloat_(rowblock,crs[0]);
				}
			}
		}
		return true;
	}

} // namespace BALL
<commit_msg>Some fixes on the CCP4File parsing procedure<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: CCP4File.C,v 1.1.4.1 2007/03/25 22:00:16 oliver Exp $
//

#include <BALL/FORMAT/CCP4File.h>

namespace BALL
{
	CCP4File::CCP4File()
		throw()
	: File(),
		swap_bytes_(false),
		offset_symops_(0),
		col_axis_(1),
		row_axis_(2),
		sec_axis_(3)
	{
	}

	CCP4File::CCP4File(const CCP4File& file)
		throw(Exception::FileNotFound)
		:	File(file),
			swap_bytes_(file.swap_bytes_),
			offset_symops_(0),
			col_axis_(1),
			row_axis_(2),
			sec_axis_(3)
	{
	}

	CCP4File::CCP4File(const String& name, File::OpenMode open_mode)
		throw()
		: File(name, open_mode),
			swap_bytes_(false),
			offset_symops_(0),
			col_axis_(1),
			row_axis_(2),
			sec_axis_(3)
	{
		// CCP4Files are always binary
		if ((open_mode & std::ios::binary) == 0)
		{
			open_mode_ = (open_mode | std::ios::binary);
			reopen();
		}
	}

	CCP4File::~CCP4File()
		throw()
	{
		close();
		clear();
	}

	const CCP4File& CCP4File::operator = (const CCP4File& file)
		throw()
	{
		File::operator = (file);
		swap_bytes_ = file.swap_bytes_;
		offset_symops_ = file.offset_symops_;

		col_axis_ = file.col_axis_;
		row_axis_ = file.row_axis_;
		sec_axis_ = file.sec_axis_;
		return *this;
	}

	void CCP4File::clear()
		throw()
	{
		File::clear();
		swap_bytes_= false;
		offset_symops_= 0;
		col_axis_ = 0;
		row_axis_ = 1;
		sec_axis_ = 2;
	}

	bool CCP4File::operator == (const CCP4File& file) const
		throw()
	{
		return (   (File::operator == (file))
						 &&(swap_bytes_    == file.swap_bytes_)
						 &&(offset_symops_== file.offset_symops_)
						 &&(col_axis_== file.col_axis_)
						 &&(row_axis_== file.row_axis_)
						 &&(sec_axis_== file.sec_axis_));
	}

	bool CCP4File::open(const String& name, File::OpenMode open_mode)
		throw(Exception::FileNotFound)
	{
		if (!(open_mode |= std::ios::binary))
		{
			open_mode = open_mode | std::ios::binary;
		}

		if (!File::open(name, open_mode))
		{
			return(false);
		}

		return true;
	}

	bool CCP4File::readHeader()
		throw()
	{
		// first read the complete 1024 bytes of header information
		char header[1024];
		std::fstream::read(header, 1024);

		if (gcount() != 1024)
		{
			Log.error() << "CCP4File::readHeader(): File does not contain a proper CCP4 header. Aborting read." << std::endl;

			return false;
		}
		// Currently only data_mode=2 is allowed, which stores density values as 4-byte float values
		int data_mode = readBinValueasInt_(header, 3);

		if (data_mode != 2)
		{
			// try to change endianness
			swap_bytes_= true;

			data_mode = readBinValueasInt_(header, 3);
			if (data_mode != 2)
			{
				Log.error() << "CCP4File::readHeader(): Corrupt CCP4 header: data mode not supported, only 32-bit float supported" << std::endl;
				return false;
			}
		}

		//check if file claims to have symmetry reocrds stored
		int size_of_symops = readBinValueasInt_(header, 23);
		if (size_of_symops != 0)
		{
			offset_symops_ = size_of_symops;
		}

		// check internal ordering of coordinate axis
		col_axis_ = readBinValueasInt_(header, 16)-1;
		row_axis_ = readBinValueasInt_(header, 17)-1;
		sec_axis_ = readBinValueasInt_(header, 18)-1;

		extent_.x = (float)readBinValueasInt_(header, 0+col_axis_);
		extent_.y = (float)readBinValueasInt_(header, 0+row_axis_);
		extent_.z = (float)readBinValueasInt_(header, 0+sec_axis_);

		start_.x = (float)readBinValueasInt_(header, 4+col_axis_);
		start_.y = (float)readBinValueasInt_(header, 4+row_axis_);
		start_.z = (float)readBinValueasInt_(header, 4+sec_axis_);

		sampling_rate_.x = (float)readBinValueasInt_(header, 7);
		sampling_rate_.y = (float)readBinValueasInt_(header, 8);
		sampling_rate_.z = (float)readBinValueasInt_(header, 9);

		cell_dimension_.x = readBinValueasFloat_(header, 10);
		cell_dimension_.y = readBinValueasFloat_(header, 11);
		cell_dimension_.z = readBinValueasFloat_(header, 12);

		alpha_ = Angle(readBinValueasFloat_(header, 13),false);
		beta_	 = Angle(readBinValueasFloat_(header, 14),false);
		gamma_ = Angle(readBinValueasFloat_(header, 15),false);

		mean_density_ = readBinValueasFloat_(header, 21);
		space_group_ = readBinValueasInt_(header, 22);
		deviation_sigma_ = readBinValueasFloat_(header, 54);

		Log.info() << "Mean from file: " << mean_density_ << std::endl;
		Log.info() << "Sigma from file: " << deviation_sigma_ << std::endl;

		// convert from grid space to cartesian coordinates
		Vector3 scaled_axes(cell_dimension_.x/sampling_rate_.x,
												cell_dimension_.y/sampling_rate_.y,
												cell_dimension_.z/sampling_rate_.z);

		Vector3 x_tmp(scaled_axes.x, 0., 0.);

		Vector3 y_tmp(cos(gamma_.toRadian()), sin(gamma_.toRadian()), 0.);
		y_tmp *= scaled_axes.y;

		Vector3 z_tmp( cos(beta_.toRadian()),
									(cos(alpha_.toRadian()) - cos(beta_.toRadian())*cos(gamma_.toRadian())) / sin(gamma_.toRadian()),
									0.);
		z_tmp.z = sqrt(1.0 - z_tmp.x*z_tmp.x - z_tmp.y*z_tmp.y);
		z_tmp *= scaled_axes.z;

		origin_.x = x_tmp.x * start_.x + y_tmp.x * start_.y + z_tmp.x * start_.z;
		origin_.y = y_tmp.y * start_.y + z_tmp.y * start_.z;
		origin_.z = z_tmp.z * start_.z;

		xaxis_.x = x_tmp.x * (extent_.x - 1);
		xaxis_.y = 0.;
		xaxis_.z = 0.;

		yaxis_.x = y_tmp.x * (extent_.y - 1);
		yaxis_.y = y_tmp.y * (extent_.y - 1);
		yaxis_.z = 0.;

		zaxis_.x = z_tmp.x * (extent_.z - 1);
		zaxis_.y = z_tmp.y * (extent_.z - 1);
		zaxis_.z = z_tmp.z * (extent_.z - 1);

		// that's it. we're done
		return true;
	}

	bool CCP4File::readSymmetryRecords()
		throw()
	{
		//check if file has special symmetry records
		int offset = getSize() - int(4*(extent_.x*extent_.y*extent_.z));
		if (offset != offset_symops_)
		{
			if(offset == 0)
			{
				Log.info() << "CCP4File::readSymmetryRecords(): Warning: File claims to have symmetry record, but in fact has not" << std::endl;
				offset_symops_ = 0;
			}
			else if (offset < 0)
			{

				Log.error() << "CCP4File::readSymmetryRecords(): Error: File seems to be truncated" << std::endl;
				return false;
			}
			else if ((offset - offset_symops_)< 0)
			{
				Log.info() << "CCP4File::readSymmetryRecords(): Error: Symmetry Record smaller than expected" << std::endl;
				return false;
			}
		}

		if(offset_symops_ != 0)
		{
			char *sym_record = new char[80];
			int sym_lines = 0;
			Log.info() << "CCP4File::readSymmetryRecords(): File has the following symmetry information stored:" << std::endl;
			while (sym_lines < offset_symops_/80)
			{
				std::fstream::read(sym_record, 80);
				Log.info() << "--> " << sym_record << std::endl;
				sym_lines++;
			}
		}
		else
		{
			Log.info() << "CCP4File::readSymmetryRecords(): File has no symmetry records" << std::endl;
		}
		return true;
	}

	int CCP4File::readBinValueasInt_(char* data, Position pos)
		throw()
	{
		int int_value = *((int*)(data + 4*pos));

		if (swap_bytes_)
			swapBytes(int_value);

		return int_value;
	}

	float CCP4File::readBinValueasFloat_(char* data, Position pos)
		throw()
	{
		float float_value = *((float*)(data + 4*pos));

		if (swap_bytes_)
			swapBytes(float_value);

		return float_value;
	}

	bool CCP4File::writeHeader()
		throw()
	{
		// construct a correct header array and write it.
		// TODO: implement
		return false;
	}

	bool CCP4File::read(RegularData3D& density_map)
		throw()
	{

		// first read the header
		if (!readHeader())
		{
			Log.error() << "CCP4File::read(): readHeader() failed. Aborting read." << std::endl;
			return false;
		}

		// then try to read symmetry records if present
		if (!readSymmetryRecords())
		{
			Log.error() << "CCP4File::read(): readSymmteryRecords() failed. Aborting read." << std::endl;
			return false;
		}

		if (int(getSize()) > int(4*(extent_.x*extent_.y*extent_.z)))
		{
			Log.info() << "CCP4File::read(): Warning: datablock bigger than expected. But continuing anyway." << std::endl;
		}

		Size global_index = 0;

		RegularData3D::IndexType size_crs;
		size_crs.x = (Size) extent_[(Position) col_axis_];
		size_crs.y = (Size) extent_[(Position) row_axis_];
		size_crs.z = (Size) extent_[(Position) sec_axis_];

		RegularData3D::IndexType size;
		size.x = (Size) extent_.x;
		size.y = (Size) extent_.y;
		size.z = (Size) extent_.z;

		density_map = RegularData3D(origin_, xaxis_, yaxis_, zaxis_, size);

		density_map.setDimension(Vector3(xaxis_.x, yaxis_.y, zaxis_.z));
		char* rowblock = new char[4*int(size_crs.x)];

		Size crs[3];
		for(crs[2]=0; crs[2] < size_crs.z; crs[2]++)
		{
			for(crs[1]=0; crs[1] < size_crs.y; crs[1]++)
			{
				std::fstream::read(rowblock, 4*(int(size_crs.x)));
				for(crs[0]=0; crs[0] < size_crs.x; crs[0]++)
				{
					global_index = (Size)(crs[col_axis_]+ crs[row_axis_]*size.x + crs[sec_axis_]*size.x*size.y);
					density_map[global_index] = readBinValueasFloat_(rowblock,crs[0]);
				}
			}
		}
		return true;
	}

} // namespace BALL
<|endoftext|>


<commit_before>// $Id: Timer_test.C,v 1.10 2001/07/15 17:32:41 amoll Exp $
#include <BALL/CONCEPT/classTest.h>
#include <unistd.h>
///////////////////////////
#include <BALL/SYSTEM/timer.h>
#include <BALL/SYSTEM/file.h>
///////////////////////////

START_TEST(Timer, "$Id: Timer_test.C,v 1.10 2001/07/15 17:32:41 amoll Exp $")

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

using namespace BALL;

#define BUSY_WAIT \
	STATUS("WAITING")\
	{ double x = 0.0; for (int i = 0; i < 500000; i++, x += rand()); }

CHECK(Timer::Timer())
	Timer* t1 = new Timer();
	TEST_NOT_EQUAL(t1, 0)
	TEST_EQUAL(t1->isRunning(), false)
RESULT

CHECK(Timer::~Timer())
	Timer* t1 = new Timer();
	delete t1;
RESULT

CHECK(Timer::Timer(Timer& timer))
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2(t1);
	TEST_EQUAL(t2.isRunning(), false)
	TEST_REAL_EQUAL(t1.getClockTime(), t2.getClockTime())
	TEST_REAL_EQUAL(t1.getUserTime(), t2.getUserTime())
	TEST_REAL_EQUAL(t1.getSystemTime(), t2.getSystemTime())
	TEST_REAL_EQUAL(t1.getCPUTime(), t2.getCPUTime())
RESULT

CHECK(Timer::clear())
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	t1.clear();
	TEST_EQUAL(t1.isRunning(), false)
	TEST_EQUAL(t1.getClockTime(), 0)
	TEST_EQUAL(t1.getUserTime(), 0)
	TEST_EQUAL(t1.getSystemTime(), 0)
	TEST_EQUAL(t1.getCPUTime(), 0)
RESULT

CHECK(Timer::start())
	Timer t1;
	TEST_EQUAL(t1.start(), true)
	TEST_EQUAL(t1.start(), false)
	TEST_EQUAL(t1.isRunning(), true)
	BUSY_WAIT
	TEST_EQUAL(t1.getClockTime() >= 0, true)
	TEST_EQUAL(t1.getUserTime() >= 0, true)
	TEST_EQUAL(t1.getCPUTime() >= 0, true)
RESULT

CHECK(Timer::stop())
	Timer t1;
	t1.start();
	TEST_EQUAL(t1.isRunning(), true)
	TEST_EQUAL(t1.stop(), true)
	TEST_EQUAL(t1.stop(), false)
	TEST_EQUAL(t1.isRunning(), false)
RESULT

CHECK(Timer::reset())
	Timer t1;
	t1.start();
	// busy waiting
	t1.reset();
	// this is somewhat dangerous, but the best we could come up
	// with
	TEST_EQUAL(t1.isRunning(), true)
	TEST_EQUAL(t1.getClockTime() < 0.1, true)
	TEST_EQUAL(t1.getUserTime() < 0.1, true)
	TEST_EQUAL(t1.getSystemTime() < 0.1, true)
	TEST_EQUAL(t1.getCPUTime() < 0.1, true)
RESULT

CHECK(Timer::getClockTime() const )
	Timer t1;
	TEST_EQUAL(t1.getClockTime(), 0)
	t1.start();
	sleep(2);
	t1.stop();
	TEST_EQUAL(t1.getClockTime() > 1, true)
	TEST_EQUAL(t1.getClockTime() < 3, true)
RESULT

CHECK(Timer::getUserTime() const )
	Timer t1;
	TEST_EQUAL(t1.getUserTime(), 0)
	t1.start();
	BUSY_WAIT
	t1.stop();
	TEST_EQUAL(t1.getUserTime() >= 0, true)
RESULT

CHECK(Timer::getSystemTime() const )
	Timer t1;
	TEST_EQUAL(t1.getSystemTime(), 0)
	t1.start();
	BUSY_WAIT
	t1.stop();
	TEST_EQUAL(t1.getSystemTime() > 0, false)
	t1.start();
	File f("data/Timer_test1.txt");
	for (int i = 0; i < 10 ; i++)
	{
		TEST_EQUAL(f.copyTo("data/Timer_test1.bak"), true)
	}
	f.remove("data/Timer_test1.bak");
	TEST_EQUAL(t1.getSystemTime()> 0, true)
RESULT

CHECK(Timer::getCPUTime() const )
	Timer t1;
	TEST_EQUAL(t1.getCPUTime(), 0)
	t1.start();
	sleep(2);
	t1.stop();
	TEST_EQUAL(t1.getCPUTime() <= 1, true)
	t1.reset();
	t1.start();
	BUSY_WAIT
	t1.stop();
	TEST_EQUAL(t1.getCPUTime() > 0, true)
	TEST_REAL_EQUAL(t1.getCPUTime(), t1.getSystemTime() + t1.getUserTime())
RESULT

CHECK(Timer::Timer& operator = (const Timer& timer))
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2;
	t2 = t1;
	TEST_EQUAL(t2.isRunning(), false)
	TEST_EQUAL(t1.getClockTime(), t2.getClockTime())
	TEST_REAL_EQUAL(t1.getUserTime(), t2.getUserTime())
	TEST_REAL_EQUAL(t1.getSystemTime(), t2.getSystemTime())
	TEST_REAL_EQUAL(t1.getCPUTime(), t2.getCPUTime())
RESULT

CHECK(Timer::isRunning() const )
	Timer t1;
	t1.start();
	TEST_EQUAL(t1.isRunning(), true)
	t1.stop();
	TEST_EQUAL(t1.isRunning(), false)
RESULT

CHECK(Timer::bool operator == (const Timer& timer) const )
	Timer t1;
	t1.start();
	sleep(1);
	t1.stop();
	Timer t2;
	TEST_EQUAL(t1 == t2, false);
	t2 = t1;
	TEST_EQUAL(t1 == t2, true);
RESULT

CHECK(Timer::bool operator != (const Timer& timer) const )
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2;
	TEST_EQUAL(t1 != t2, true);
	t2 = t1;
	TEST_EQUAL(t1 != t2, false);
RESULT

CHECK(Timer::bool operator < (const Timer& timer) const )
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2;
	TEST_EQUAL(t1 < t2, false);
	TEST_EQUAL(t2 < t1, true);
	t2 = t1;
	TEST_EQUAL(t1 < t2, false);
RESULT

CHECK(Timer::bool operator <= (const Timer& timer) const )
	Timer& t1 = *new Timer;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer& t2 = *new Timer;
	TEST_EQUAL(t1 <= t2, false);
	TEST_EQUAL(t2 <= t1, true);
	t2 = t1;
	TEST_EQUAL(t1 <= t2, true);
	delete &t1;
	delete &t2;
RESULT

CHECK(Timer::bool operator >= (const Timer& timer) const )
	Timer& t1 = *new Timer;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer& t2 = *new Timer;
	TEST_EQUAL(t1 >= t2, true);
	TEST_EQUAL(t2 > t1, false);
	t2 = t1;
	TEST_EQUAL(t1 >= t2, true);
	delete &t1;
	delete &t2;
RESULT

CHECK(Timer::bool operator > (const Timer& timer) const )
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2;
	TEST_EQUAL(t1 > t2, true);
	TEST_EQUAL(t2 > t1, false);
	t2 = t1;
	TEST_EQUAL(t1 > t2, false);
RESULT

CHECK(Timer::isValid() const )
	Timer t1;
	TEST_EQUAL(t1.isValid(), true);
RESULT

CHECK(Timer::dump(::std::ostream& s = ::std::cout, Size depth = 0L) const )
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
  String filename;
	NEW_TMP_FILE(filename)
	std::ofstream outfile(filename.c_str(), File::OUT);
	t1.dump(outfile);
	outfile.close();
	TEST_FILE(filename.c_str(), "data/Timer_test.txt", true)
RESULT
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<commit_msg>fixed: should do now even on very fast filesystems<commit_after>// $Id: Timer_test.C,v 1.11 2001/07/17 02:36:38 oliver Exp $
#include <BALL/CONCEPT/classTest.h>
#include <unistd.h>
///////////////////////////
#include <BALL/SYSTEM/timer.h>
#include <BALL/SYSTEM/file.h>
///////////////////////////

START_TEST(Timer, "$Id: Timer_test.C,v 1.11 2001/07/17 02:36:38 oliver Exp $")

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

using namespace BALL;

#define BUSY_WAIT \
	STATUS("WAITING")\
	{ double x = 0.0; for (int i = 0; i < 500000; i++, x += rand()); }

CHECK(Timer::Timer())
	Timer* t1 = new Timer();
	TEST_NOT_EQUAL(t1, 0)
	TEST_EQUAL(t1->isRunning(), false)
RESULT

CHECK(Timer::~Timer())
	Timer* t1 = new Timer();
	delete t1;
RESULT

CHECK(Timer::Timer(Timer& timer))
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2(t1);
	TEST_EQUAL(t2.isRunning(), false)
	TEST_REAL_EQUAL(t1.getClockTime(), t2.getClockTime())
	TEST_REAL_EQUAL(t1.getUserTime(), t2.getUserTime())
	TEST_REAL_EQUAL(t1.getSystemTime(), t2.getSystemTime())
	TEST_REAL_EQUAL(t1.getCPUTime(), t2.getCPUTime())
RESULT

CHECK(Timer::clear())
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	t1.clear();
	TEST_EQUAL(t1.isRunning(), false)
	TEST_EQUAL(t1.getClockTime(), 0)
	TEST_EQUAL(t1.getUserTime(), 0)
	TEST_EQUAL(t1.getSystemTime(), 0)
	TEST_EQUAL(t1.getCPUTime(), 0)
RESULT

CHECK(Timer::start())
	Timer t1;
	TEST_EQUAL(t1.start(), true)
	TEST_EQUAL(t1.start(), false)
	TEST_EQUAL(t1.isRunning(), true)
	BUSY_WAIT
	TEST_EQUAL(t1.getClockTime() >= 0, true)
	TEST_EQUAL(t1.getUserTime() >= 0, true)
	TEST_EQUAL(t1.getCPUTime() >= 0, true)
RESULT

CHECK(Timer::stop())
	Timer t1;
	t1.start();
	TEST_EQUAL(t1.isRunning(), true)
	TEST_EQUAL(t1.stop(), true)
	TEST_EQUAL(t1.stop(), false)
	TEST_EQUAL(t1.isRunning(), false)
RESULT

CHECK(Timer::reset())
	Timer t1;
	t1.start();
	// busy waiting
	t1.reset();
	// this is somewhat dangerous, but the best we could come up
	// with
	TEST_EQUAL(t1.isRunning(), true)
	TEST_EQUAL(t1.getClockTime() < 0.1, true)
	TEST_EQUAL(t1.getUserTime() < 0.1, true)
	TEST_EQUAL(t1.getSystemTime() < 0.1, true)
	TEST_EQUAL(t1.getCPUTime() < 0.1, true)
RESULT

CHECK(Timer::getClockTime() const )
	Timer t1;
	TEST_EQUAL(t1.getClockTime(), 0)
	t1.start();
	sleep(2);
	t1.stop();
	TEST_EQUAL(t1.getClockTime() > 1, true)
	TEST_EQUAL(t1.getClockTime() < 3, true)
RESULT

CHECK(Timer::getUserTime() const )
	Timer t1;
	TEST_EQUAL(t1.getUserTime(), 0)
	t1.start();
	BUSY_WAIT
	t1.stop();
	TEST_EQUAL(t1.getUserTime() >= 0, true)
RESULT

CHECK(Timer::getSystemTime() const )
	Timer t1;
	TEST_EQUAL(t1.getSystemTime(), 0)
	t1.start();
	BUSY_WAIT
	t1.stop();
	TEST_EQUAL(t1.getSystemTime() > 0, false)
	t1.start();
	File f("data/Timer_test1.txt");
	for (int i = 0; i < 200 ; i++)
	{
		TEST_EQUAL(f.copyTo("data/Timer_test1.bak"), true)
	}
	f.remove("data/Timer_test1.bak");
	TEST_EQUAL(t1.getSystemTime() >= 0, true)
RESULT

CHECK(Timer::getCPUTime() const )
	Timer t1;
	TEST_EQUAL(t1.getCPUTime(), 0)
	t1.start();
	sleep(2);
	t1.stop();
	TEST_EQUAL(t1.getCPUTime() <= 1, true)
	t1.reset();
	t1.start();
	BUSY_WAIT
	t1.stop();
	TEST_EQUAL(t1.getCPUTime() > 0, true)
	TEST_REAL_EQUAL(t1.getCPUTime(), t1.getSystemTime() + t1.getUserTime())
RESULT

CHECK(Timer::Timer& operator = (const Timer& timer))
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2;
	t2 = t1;
	TEST_EQUAL(t2.isRunning(), false)
	TEST_EQUAL(t1.getClockTime(), t2.getClockTime())
	TEST_REAL_EQUAL(t1.getUserTime(), t2.getUserTime())
	TEST_REAL_EQUAL(t1.getSystemTime(), t2.getSystemTime())
	TEST_REAL_EQUAL(t1.getCPUTime(), t2.getCPUTime())
RESULT

CHECK(Timer::isRunning() const )
	Timer t1;
	t1.start();
	TEST_EQUAL(t1.isRunning(), true)
	t1.stop();
	TEST_EQUAL(t1.isRunning(), false)
RESULT

CHECK(Timer::bool operator == (const Timer& timer) const )
	Timer t1;
	t1.start();
	sleep(1);
	t1.stop();
	Timer t2;
	TEST_EQUAL(t1 == t2, false);
	t2 = t1;
	TEST_EQUAL(t1 == t2, true);
RESULT

CHECK(Timer::bool operator != (const Timer& timer) const )
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2;
	TEST_EQUAL(t1 != t2, true);
	t2 = t1;
	TEST_EQUAL(t1 != t2, false);
RESULT

CHECK(Timer::bool operator < (const Timer& timer) const )
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2;
	TEST_EQUAL(t1 < t2, false);
	TEST_EQUAL(t2 < t1, true);
	t2 = t1;
	TEST_EQUAL(t1 < t2, false);
RESULT

CHECK(Timer::bool operator <= (const Timer& timer) const )
	Timer& t1 = *new Timer;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer& t2 = *new Timer;
	TEST_EQUAL(t1 <= t2, false);
	TEST_EQUAL(t2 <= t1, true);
	t2 = t1;
	TEST_EQUAL(t1 <= t2, true);
	delete &t1;
	delete &t2;
RESULT

CHECK(Timer::bool operator >= (const Timer& timer) const )
	Timer& t1 = *new Timer;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer& t2 = *new Timer;
	TEST_EQUAL(t1 >= t2, true);
	TEST_EQUAL(t2 > t1, false);
	t2 = t1;
	TEST_EQUAL(t1 >= t2, true);
	delete &t1;
	delete &t2;
RESULT

CHECK(Timer::bool operator > (const Timer& timer) const )
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
	Timer t2;
	TEST_EQUAL(t1 > t2, true);
	TEST_EQUAL(t2 > t1, false);
	t2 = t1;
	TEST_EQUAL(t1 > t2, false);
RESULT

CHECK(Timer::isValid() const )
	Timer t1;
	TEST_EQUAL(t1.isValid(), true);
RESULT

CHECK(Timer::dump(::std::ostream& s = ::std::cout, Size depth = 0L) const )
	Timer t1;
	t1.start();
	BUSY_WAIT
	t1.stop();
  String filename;
	NEW_TMP_FILE(filename)
	std::ofstream outfile(filename.c_str(), File::OUT);
	t1.dump(outfile);
	outfile.close();
	TEST_FILE(filename.c_str(), "data/Timer_test.txt", true)
RESULT
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<|endoftext|>


<commit_before>#include "ptreferential.h"
#include "reflexion.h"
#include "where.h"
#include "type/pb_converter.h"

#include <algorithm>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/phoenix1.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix1_binders.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/phoenix/object/construct.hpp>

//TODO: change!
using namespace navitia::type;
using namespace navitia::ptref;

namespace qi = boost::spirit::qi;

namespace navitia{ namespace ptref{
using namespace navitia::type;

namespace qi = boost::spirit::qi;

/// Fonction qui va lire une chaîne de caractère et remplir un vector de Filter
        template <typename Iterator>
        struct select_r
            : qi::grammar<Iterator, std::vector<Filter>(), qi::space_type>
{
    qi::rule<Iterator, std::string(), qi::space_type> txt, txt2; // Match une string
    qi::rule<Iterator, Operator_e(), qi::space_type> bin_op; // Match une operator binaire telle que <, =...
    qi::rule<Iterator, std::vector<Filter>(), qi::space_type> filter; // La string complète à parser
    qi::rule<Iterator, Filter(), qi::space_type> filter1, filter2; // La string complète à parser

    select_r() : select_r::base_type(filter) {
        txt = qi::lexeme[+(qi::alnum|qi::char_("_:-"))];
        txt2 = qi::lexeme[+(qi::alnum|qi::char_("_:-=.<> "))];
        bin_op =  qi::string("<=")[qi::_val = LEQ]
                | qi::string(">=")[qi::_val = GEQ]
                | qi::string("<>")[qi::_val = NEQ]
                | qi::string("<") [qi::_val = LT]
                | qi::string(">") [qi::_val = GT]
                | qi::string("=") [qi::_val = EQ];

        filter1 = (txt >> "." >> txt >> bin_op >> txt)[qi::_val = boost::phoenix::construct<Filter>(qi::_1, qi::_2, qi::_3, qi::_4)];
        filter2 = (txt >> "HAVING" >> '(' >> txt2 >> ')')[qi::_val = boost::phoenix::construct<Filter>(qi::_1, qi::_2)];
        filter %= (filter1 | filter2) % qi::lexeme["and"];
    }

};

// vérification d'une clause WHERE
template<class T>
WhereWrapper<T> build_clause(std::vector<Filter> filters) {
    WhereWrapper<T> wh(new BaseWhere<T>());
    for(const Filter & filter : filters) {
        if(filter.attribute == "id")
            wh = wh && WHERE(ptr_id<T>(), filter.op, filter.value);
        else if(filter.attribute == "idx")
            wh = wh && WHERE(ptr_idx<T>(), filter.op, filter.value);
        else if(filter.attribute == "external_code")
            wh = wh && WHERE(ptr_external_code<T>(), filter.op, filter.value);
        else if(filter.attribute == "name")
            wh = wh && WHERE(ptr_name<T>(), filter.op, filter.value);
        }
    return wh;
}

pbnavitia::Response extract_data(Data & data, Type_e requested_type, std::vector<idx_t> & rows, const int depth) {
    pbnavitia::Response result;
    result.set_requested_api(pbnavitia::PTREFERENTIAL);
    pbnavitia::PTReferential * pb_response = result.mutable_ptref();

    for(idx_t idx : rows){
        switch(requested_type){
        case Type_e::eLine: fill_pb_object(idx, data, pb_response->add_line(), depth); break;
        case Type_e::eRoute: fill_pb_object(idx, data, pb_response->add_route(), depth); break;
        case Type_e::eStopPoint: fill_pb_object(idx, data, pb_response->add_stop_point(), depth); break;
        case Type_e::eStopArea: fill_pb_object(idx, data, pb_response->add_stop_area(), depth); break;
        case Type_e::eNetwork: fill_pb_object(idx, data, pb_response->add_network(), depth); break;
        case Type_e::eMode: fill_pb_object(idx, data, pb_response->add_commercial_mode(), depth); break;
        case Type_e::eModeType: fill_pb_object(idx, data, pb_response->add_physical_mode(), depth); break;
        case Type_e::eCity: fill_pb_object(idx, data, pb_response->add_city(), depth); break;
        case Type_e::eConnection: fill_pb_object(idx, data, pb_response->add_connection(), depth); break;
        case Type_e::eRoutePoint: fill_pb_object(idx, data, pb_response->add_route_point(), depth); break;
        case Type_e::eCompany: fill_pb_object(idx, data, pb_response->add_company(), depth); break;
        default: break;
        }
    }
    return result;
}

template<typename T, typename C>
std::vector<idx_t> filtered_indexes(const std::vector<T> & data, const C & clause){
    std::vector<idx_t> result;
    for(size_t i = 0; i < data.size(); ++i){
        if(clause(data[i]))
            result.push_back(i);
    }
    return result;
}

template<typename T>
std::vector<idx_t> get_indexes(Filter filter,  Type_e requested_type, Data & d) {
    auto & data = d.pt_data.get_data<T>();
    std::vector<idx_t> indexes;
    if(filter.op != HAVING) {
        indexes = filtered_indexes(data, build_clause<T>({filter})); // filtered.get_offsets();
    } else {
        indexes = make_query(nt::static_data::get()->typeByCaption(filter.object), filter.value, d);
    }

    Type_e current = filter.navitia_type;
    std::map<Type_e, Type_e> path = find_path(requested_type);
    while(path[current] != current){
        indexes = d.pt_data.get_target_by_source(current, path[current], indexes);
        current = path[current];
    }

    return indexes;
}

std::vector<Filter> parse(std::string request){
    std::string::iterator begin = request.begin();
    std::vector<Filter> filters;
    select_r<std::string::iterator> s;
    if (qi::phrase_parse(begin, request.end(), s, qi::space, filters)) {
        if(begin != request.end()) {
            std::string unparsed(begin, request.end());
            ptref_parsing_error error;
            error.type = ptref_parsing_error::partial_error;
            error.more = unparsed;
            throw error;
        }
    } else {
        ptref_parsing_error error;
        error.type = ptref_parsing_error::global_error;
        throw error;
    }
    return filters;
}

std::vector<idx_t> make_query(Type_e requested_type, std::string request, Data & data) {
    std::vector<Filter> filters;

    if(!request.empty()){
	filters = parse(request);
    }

    type::static_data * static_data = type::static_data::get();
    for(Filter & filter : filters){
        try {
            filter.navitia_type = static_data->typeByCaption(filter.object);
        } catch(...) {
            ptref_unknown_object error;
            error.more = filter.object;
            throw error;
        }
    }

    std::vector<idx_t> final_indexes = data.pt_data.get_all_index(requested_type);
    std::vector<idx_t> indexes;
    for(const Filter & filter : filters){
        switch(filter.navitia_type){
        case Type_e::eLine: indexes = get_indexes<Line>(filter, requested_type, data); break;
        case Type_e::eValidityPattern: indexes = get_indexes<ValidityPattern>(filter, requested_type, data); break;
        case Type_e::eRoute: indexes = get_indexes<Route>(filter, requested_type, data); break;
        case Type_e::eStopPoint: indexes = get_indexes<StopPoint>(filter, requested_type, data); break;
        case Type_e::eStopArea: indexes = get_indexes<StopArea>(filter, requested_type, data); break;
        case Type_e::eNetwork: indexes = get_indexes<Network>(filter, requested_type, data); break;
        case Type_e::eMode: indexes = get_indexes<Mode>(filter, requested_type, data); break;
        case Type_e::eModeType: indexes = get_indexes<ModeType>(filter, requested_type, data); break;
        case Type_e::eCity: indexes = get_indexes<City>(filter, requested_type, data); break;
        case Type_e::eConnection: indexes = get_indexes<Connection>(filter, requested_type, data); break;
        case Type_e::eRoutePoint: indexes = get_indexes<RoutePoint>(filter, requested_type, data); break;
        case Type_e::eCompany: indexes = get_indexes<Company>(filter, requested_type, data); break;
        default: break;
        }
        // Attention ! les structures doivent être triées !
        std::sort(indexes.begin(), indexes.end());
        std::vector<idx_t> tmp_indexes;
        std::back_insert_iterator< std::vector<idx_t> > it(tmp_indexes);
        std::set_intersection(final_indexes.begin(), final_indexes.end(), indexes.begin(), indexes.end(), it);
        final_indexes = tmp_indexes;
    }
    return final_indexes;
}

pbnavitia::Response query_pb(Type_e requested_type, std::string request, const int depth, Data & data){
    std::vector<idx_t> final_indexes;
    pbnavitia::Response pb_response;
    try {
        final_indexes = make_query(requested_type, request, data);
    } catch(ptref_parsing_error parse_error) {
        if(parse_error.type == ptref_parsing_error::error_type::partial_error) {
            pb_response.set_error("PTReferential : On n'a pas réussi à parser toute la requête. Non-interprété : >>" + parse_error.more + "<<");
        } else {
            pb_response.set_error("PTReferential : Impossible de parser la requête");
        }
        return pb_response;
    } catch(ptref_unknown_object unknown_obj_error) {
        pb_response.set_error("Objet NAViTiA inconnu : " + unknown_obj_error.more);
        return pb_response;
    }

    final_indexes = make_query(requested_type, request, data);
    return extract_data(data, requested_type, final_indexes, depth);
}

}} // navitia::ptref
<commit_msg>Ptref : on peut maintenant séparer les filtres par AND<commit_after>#include "ptreferential.h"
#include "reflexion.h"
#include "where.h"
#include "type/pb_converter.h"

#include <algorithm>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/phoenix1.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix1_binders.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/phoenix/object/construct.hpp>

//TODO: change!
using namespace navitia::type;
using namespace navitia::ptref;

namespace qi = boost::spirit::qi;

namespace navitia{ namespace ptref{
using namespace navitia::type;

namespace qi = boost::spirit::qi;

/// Fonction qui va lire une chaîne de caractère et remplir un vector de Filter
        template <typename Iterator>
        struct select_r
            : qi::grammar<Iterator, std::vector<Filter>(), qi::space_type>
{
    qi::rule<Iterator, std::string(), qi::space_type> txt, txt2; // Match une string
    qi::rule<Iterator, Operator_e(), qi::space_type> bin_op; // Match une operator binaire telle que <, =...
    qi::rule<Iterator, std::vector<Filter>(), qi::space_type> filter; // La string complète à parser
    qi::rule<Iterator, Filter(), qi::space_type> filter1, filter2; // La string complète à parser

    select_r() : select_r::base_type(filter) {
        txt = qi::lexeme[+(qi::alnum|qi::char_("_:-"))];
        txt2 = qi::lexeme[+(qi::alnum|qi::char_("_:-=.<> "))];
        bin_op =  qi::string("<=")[qi::_val = LEQ]
                | qi::string(">=")[qi::_val = GEQ]
                | qi::string("<>")[qi::_val = NEQ]
                | qi::string("<") [qi::_val = LT]
                | qi::string(">") [qi::_val = GT]
                | qi::string("=") [qi::_val = EQ];

        filter1 = (txt >> "." >> txt >> bin_op >> txt)[qi::_val = boost::phoenix::construct<Filter>(qi::_1, qi::_2, qi::_3, qi::_4)];
        filter2 = (txt >> "HAVING" >> '(' >> txt2 >> ')')[qi::_val = boost::phoenix::construct<Filter>(qi::_1, qi::_2)];
        filter %= (filter1 | filter2) % (qi::lexeme["and"] | qi::lexeme["AND"]) ;
    }

};

// vérification d'une clause WHERE
template<class T>
WhereWrapper<T> build_clause(std::vector<Filter> filters) {
    WhereWrapper<T> wh(new BaseWhere<T>());
    for(const Filter & filter : filters) {
        if(filter.attribute == "id")
            wh = wh && WHERE(ptr_id<T>(), filter.op, filter.value);
        else if(filter.attribute == "idx")
            wh = wh && WHERE(ptr_idx<T>(), filter.op, filter.value);
        else if(filter.attribute == "external_code")
            wh = wh && WHERE(ptr_external_code<T>(), filter.op, filter.value);
        else if(filter.attribute == "name")
            wh = wh && WHERE(ptr_name<T>(), filter.op, filter.value);
        }
    return wh;
}

pbnavitia::Response extract_data(Data & data, Type_e requested_type, std::vector<idx_t> & rows, const int depth) {
    pbnavitia::Response result;
    result.set_requested_api(pbnavitia::PTREFERENTIAL);
    pbnavitia::PTReferential * pb_response = result.mutable_ptref();

    for(idx_t idx : rows){
        switch(requested_type){
        case Type_e::eLine: fill_pb_object(idx, data, pb_response->add_line(), depth); break;
        case Type_e::eRoute: fill_pb_object(idx, data, pb_response->add_route(), depth); break;
        case Type_e::eStopPoint: fill_pb_object(idx, data, pb_response->add_stop_point(), depth); break;
        case Type_e::eStopArea: fill_pb_object(idx, data, pb_response->add_stop_area(), depth); break;
        case Type_e::eNetwork: fill_pb_object(idx, data, pb_response->add_network(), depth); break;
        case Type_e::eMode: fill_pb_object(idx, data, pb_response->add_commercial_mode(), depth); break;
        case Type_e::eModeType: fill_pb_object(idx, data, pb_response->add_physical_mode(), depth); break;
        case Type_e::eCity: fill_pb_object(idx, data, pb_response->add_city(), depth); break;
        case Type_e::eConnection: fill_pb_object(idx, data, pb_response->add_connection(), depth); break;
        case Type_e::eRoutePoint: fill_pb_object(idx, data, pb_response->add_route_point(), depth); break;
        case Type_e::eCompany: fill_pb_object(idx, data, pb_response->add_company(), depth); break;
        default: break;
        }
    }
    return result;
}

template<typename T, typename C>
std::vector<idx_t> filtered_indexes(const std::vector<T> & data, const C & clause){
    std::vector<idx_t> result;
    for(size_t i = 0; i < data.size(); ++i){
        if(clause(data[i]))
            result.push_back(i);
    }
    return result;
}

template<typename T>
std::vector<idx_t> get_indexes(Filter filter,  Type_e requested_type, Data & d) {
    auto & data = d.pt_data.get_data<T>();
    std::vector<idx_t> indexes;
    if(filter.op != HAVING) {
        indexes = filtered_indexes(data, build_clause<T>({filter})); // filtered.get_offsets();
    } else {
        indexes = make_query(nt::static_data::get()->typeByCaption(filter.object), filter.value, d);
    }

    Type_e current = filter.navitia_type;
    std::map<Type_e, Type_e> path = find_path(requested_type);
    while(path[current] != current){
        indexes = d.pt_data.get_target_by_source(current, path[current], indexes);
        current = path[current];
    }

    return indexes;
}

std::vector<Filter> parse(std::string request){
    std::string::iterator begin = request.begin();
    std::vector<Filter> filters;
    select_r<std::string::iterator> s;
    if (qi::phrase_parse(begin, request.end(), s, qi::space, filters)) {
        if(begin != request.end()) {
            std::string unparsed(begin, request.end());
            ptref_parsing_error error;
            error.type = ptref_parsing_error::partial_error;
            error.more = unparsed;
            throw error;
        }
    } else {
        ptref_parsing_error error;
        error.type = ptref_parsing_error::global_error;
        throw error;
    }
    return filters;
}

std::vector<idx_t> make_query(Type_e requested_type, std::string request, Data & data) {
    std::vector<Filter> filters;

    if(!request.empty()){
	filters = parse(request);
    }

    type::static_data * static_data = type::static_data::get();
    for(Filter & filter : filters){
        try {
            filter.navitia_type = static_data->typeByCaption(filter.object);
        } catch(...) {
            ptref_unknown_object error;
            error.more = filter.object;
            throw error;
        }
    }

    std::vector<idx_t> final_indexes = data.pt_data.get_all_index(requested_type);
    std::vector<idx_t> indexes;
    for(const Filter & filter : filters){
        switch(filter.navitia_type){
        case Type_e::eLine: indexes = get_indexes<Line>(filter, requested_type, data); break;
        case Type_e::eValidityPattern: indexes = get_indexes<ValidityPattern>(filter, requested_type, data); break;
        case Type_e::eRoute: indexes = get_indexes<Route>(filter, requested_type, data); break;
        case Type_e::eStopPoint: indexes = get_indexes<StopPoint>(filter, requested_type, data); break;
        case Type_e::eStopArea: indexes = get_indexes<StopArea>(filter, requested_type, data); break;
        case Type_e::eNetwork: indexes = get_indexes<Network>(filter, requested_type, data); break;
        case Type_e::eMode: indexes = get_indexes<Mode>(filter, requested_type, data); break;
        case Type_e::eModeType: indexes = get_indexes<ModeType>(filter, requested_type, data); break;
        case Type_e::eCity: indexes = get_indexes<City>(filter, requested_type, data); break;
        case Type_e::eConnection: indexes = get_indexes<Connection>(filter, requested_type, data); break;
        case Type_e::eRoutePoint: indexes = get_indexes<RoutePoint>(filter, requested_type, data); break;
        case Type_e::eCompany: indexes = get_indexes<Company>(filter, requested_type, data); break;
        default: break;
        }
        // Attention ! les structures doivent être triées !
        std::sort(indexes.begin(), indexes.end());
        std::vector<idx_t> tmp_indexes;
        std::back_insert_iterator< std::vector<idx_t> > it(tmp_indexes);
        std::set_intersection(final_indexes.begin(), final_indexes.end(), indexes.begin(), indexes.end(), it);
        final_indexes = tmp_indexes;
    }
    return final_indexes;
}

pbnavitia::Response query_pb(Type_e requested_type, std::string request, const int depth, Data & data){
    std::vector<idx_t> final_indexes;
    pbnavitia::Response pb_response;
    try {
        final_indexes = make_query(requested_type, request, data);
    } catch(ptref_parsing_error parse_error) {
        if(parse_error.type == ptref_parsing_error::error_type::partial_error) {
            pb_response.set_error("PTReferential : On n'a pas réussi à parser toute la requête. Non-interprété : >>" + parse_error.more + "<<");
        } else {
            pb_response.set_error("PTReferential : Impossible de parser la requête");
        }
        return pb_response;
    } catch(ptref_unknown_object unknown_obj_error) {
        pb_response.set_error("Objet NAViTiA inconnu : " + unknown_obj_error.more);
        return pb_response;
    }

    final_indexes = make_query(requested_type, request, data);
    return extract_data(data, requested_type, final_indexes, depth);
}

}} // navitia::ptref
<|endoftext|>


<commit_before>#include "../CPPace.Lib/Log.h"
#include "../CPPace.Lib/GraphIO.h"
#include "../CPPace.Lib/MinimumFillIn.h"

using namespace std;

int main(int argc, char *argv[]) {
  switch (argc) {
  case 1: {
    GraphIO::GraphContext context = GraphIO::read_from_stream(cin);
    stack<pair<int, int>> edges = MinimumFillIn::minimum_fill_in(context);
    while (!edges.empty()) {
      pair<int, int> edge = edges.top();
      edges.pop();
      cout << edge.first << " " << edge.second << endl;
    }
    break;
  }
  case 2: {
    GraphIO::GraphContext context = GraphIO::read_from_path(argv[1]);
    Log::info("NAME: .......... %s", argv[1]);
    Log::info("NUM_EDGES: ..... %d", context.graph.num_edges);
    Log::info("NUM_VERTICES: .. %d", context.graph.num_vertices);
    Log::info("========================================");

    stack<pair<int, int>> edges = MinimumFillIn::minimum_fill_in(context);
    Log::info("Solution:");
    while (!edges.empty()) {
      pair<int, int> edge = edges.top();
      edges.pop();
      Log::info("%s -- %s", context.vertex_name(edge.first).c_str(), context.vertex_name(edge.second).c_str());
    }
    break;
  }
  default:
    Log::error("Invalid arguments");
    break;
  }
}
<commit_msg>Fix Optil.io main case<commit_after>#include "../CPPace.Lib/Log.h"
#include "../CPPace.Lib/GraphIO.h"
#include "../CPPace.Lib/MinimumFillIn.h"

using namespace std;

int main(int argc, char *argv[]) {
  switch (argc) {
  case 1: {
    GraphIO::GraphContext context = GraphIO::read_from_stream(cin);
    stack<pair<int, int>> edges = MinimumFillIn::minimum_fill_in(context);
    while (!edges.empty()) {
      pair<int, int> edge = edges.top();
      edges.pop();
      cout << context.vertex_name(edge.first) << " " << context.vertex_name(edge.second) << endl;
    }
    break;
  }
  case 2: {
    GraphIO::GraphContext context = GraphIO::read_from_path(argv[1]);
    Log::info("NAME: .......... %s", argv[1]);
    Log::info("NUM_EDGES: ..... %d", context.graph.num_edges);
    Log::info("NUM_VERTICES: .. %d", context.graph.num_vertices);
    Log::info("========================================");

    stack<pair<int, int>> edges = MinimumFillIn::minimum_fill_in(context);
    Log::info("Solution:");
    while (!edges.empty()) {
      pair<int, int> edge = edges.top();
      edges.pop();
      Log::info("%s -- %s", context.vertex_name(edge.first).c_str(), context.vertex_name(edge.second).c_str());
    }
    break;
  }
  default:
    Log::error("Invalid arguments");
    break;
  }
}
<|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
/* -*- mode: C++; style: linux -*- */
/*
 * examples/dot-product.C
 *
 * Copyright (C) 2002, 2010 Bradford Hovinen <hovinen@cis.udel.edu>
 *
 * This file is part of LinBox.
 *
 *   LinBox is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as
 *   published by the Free Software Foundation, either version 2 of
 *   the License, or (at your option) any later version.
 *
 *   LinBox is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with LinBox.  If not, see
 *   <http://www.gnu.org/licenses/>.
 */

/** \file examples/dot-product.C
 * @example  examples/dot-product.C
 * \brief Timings on dot products of random vectors.
 * \ingroup examples
 *
 * \author Bradford Hovinen <hovinen@cis.udel.edu>
 *
 * Use of vectors meeting the LinBox dense and sparse vector archetypes
 * is illustrated and their dot-product times are benchmarked.
 *
 * Constructs random vectors and computes their dot product, giving the
 * required time.
 */

#include "linbox/linbox-config.h"

#include <iostream>

#include "linbox/field/modular.h"
#include "linbox/vector/vector-domain.h"
#include "linbox/vector/stream.h"
#include "linbox/util/commentator.h"

using namespace LinBox;

typedef Modular<uint32> Field;

// Constants: we are working with an n x n matrix over GF(q)
const int n = 10000000;
const double p = .001;
const int q = 32749;

/// no command line args
int main (int argc, char **argv)
{
	commentator.setMaxDepth (1);
	commentator.setReportStream (std::cout);

	Field F (q);

	RandomDenseStream<Field, Vector<Field>::Dense> factory1 (F, n);
	RandomSparseStream<Field, Vector<Field>::SparseSeq> factory2 (F, p, n);
	RandomSparseStream<Field, Vector<Field>::SparsePar> factory3 (F, p, n);

	Vector<Field>::Dense v1 (n), v2 (n);
	Vector<Field>::SparseSeq v3;
	Vector<Field>::SparsePar v4;

	factory1 >> v1 >> v2;
	factory2 >> v3;
	factory3 >> v4;

	VectorDomain<Field> VD (F);
	Field::Element res;

	commentator.start ("dense/dense dot product (1)");
	for (int i = 0; i < 1; i++)
		VD.dot (res, v1, v2);
	commentator.stop ("done");

	commentator.start ("dense/sparse sequence dot product (1000)");
	for (int i = 0; i < 1000; i++)
		VD.dot (res, v1, v3);
	commentator.stop ("done");

	commentator.start ("dense/sparse parallel dot product (1000)");
	for (int i = 0; i < 1000; i++)
		VD.dot (res, v1, v4);
	commentator.stop ("done");

	return 0;
}
<commit_msg>LinBox::uint32<commit_after>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
/* -*- mode: C++; style: linux -*- */
/*
 * examples/dot-product.C
 *
 * Copyright (C) 2002, 2010 Bradford Hovinen <hovinen@cis.udel.edu>
 *
 * This file is part of LinBox.
 *
 *   LinBox is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as
 *   published by the Free Software Foundation, either version 2 of
 *   the License, or (at your option) any later version.
 *
 *   LinBox is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with LinBox.  If not, see
 *   <http://www.gnu.org/licenses/>.
 */

/** \file examples/dot-product.C
 * @example  examples/dot-product.C
 * \brief Timings on dot products of random vectors.
 * \ingroup examples
 *
 * \author Bradford Hovinen <hovinen@cis.udel.edu>
 *
 * Use of vectors meeting the LinBox dense and sparse vector archetypes
 * is illustrated and their dot-product times are benchmarked.
 *
 * Constructs random vectors and computes their dot product, giving the
 * required time.
 */

#include "linbox/linbox-config.h"

#include <iostream>

#include "linbox/field/modular.h"
#include "linbox/vector/vector-domain.h"
#include "linbox/vector/stream.h"
#include "linbox/util/commentator.h"

using namespace LinBox;

typedef Modular<LinBox::uint32> Field;

// Constants: we are working with an n x n matrix over GF(q)
const int n = 10000000;
const double p = .001;
const int q = 32749;

/// no command line args
int main (int argc, char **argv)
{
	commentator.setMaxDepth (1);
	commentator.setReportStream (std::cout);

	Field F (q);

	RandomDenseStream<Field, Vector<Field>::Dense> factory1 (F, n);
	RandomSparseStream<Field, Vector<Field>::SparseSeq> factory2 (F, p, n);
	RandomSparseStream<Field, Vector<Field>::SparsePar> factory3 (F, p, n);

	Vector<Field>::Dense v1 (n), v2 (n);
	Vector<Field>::SparseSeq v3;
	Vector<Field>::SparsePar v4;

	factory1 >> v1 >> v2;
	factory2 >> v3;
	factory3 >> v4;

	VectorDomain<Field> VD (F);
	Field::Element res;

	commentator.start ("dense/dense dot product (1)");
	for (int i = 0; i < 1; i++)
		VD.dot (res, v1, v2);
	commentator.stop ("done");

	commentator.start ("dense/sparse sequence dot product (1000)");
	for (int i = 0; i < 1000; i++)
		VD.dot (res, v1, v3);
	commentator.stop ("done");

	commentator.start ("dense/sparse parallel dot product (1000)");
	for (int i = 0; i < 1000; i++)
		VD.dot (res, v1, v4);
	commentator.stop ("done");

	return 0;
}
<|endoftext|>


<commit_before>/**
 * @file llclipboard.cpp
 * @brief LLClipboard base class
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "linden_common.h"

#include "llclipboard.h"

#include "llerror.h"
#include "llmath.h"
#include "llstring.h"
#include "llview.h"
#include "llwindow.h"

LLClipboard::LLClipboard() :
	mGeneration(0)
{
	reset();
}

LLClipboard::~LLClipboard()
{
	reset();
}

void LLClipboard::reset()
{
	// Increment the clipboard count
	mGeneration++;
	// Clear the clipboard
	mObjects.clear();
	mCutMode = false;
	mString = LLWString();
}

// Copy the input uuid to the LL clipboard
bool LLClipboard::copyToClipboard(const LLUUID& src, const LLAssetType::EType type)
{
	reset();
	return addToClipboard(src, type);
}

// Add the input uuid to the LL clipboard
// Convert the uuid to string and concatenate that string to the system clipboard if legit
bool LLClipboard::addToClipboard(const LLUUID& src, const LLAssetType::EType type)
{
	bool res = false;
	if (src.notNull())
	{
		res = true;
		if (LLAssetType::lookupIsAssetIDKnowable(type))
		{
			LLWString source = utf8str_to_wstring(src.asString());
			res = addToClipboard(source, 0, source.size());
		}
		if (res)
		{
			mObjects.push_back(src);
			mGeneration++;
		}
	}
	return res;
}

bool LLClipboard::pasteFromClipboard(std::vector<LLUUID>& inv_objects) const
{
	bool res = false;
	S32 count = mObjects.size();
	if (count > 0)
	{
		res = true;
		inv_objects.clear();
		for (S32 i = 0; i < count; i++)
		{
			inv_objects.push_back(mObjects[i]);
		}
	}
	return res;
}

// Returns true if the LL Clipboard has pasteable items in it
bool LLClipboard::hasContents() const
{
	return (mObjects.size() > 0);
}

// Returns true if the input uuid is in the list of clipboard objects
bool LLClipboard::isOnClipboard(const LLUUID& object) const
{
	std::vector<LLUUID>::const_iterator iter = std::find(mObjects.begin(), mObjects.end(), object);
	return (iter != mObjects.end());
}

// Copy the input string to the LL and the system clipboard
bool LLClipboard::copyToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)
{
	reset();
	return addToClipboard(src, pos, len, use_primary);
}

// Concatenate the input string to the LL and the system clipboard
bool LLClipboard::addToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)
{
	const LLWString sep(utf8str_to_wstring(std::string(", ")));
	if (mString.length() == 0)
	{
		mString = src.substr(pos, len);
	}
	else
	{
		mString = mString + sep + src.substr(pos, len);
	}
	mGeneration++;
	return (use_primary ? LLView::getWindow()->copyTextToPrimary(mString) : LLView::getWindow()->copyTextToClipboard(mString));
}

// Copy the System clipboard to the output string.
// Manage the LL Clipboard / System clipboard consistency
bool LLClipboard::pasteFromClipboard(LLWString &dst, bool use_primary)
{
	bool res = (use_primary ? LLView::getWindow()->pasteTextFromPrimary(dst) : LLView::getWindow()->pasteTextFromClipboard(dst));
	if (res)
	{
		if (dst != mString)
		{
			// Invalidate the LL clipboard if the System had a different string in it (i.e. some copy/cut was done in some other app)
			reset();
		}
		mString = dst;
	}
	return res;
}

// Return true if there's something on the System clipboard
bool LLClipboard::isTextAvailable(bool use_primary) const
{
	return (use_primary ? LLView::getWindow()->isPrimaryTextAvailable() : LLView::getWindow()->isClipboardTextAvailable());
}

<commit_msg>EXP-1913 : Prevent text clipboard to zap inventory clipboard<commit_after>/**
 * @file llclipboard.cpp
 * @brief LLClipboard base class
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "linden_common.h"

#include "llclipboard.h"

#include "llerror.h"
#include "llmath.h"
#include "llstring.h"
#include "llview.h"
#include "llwindow.h"

LLClipboard::LLClipboard() :
	mGeneration(0)
{
	reset();
}

LLClipboard::~LLClipboard()
{
	reset();
}

void LLClipboard::reset()
{
	// Increment the clipboard count
	mGeneration++;
	// Clear the clipboard
	mObjects.clear();
	mCutMode = false;
	mString = LLWString();
}

// Copy the input uuid to the LL clipboard
bool LLClipboard::copyToClipboard(const LLUUID& src, const LLAssetType::EType type)
{
	reset();
	return addToClipboard(src, type);
}

// Add the input uuid to the LL clipboard
// Convert the uuid to string and concatenate that string to the system clipboard if legit
bool LLClipboard::addToClipboard(const LLUUID& src, const LLAssetType::EType type)
{
	bool res = false;
	if (src.notNull())
	{
		res = true;
		if (LLAssetType::lookupIsAssetIDKnowable(type))
		{
			LLWString source = utf8str_to_wstring(src.asString());
			res = addToClipboard(source, 0, source.size());
		}
		if (res)
		{
			mObjects.push_back(src);
			mGeneration++;
		}
	}
	return res;
}

bool LLClipboard::pasteFromClipboard(std::vector<LLUUID>& inv_objects) const
{
	bool res = false;
	S32 count = mObjects.size();
	if (count > 0)
	{
		res = true;
		inv_objects.clear();
		for (S32 i = 0; i < count; i++)
		{
			inv_objects.push_back(mObjects[i]);
		}
	}
	return res;
}

// Returns true if the LL Clipboard has pasteable items in it
bool LLClipboard::hasContents() const
{
	return (mObjects.size() > 0);
}

// Returns true if the input uuid is in the list of clipboard objects
bool LLClipboard::isOnClipboard(const LLUUID& object) const
{
	std::vector<LLUUID>::const_iterator iter = std::find(mObjects.begin(), mObjects.end(), object);
	return (iter != mObjects.end());
}

// Copy the input string to the LL and the system clipboard
bool LLClipboard::copyToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)
{
	return addToClipboard(src, pos, len, use_primary);
}

// Concatenate the input string to the LL and the system clipboard
bool LLClipboard::addToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)
{
	const LLWString sep(utf8str_to_wstring(std::string(", ")));
	if (mString.length() == 0)
	{
		mString = src.substr(pos, len);
	}
	else
	{
		mString = mString + sep + src.substr(pos, len);
	}
	return (use_primary ? LLView::getWindow()->copyTextToPrimary(mString) : LLView::getWindow()->copyTextToClipboard(mString));
}

// Copy the System clipboard to the output string.
// Manage the LL Clipboard / System clipboard consistency
bool LLClipboard::pasteFromClipboard(LLWString &dst, bool use_primary)
{
	bool res = (use_primary ? LLView::getWindow()->pasteTextFromPrimary(dst) : LLView::getWindow()->pasteTextFromClipboard(dst));
	if (res)
	{
		if (dst != mString)
		{
			// Invalidate the LL clipboard if the System had a different string in it (i.e. some copy/cut was done in some other app)
			reset();
		}
		mString = dst;
	}
	return res;
}

// Return true if there's something on the System clipboard
bool LLClipboard::isTextAvailable(bool use_primary) const
{
	return (use_primary ? LLView::getWindow()->isPrimaryTextAvailable() : LLView::getWindow()->isClipboardTextAvailable());
}

<|endoftext|>