<commit_before>#include "cmake_writer.h"
#include <fstream>
#include <iterator>
#include <sstream>
#include "settings_parser.h"

CmakeWriter::CmakeWriter(RepoSearcher searcher) : searcher_(searcher) {
  SettingsParser parse;
  parse.ParseSettings("./cmakemaker", libraries_);
}

void CmakeWriter::WriteCmakeFiles() {
  auto& main_dir = searcher_.SearchPath("./");
  WriteMain(main_dir);
  std::vector<RepoSearcher::directory> targets;
  for (auto& dir : main_dir.directories)
    targets.push_back(searcher_.SearchPathSubdirs(dir));
  searcher_.FindDependencies(targets, libraries_);

  int i = 0;
  for (auto& dir : main_dir.directories) WriteSubdir(dir, targets[i++]);
}

void CmakeWriter::WriteMain(RepoSearcher::directory& dir) {
  std::ofstream open("./CMakeLists.txt");

  open << "########### CMakeMaker autogenerated file ###########" << std::endl;
  open << "cmake_minimum_required(VERSION 3.0)" << std::endl
       << "project(cmakemaker_solution C CXX)" << std::endl
       << std::endl;

  open << "set (LIBRARY_OUTPUT_PATH Build_Output/libs CACHE PATH \"Lib path\")"
       << std::endl
       << "set(EXECUTABLE_OUTPUT_PATH Build_Output/bin CACHE PATH \"Exe "
          "path\")"
       << std::endl
       << "mark_as_advanced(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)"
       << std::endl
       << "add_definitions(-DUNICODE -D_UNICODE)" << std::endl
       << std::endl
       << "if (WIN32)" << std::endl
       << "  add_definitions(-DWindowsBuild)" << std::endl
       << "  set(CMAKE_CXX_FLAGS_RELEASE  \"${CMAKE_CXX_FLAGS_RELEASE} -MP\")"
       << std::endl
       << "else(WIN32)" << std::endl
       << "  add_definitions(-DUnixBuild)" << std::endl
       << "  set(CMAKE_CXX_FLAGS  \"${CMAKE_CXX_FLAGS} -fPIC\")" << std::endl
       << "endif(WIN32)" << std::endl << std::endl;

  for (auto& subdir : dir.directories)
    open << "add_subdirectory(" << subdir << ")" << std::endl;

  open.close();
}

void CmakeWriter::WriteSubdir(std::string dir_name,
                              RepoSearcher::directory& dir) {
  std::ofstream open(dir_name + "/CMakeLists.txt");
  std::string proj_name =
      dir_name.substr(dir_name.find_last_of('/') + 1, dir_name.size());

  open << "########### CMakeMaker autogenerated file ###########" << std::endl;
  open << "cmake_minimum_required(VERSION 3.0)" << std::endl << std::endl;

  bool cuda_compile = dir.files["cu"].fmap.empty() ? false : true;
  std::vector<std::string> extensions = {"cc", "cpp", "h", "cu", "cuh", "qml"};

  if (cuda_compile) open << "find_package(CUDA)" << std::endl;
  for (auto& lib : dir.libraries) {
    auto& lib_info = libraries_[lib];
    if (!lib_info.find_command.empty()) {
      open << "find_package(" << libraries_[lib].find_command;
      if (!lib_info.components.empty()) {
        open << " COMPONENTS" << std::endl;
        for (auto& mod : lib_info.components) open << "  " << mod << std::endl;
      }
      open << ")\n";
    }
  }

  open << std::endl << std::endl;

  if (cuda_compile) {
    open << "set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE OFF)" << std::endl
         << "set(CUDA_64_BIT_DEVICE_CODE ON)" << std::endl
         << "if(CUDA_FOUND)" << std::endl
         << "  add_definitions(-DCuda_Found)" << std::endl
         << "else(CUDA_FOUND)" << std::endl
         << "  message(\"Could not find the Cuda toolkit, the Cuda algorithms "
            "will not be built.\")"
         << std::endl
         << "endif(CUDA_FOUND)";
    open << std::endl << std::endl;
  }

  open << "set(cpp_files" << std::endl;
  for (auto& ext : extensions)
    for (auto& file : dir.files[ext].fmap)
      for (auto& pair : file.second) open << "  " << pair << std::endl;
  open << ")" << std::endl << std::endl;

  WriteSourceGroups(open, dir, extensions);

  if (!dir.moc_files.empty()) {
    open << "qt5_wrap_cpp(moc_files\n";
    for (auto& file : dir.moc_files) open << "  " + file + "\n";
    open << ")\n\n";

    if (!dir.precomp_h.empty() && !dir.precomp_cc.empty())
      open << "foreach(src_file ${moc_files})\n"
           << "  set_source_files_properties(${src_file} PROPERTIES "
              "COMPILE_FLAGS \"/Yu" +
                  dir.precomp_h.substr(dir.precomp_h.find_last_of('/') + 1,
                                       dir.precomp_h.size()) +
                  " /FI" +
                  dir.precomp_h.substr(dir.precomp_h.find_last_of('/') + 1,
                                       dir.precomp_h.size()) +
                  "\")\n"
           << "endforeach()\n\n";
  }

  if (dir_name.find("runnable_") != std::string::npos ||
      dir_name.find("cmd_") != std::string::npos ||
      dir_name.find("app_") != std::string::npos) {
    open << (cuda_compile ? "cuda_add_executable(" : "add_executable(");
    open << proj_name;
    if (dir_name.find("app_") != std::string::npos) open << " WIN32";
  } else if (dir_name.find("lib_") != std::string::npos ||
             dir_name.find("slib_") != std::string::npos ||
             dir_name.find("dlib_") != std::string::npos) {
    open << (cuda_compile ? "cuda_add_library(" : "add_library(");
    open << proj_name;
    if (dir_name.find("slib_") != std::string::npos)
      open << " STATIC";
    else
      open << " SHARED";
  }
  open << " ${cpp_files}";
  if (!dir.moc_files.empty()) open << " ${moc_files}";
  if (dir.files.find("qrc") != dir.files.end()) open << " ${qt_resources}";
  open << ")" << std::endl << std::endl;

  open << "include_directories(" << proj_name << std::endl;
  for (auto& d : dir.directories)
    if (!d.empty()) open << "  " << d << std::endl;
  for (auto& d : dir.include_dirs)
    if (!d.empty()) open << "  " << d << std::endl;
  for (auto& lib : dir.libraries)
    if (!libraries_[lib].include_dir.empty())
      open << "  " << libraries_[lib].include_dir << std::endl;
  if (cuda_compile)
    open << "  "
         << "${CUDA_INCLUDE_DIRS}" << std::endl;
  open << ")" << std::endl << std::endl;

  open << "target_link_libraries(" << proj_name << std::endl;
  for (auto& dep : dir.dependencies) open << "  " << dep << std::endl;
  for (auto& lib : dir.libraries)
    open << "  " << libraries_[lib].lib_dir << std::endl;
  if (cuda_compile)
    open << "  "
         << "${CUDA_LIBRARIES}" << std::endl;
  open << ")" << std::endl << std::endl;

  if (!dir.precomp_h.empty() && !dir.precomp_cc.empty()) {
    open << "if (MSVC)" << std::endl
         << "  set_target_properties(" << proj_name
         << " PROPERTIES COMPILE_FLAGS \"/Yu"
         << dir.precomp_h.substr(dir.precomp_h.find_last_of('/') + 1,
                                 dir.precomp_h.size())
         << "\")" << std::endl
         << "  set_source_files_properties(" << dir.precomp_cc
         << " PROPERTIES COMPILE_FLAGS \"/Yc"
         << dir.precomp_h.substr(dir.precomp_h.find_last_of('/') + 1,
                                 dir.precomp_h.size())
         << "\")" << std::endl
         << "endif(MSVC)";
  }

  open.close();
}

void CmakeWriter::WriteSourceGroups(std::ofstream& open,
                                    RepoSearcher::directory& dir,
                                    std::vector<std::string>& extensions) {
  for (auto& d : dir.directories) {
    auto group_name = d.substr(d.find_first_of('/') + 1, d.size());

    if (group_name.find('/') != std::string::npos) {
      std::vector<std::string> dir_names;
      while (group_name.find('/') != std::string::npos) {
        dir_names.push_back(
            group_name.substr(0, group_name.find_first_of('/')));
        group_name = group_name.substr(group_name.find_first_of('/') + 1,
                                       group_name.size());
      }
      dir_names.push_back(group_name);

      group_name = "";
      for (int i = 0; i < dir_names.size(); ++i)
        group_name += dir_names[i] + (i != dir_names.size() - 1 ? "\\\\" : "");
    }

    open << "source_group(" << group_name << " FILES" << std::endl;
    for (auto& ext : extensions)
      for (auto& file : dir.files[ext].fmap)
        if (file.first.compare(d) == 0)
          for (auto& pair : file.second) open << "  " << pair << std::endl;
    open << ")" << std::endl << std::endl;
  }
}
<commit_msg>- precompiled header stuff<commit_after>#include "cmake_writer.h"
#include <fstream>
#include <iterator>
#include <sstream>
#include "settings_parser.h"

CmakeWriter::CmakeWriter(RepoSearcher searcher) : searcher_(searcher) {
  SettingsParser parse;
  parse.ParseSettings("./cmakemaker", libraries_);
}

void CmakeWriter::WriteCmakeFiles() {
  auto& main_dir = searcher_.SearchPath("./");
  WriteMain(main_dir);
  std::vector<RepoSearcher::directory> targets;
  for (auto& dir : main_dir.directories)
    targets.push_back(searcher_.SearchPathSubdirs(dir));
  searcher_.FindDependencies(targets, libraries_);

  int i = 0;
  for (auto& dir : main_dir.directories) WriteSubdir(dir, targets[i++]);
}

void CmakeWriter::WriteMain(RepoSearcher::directory& dir) {
  std::ofstream open("./CMakeLists.txt");

  open << "########### CMakeMaker autogenerated file ###########" << std::endl;
  open << "cmake_minimum_required(VERSION 3.0)" << std::endl
       << "project(cmakemaker_solution C CXX)" << std::endl
       << std::endl
       << std::endl;

  open
      << "macro(add_msvc_precompiled_header PrecompiledHeader "
         "PrecompiledSource SourcesVar)\n"
      << "  if(MSVC)\n"
      << "    get_filename_component(PrecompiledBasename ${PrecompiledHeader} "
         "NAME_WE)\n"
      << "    set(PrecompiledBinary \"$(IntDir)/${PrecompiledBasename}.pch\")\n"
      << "    set(Sources ${${SourcesVar}})\n"
      << "    set_source_files_properties(${Sources}\n"
      << "      PROPERTIES COMPILE_FLAGS \"/Yu\\\"${PrecompiledHeader}\\\" "
         "/FI\\\"${PrecompiledHeader}\\\" /Fp\\\"${PrecompiledBinary}\\\"\"\n"
      << "      OBJECT_DEPENDS \"${PrecompiledBinary}\")\n"
      << "    set_source_files_properties(${PrecompiledSource}\n"
      << "      PROPERTIES COMPILE_FLAGS \"/Yc\\\"${PrecompiledHeader}\\\" "
         "/FI\\\"${PrecompiledHeader}\\\" /Fp\\\"${PrecompiledBinary}\\\"\"\n"
      << "      OBJECT_OUTPUTS \"${PrecompiledBinary}\")\n"
      << "    list(APPEND ${SourcesVar} ${PrecompiledSource})\n"
      << "  endif(MSVC)\n"
      << "endmacro(add_msvc_precompiled_header)\n\n";

  open << "set (LIBRARY_OUTPUT_PATH Build_Output/libs CACHE PATH \"Lib path\")"
       << std::endl
       << "set(EXECUTABLE_OUTPUT_PATH Build_Output/bin CACHE PATH \"Exe "
          "path\")"
       << std::endl
       << "mark_as_advanced(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)"
       << std::endl
       << "add_definitions(-DUNICODE -D_UNICODE)" << std::endl
       << std::endl
       << "if (WIN32)" << std::endl
       << "  add_definitions(-DWindowsBuild)" << std::endl
       << "  set(CMAKE_CXX_FLAGS_RELEASE  \"${CMAKE_CXX_FLAGS_RELEASE} -MP\")"
       << std::endl
       << "else(WIN32)" << std::endl
       << "  add_definitions(-DUnixBuild)" << std::endl
       << "  set(CMAKE_CXX_FLAGS  \"${CMAKE_CXX_FLAGS} -fPIC\")" << std::endl
       << "endif(WIN32)" << std::endl
       << std::endl;

  for (auto& subdir : dir.directories)
    open << "add_subdirectory(" << subdir << ")" << std::endl;

  open.close();
}

void CmakeWriter::WriteSubdir(std::string dir_name,
                              RepoSearcher::directory& dir) {
  std::ofstream open(dir_name + "/CMakeLists.txt");
  std::string proj_name =
      dir_name.substr(dir_name.find_last_of('/') + 1, dir_name.size());
  std::vector<std::string> precomp_file_bundles, proj_names;
  proj_names.push_back(proj_name);

  open << "########### CMakeMaker autogenerated file ###########" << std::endl;
  open << "cmake_minimum_required(VERSION 3.0)" << std::endl << std::endl;

  bool cuda_compile = dir.files["cu"].fmap.empty() ? false : true;
  std::vector<std::string> extensions = {"cc", "cpp", "h", "cu", "cuh", "qml"};

  if (cuda_compile) open << "find_package(CUDA)" << std::endl;
  for (auto& lib : dir.libraries) {
    auto& lib_info = libraries_[lib];
    if (!lib_info.find_command.empty()) {
      open << "find_package(" << libraries_[lib].find_command;
      if (!lib_info.components.empty()) {
        open << " COMPONENTS" << std::endl;
        for (auto& mod : lib_info.components) open << "  " << mod << std::endl;
      }
      open << ")\n";
    }
  }

  open << std::endl << std::endl;

  if (cuda_compile) {
    open << "set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE OFF)" << std::endl
         << "set(CUDA_64_BIT_DEVICE_CODE ON)" << std::endl
         << "if(CUDA_FOUND)" << std::endl
         << "  add_definitions(-DCuda_Found)" << std::endl
         << "else(CUDA_FOUND)" << std::endl
         << "  message(\"Could not find the Cuda toolkit, the Cuda algorithms "
            "will not be built.\")"
         << std::endl
         << "endif(CUDA_FOUND)";
    open << std::endl << std::endl;
  }

  open << "set(cpp_files" << std::endl;
  for (auto& ext : extensions)
    for (auto& file : dir.files[ext].fmap)
      for (auto& pair : file.second) open << "  " << pair << std::endl;
  open << ")" << std::endl << std::endl;

  WriteSourceGroups(open, dir, extensions);

  if (!dir.moc_files.empty()) {
    open << "qt5_wrap_cpp(moc_files\n";
    for (auto& file : dir.moc_files) open << "  " + file + "\n";
    open << ")\n\n";

    if (!dir.precomp_h.empty() && !dir.precomp_cc.empty())
      precomp_file_bundles.push_back("moc_files");
  }

  if (!dir.precomp_h.empty() && !dir.precomp_cc.empty())
    precomp_file_bundles.push_back("cpp_files");

  for (auto& s : precomp_file_bundles)
    open << "add_msvc_precompiled_header(\"" +
                dir.precomp_h.substr(dir.precomp_h.find_last_of('/') + 1,
                                     dir.precomp_h.size()) +
                "\" "
                "\"" +
                dir.precomp_cc + "\" " + s + ")\n";

  if (dir_name.find("lib_") != std::string::npos &&
      dir_name.find("slib_") == std::string::npos &&
      dir_name.find("dlib_") == std::string::npos)
    proj_names.push_back("static_" + proj_name);

  int proj_count = 0;
  for (auto& p_name : proj_names) {
    if (dir_name.find("runnable_") != std::string::npos ||
        dir_name.find("cmd_") != std::string::npos ||
        dir_name.find("app_") != std::string::npos) {
      open << (cuda_compile ? "cuda_add_executable(" : "add_executable(");
      open << p_name;
      if (dir_name.find("app_") != std::string::npos) open << " WIN32";
    } else if (dir_name.find("lib_") != std::string::npos ||
               dir_name.find("slib_") != std::string::npos ||
               dir_name.find("dlib_") != std::string::npos) {
      open << (cuda_compile ? "cuda_add_library(" : "add_library(");
      open << p_name;
      if (dir_name.find("slib_") != std::string::npos)
        open << " STATIC";
      else if (dir_name.find("dlib_") != std::string::npos)
        open << " SHARED";
      else if (proj_count++ == 0)
        open << " SHARED";
      else
        open << " STATIC";
    }
    open << " ${cpp_files}";
    if (!dir.moc_files.empty()) open << " ${moc_files}";
    if (dir.files.find("qrc") != dir.files.end()) open << " ${qt_resources}";
    open << ")" << std::endl << std::endl;
  }

  for (auto& p_name : proj_names) {
    open << "include_directories(" << p_name << std::endl;
    for (auto& d : dir.directories)
      if (!d.empty()) open << "  " << d << std::endl;
    for (auto& d : dir.include_dirs)
      if (!d.empty()) open << "  " << d << std::endl;
    for (auto& lib : dir.libraries)
      if (!libraries_[lib].include_dir.empty())
        open << "  " << libraries_[lib].include_dir << std::endl;
    if (cuda_compile)
      open << "  "
           << "${CUDA_INCLUDE_DIRS}" << std::endl;
    open << ")" << std::endl << std::endl;

    open << "target_link_libraries(" << p_name << std::endl;
    for (auto& dep : dir.dependencies) open << "  " << dep << std::endl;
    for (auto& lib : dir.libraries)
      open << "  " << libraries_[lib].lib_dir << std::endl;
    if (cuda_compile)
      open << "  "
           << "${CUDA_LIBRARIES}" << std::endl;
    open << ")" << std::endl << std::endl;
  }

  open.close();
}

void CmakeWriter::WriteSourceGroups(std::ofstream& open,
                                    RepoSearcher::directory& dir,
                                    std::vector<std::string>& extensions) {
  for (auto& d : dir.directories) {
    auto group_name = d.substr(d.find_first_of('/') + 1, d.size());

    if (group_name.find('/') != std::string::npos) {
      std::vector<std::string> dir_names;
      while (group_name.find('/') != std::string::npos) {
        dir_names.push_back(
            group_name.substr(0, group_name.find_first_of('/')));
        group_name = group_name.substr(group_name.find_first_of('/') + 1,
                                       group_name.size());
      }
      dir_names.push_back(group_name);

      group_name = "";
      for (size_t i = 0; i < dir_names.size(); ++i)
        group_name += dir_names[i] + (i != dir_names.size() - 1 ? "\\\\" : "");
    }

    open << "source_group(" << group_name << " FILES" << std::endl;
    for (auto& ext : extensions)
      for (auto& file : dir.files[ext].fmap)
        if (file.first.compare(d) == 0)
          for (auto& pair : file.second) open << "  " << pair << std::endl;
    open << ")" << std::endl << std::endl;
  }
}
<|endoftext|>


<commit_before>
#include "loop.h"

#include "config.h"
#include "output.h"
#include "mode.h"

#include <QX11Info>
#include <QtCore/QDebug>

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>

using namespace KScreen;

Loop::Loop(QObject* parent): QObject(parent)
{
    QMetaObject::invokeMethod(this, "start");
}

Loop::~Loop()
{

}

void Loop::start()
{
    qDebug() << "START";
    Config* config = Config::current();
    config->outputs()[65]->setCurrentMode(70);
    qDebug() << "Setting config";
    Config::setConfig(config);
    qDebug() << "setted";
    printConfig();
}

void Loop::printConfig()
{
//     KScreen *screen = KScreen::self();
//     qDebug() << "Backend: " << screen->backend();

    Config *config = Config::current();
    qDebug() << "Screen:";
    qDebug() << "maxSize:" << config->screen()->maxSize();
    qDebug() << "minSize:" << config->screen()->minSize();
    qDebug() << "currentSize:" << config->screen()->currentSize();

    OutputList outputs = config->outputs();
    OutputList outputEnabled;
    Q_FOREACH(Output *output, outputs) {
        qDebug() << "Id: " << output->id();
        qDebug() << "Name: " << output->name();
        qDebug() << "Type: " << output->type();
        qDebug() << "Connected: " << output->isConnected();
        qDebug() << "Enabled: " << output->isEnabled();
        qDebug() << "Primary: " << output->isPrimary();
        qDebug() << "Pos: " << output->pos();
        if (output->currentMode()) {
            qDebug() << "Size: " << output->mode(output->currentMode())->size();
        }
        qDebug() << "Clones: " << output->clones().isEmpty();
        qDebug() << "Mode: " << output->currentMode();
        qDebug() << "Modes: ";

        ModeList modes = output->modes();
        Q_FOREACH(Mode* mode, modes) {
            qDebug() << "\t" << mode->id() << "  " << mode->name() << " " << mode->size() << " " << mode->refreshRate();
        }

        if (output->isEnabled()) {
            outputEnabled.insert(output->id(), output);
        }
        qDebug() << "\n==================================================\n";
    }
}
#include <loop.moc><commit_msg>EDID support<commit_after>
#include "loop.h"

#include "config.h"
#include "output.h"
#include "mode.h"
#include <edid.h>

#include <QX11Info>
#include <QtCore/QDebug>

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>

using namespace KScreen;

Loop::Loop(QObject* parent): QObject(parent)
{
    QMetaObject::invokeMethod(this, "start");
}

Loop::~Loop()
{

}

void Loop::start()
{
    qDebug() << "START";
    Config* config = Config::current();
    config->outputs()[65]->setCurrentMode(70);
    qDebug() << "Setting config";
    Config::setConfig(config);
    qDebug() << "setted";
    printConfig();
}

void Loop::printConfig()
{
//     KScreen *screen = KScreen::self();
//     qDebug() << "Backend: " << screen->backend();

    Config *config = Config::current();
    qDebug() << "Screen:";
    qDebug() << "maxSize:" << config->screen()->maxSize();
    qDebug() << "minSize:" << config->screen()->minSize();
    qDebug() << "currentSize:" << config->screen()->currentSize();

    OutputList outputs = config->outputs();
    OutputList outputEnabled;
    Q_FOREACH(Output *output, outputs) {
        qDebug() << "Id: " << output->id();
        qDebug() << "Name: " << output->name();
        qDebug() << "Type: " << output->type();
        qDebug() << "Connected: " << output->isConnected();
        qDebug() << "Enabled: " << output->isEnabled();
        qDebug() << "Primary: " << output->isPrimary();
        qDebug() << "Pos: " << output->pos();
        if (output->currentMode()) {
            qDebug() << "Size: " << output->mode(output->currentMode())->size();
        }
        qDebug() << "Clones: " << output->clones().isEmpty();
        qDebug() << "Mode: " << output->currentMode();
        qDebug() << "Modes: ";

        ModeList modes = output->modes();
        Q_FOREACH(Mode* mode, modes) {
            qDebug() << "\t" << mode->id() << "  " << mode->name() << " " << mode->size() << " " << mode->refreshRate();
        }

        Edid* edid = output->edid();
	qDebug() << "EDID Info: ";
	if (edid != 0) {
	    qDebug() << "\tDevice ID: " << edid->deviceId();
	    qDebug() << "\tName: " << edid->name();
	    qDebug() << "\tVendor: " << edid->vendor();
	    qDebug() << "\tSerial: " << edid->serial();
	    qDebug() << "\tEISA ID: " << edid->eisaId();
	    qDebug() << "\tHash: " << edid->hash();
	    qDebug() << "\tWidth: " << edid->width();
	    qDebug() << "\tHeight: " << edid->height();
	    qDebug() << "\tGamma: " << edid->gamma();
	    qDebug() << "\tRed: " << edid->red();
	    qDebug() << "\tGreen: " << edid->green();
	    qDebug() << "\tBlue: " << edid->blue();
	    qDebug() << "\tWhite: " << edid->white();
	} else {
	    qDebug() << "\tUnavailable";
	}

        if (output->isEnabled()) {
            outputEnabled.insert(output->id(), output);
        }
        qDebug() << "\n==================================================\n";
    }
}
#include <loop.moc><|endoftext|>


<commit_before>/*
 * main.cpp -- This file is part of primesieve
 *
 * Copyright (C) 2011 Kim Walisch, <kim.walisch@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

/**
 * @file  main.cpp
 * @brief Command-line version of primesieve, multi-threaded (OpenMP),
 *        compiles on many platforms.
 *
 * primesieve is a highly optimized implementation of the sieve of
 * Eratosthenes that finds prime numbers and prime k-tuplets (twin
 * primes, prime triplets, ...) up to 2^64 maximum.
 */

#include "../expr/ExpressionParser.h"
#include "../soe/ParallelPrimeSieve.h"
#include "../soe/pmath.h"
#include "../soe/cpuid.h"

/// declared in test.cpp
void test();

#include <stdint.h>
#include <exception>
#include <iostream>
#include <iomanip>    /* std::setw(int) */
#include <cstdlib>    /* std::exit(int) */
#include <string>
#include <cstring>    /* std::strlen(const char*) */
#include <cctype>     /* std::tolower(int) */
#include <sstream>

namespace {
  // Unfortunately there is no easy way to get the CPU L1 and L2 cache
  // size, these values are close for most x86-64 CPUs in 2011
  const uint32_t L1_CACHE_SIZE = 64;
  const uint32_t L2_CACHE_SIZE = 512;
  const uint64_t L2_THRESHOLD = ipow(10, 11) * 5;

  bool quietMode = false;
  bool showExpressionResults = false;

  uint64_t start = 0;         /* lower bound for sieving */
  uint64_t stop = 0;          /* upper bound for sieving */
  uint32_t sieveSize = 0;     /* sieve size in KiloBytes */
  uint32_t flags = 0;         /* settings */

  int maxThreads = ParallelPrimeSieve::getMaxThreads();
  int threads = -1;

  std::string primes[7] = { "Prime numbers", "Twin primes", "Prime triplets",
    "Prime quadruplets", "Prime quintuplets", "Prime sextuplets",
    "Prime septuplets" };
}

void version() {
  std::cout << "primesieve 2.0, <http://primesieve.googlecode.com>" << std::endl
            << "Copyright (C) 2011 Kim Walisch" << std::endl
            << "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>." << std::endl
            << "This is free software: you are free to change and redistribute it." << std::endl
            << "There is NO WARRANTY, to the extent permitted by law." << std::endl;
  std::exit(EXIT_SUCCESS);
}

void help() {
  std::cout << "Usage: primesieve START STOP [OPTION]..." << std::endl
            << "Use the sieve of Eratosthenes to find the prime numbers and prime" << std::endl
            << "k-tuplets between START and STOP < 2^64" << std::endl
            << std::endl
            << "Examples:" << std::endl
            << "  primesieve 1 10000000 -p1" << std::endl
            << "  primesieve 1 1e11 -s 32" << std::endl
            << "  primesieve 1e18 1e18+2**32 -c1234567" << std::endl
            << std::endl
            << "Options:" << std::endl
            << "  -c[N]         Count prime numbers and/or prime k-tuplets," << std::endl
            << "                e.g -c1 count prime numbers, -c3 count prime triplets, ..." << std::endl
            << "                N >= 1 and N <= 7" << std::endl
            << "  -p[N]         Print prime numbers or prime k-tuplets," << std::endl
            << "                e.g -p1 print prime numbers, -p2 print twin primes, ..." << std::endl
            << "                N >= 1 and N <= 7" << std::endl
            << "  -q            Quiet mode, print less output" << std::endl
            << "  -s <SIZE>     Set the sieve size in KiloBytes, e.g. -s 256," << std::endl
            << "                set SIZE to your CPU's L1/L2 cache size for best performance" << std::endl
            << "                SIZE >= 1 and SIZE <= 8192" << std::endl
            << "  -t <THREADS>  Set the number of threads for sieving, e.g. -t 4," << std::endl
            << "                THREADS >= 1 and THREADS <= " << maxThreads << " (CPU max threads)" << std::endl
            << "  -test         Run various sieving tests (single-threaded) and exit" << std::endl
            << "  -v            Print version and license information and exit" << std::endl;
  std::exit(EXIT_SUCCESS);
}

void error(const std::string &str1, const std::string &str2 = "") {
  std::cerr << str1 << str2 << std::endl
            << "Try `primesieve -help' for more information." << std::endl;
  std::exit(EXIT_FAILURE);
}

bool isDigits(const std::string &str) {
  if (str.length() == 0)
    return false;
  return str.find_first_not_of("0123456789") == std::string::npos;
}

/**
 * Process the command-line options.
 * @see help(void)
 */
void processOptions(int argc, char* argv[]) {
  if (argc < 2 || argc > 20)
    help();
  ExpressionParser<uint64_t> parser;
  int i = 1;

  // process the START and STOP number
  if (argc > 2) {
    if (!isDigits(argv[i]))
      showExpressionResults = true;
    if (!parser.eval(argv[i++]))
      error("START is not a valid expression: ", parser.getErrorMessage(false));
    start = parser.getResult();
    if (!isDigits(argv[i]))
      showExpressionResults = true;
    if (!parser.eval(argv[i++]))
      error("STOP is not a valid expression: ", parser.getErrorMessage(false));
    stop = parser.getResult();
  }

  // process the options ([OPTION]...)
  for (; i < argc; i++) {
    char* c = argv[i];
    if (*c != '-' && *c != '/')
      help();
    switch (std::tolower(*(++c)++)) {
      case 'c': do {
                  if (*c < '1' || *c > '7')
                    help();
                  flags |= COUNT_PRIMES << (*c - '1');
                } while (*(++c) != 0);
                break;
      case 'p': if (*c < '1' || *c > '7')
                  help();
                flags |= PRINT_PRIMES << (*c - '1');
                quietMode = true;
                break;
      case 'q': quietMode = true;
                break;
      case 's': if (!parser.eval(argv[++i]))
                  help();
                sieveSize = static_cast<uint32_t> (parser.getResult());
                if (sieveSize < 1 || sieveSize > 8192)
                  error("Sieve size must be >= 1 and <= 8192 KiloBytes");
                sieveSize = nextHighestPowerOf2(sieveSize);
                break;
      case 't': if (std::string("test").compare(++argv[i]) == 0) {
                  test();
                  std::exit(EXIT_SUCCESS);
                }
                if (!parser.eval(argv[++i]))
                  help();
                threads = static_cast<int> (parser.getResult());
                if (threads < 1 || threads > maxThreads) {
                  std::ostringstream message;
                  message << "Use a number of threads >= 1 and <= "
                          << maxThreads
                          << " for this CPU";
                  error(message.str());
                }
                break;
      case 'v': version();
      default : help();
    }
  }
  if ((flags & PRINT_FLAGS) && threads > 1)
    error("Printing is only allowed using a single thread");
}

/**
 * Process the command-line options and start sieving.
 */
int main(int argc, char* argv[]) {
  processOptions(argc, argv);
  int width = static_cast<int> (std::strlen("Sieve size"));
  std::cout.setf(std::ios::left);

  // display expression results
  if (!quietMode && showExpressionResults)
    std::cout << std::setw(width) << "START" << " = " << start << std::endl
              << std::setw(width) << "STOP"  << " = " << stop  << std::endl;
  if (start > stop)
    error("STOP must be >= START");
  if (stop >= UINT64_MAX - UINT32_MAX * UINT64_C(10))
    error("STOP must be < (2^64-1) - (2^32-1) * 10");

  // set default settings
  if ((flags & COUNT_FLAGS) == 0 && (flags & PRINT_FLAGS) == 0)
    flags |= COUNT_PRIMES;
  if ((flags & PRINT_FLAGS) == 0)
    flags |= PRINT_STATUS;
  if (sieveSize == 0)
    sieveSize = (stop < L2_THRESHOLD) ?L1_CACHE_SIZE :L2_CACHE_SIZE;

  if (!quietMode)
    std::cout << std::setw(width) << "Sieve size" << " = " << sieveSize
              << " KiloBytes" << std::endl;
  try {
    ParallelPrimeSieve primeSieve;
    primeSieve.setStartNumber(start);
    primeSieve.setStopNumber(stop);
    primeSieve.setSieveSize(sieveSize);
    primeSieve.setFlags(flags);

    if (threads == -1)
      threads = primeSieve.getIdealThreadCount();
    if (!quietMode)
      std::cout << std::setw(width) << "threads" << " = " << threads << std::endl;

    // start sieving primes
    primeSieve.sieve(threads);

    // get max output string length
    width = static_cast<int> (std::strlen("Time elapsed"));
    for (int i = 0; i < primeSieve.COUNTS_SIZE; i++) {
      if (flags & (COUNT_PRIMES << i)) {
        int length = static_cast<int> (primes[i].length());
        if (width < length)
          width = length;
      }
    }
    // print prime count results
    std::cout << std::endl;
    for (int i = 0; i < primeSieve.COUNTS_SIZE; i++) {
      if (flags & (COUNT_PRIMES << i))
        std::cout << std::setw(width) << primes[i] << " : " <<
            primeSieve.getCounts(i) << std::endl;
    }
    std::cout << std::setw(width) << "Time elapsed" << " : " <<
        primeSieve.getTimeElapsed() << " sec" << std::endl;
  }
  catch (std::exception& ex) {
    std::cerr << ex.what() << std::endl;
    std::exit(EXIT_FAILURE);
  }
  return 0;
}
<commit_msg>exceptions updated<commit_after>/*
 * main.cpp -- This file is part of primesieve
 *
 * Copyright (C) 2011 Kim Walisch, <kim.walisch@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

/**
 * @file  main.cpp
 * @brief Command-line version of primesieve, multi-threaded (OpenMP),
 *        compiles on many platforms.
 *
 * primesieve is a highly optimized implementation of the sieve of
 * Eratosthenes that finds prime numbers and prime k-tuplets (twin
 * primes, prime triplets, ...) up to 2^64 maximum.
 */

#include "../expr/ExpressionParser.h"
#include "../soe/ParallelPrimeSieve.h"
#include "../soe/pmath.h"
#include "../soe/cpuid.h"

/// declared in test.cpp
void test();

#include <stdint.h>
#include <exception>
#include <iostream>
#include <iomanip>    /* std::setw(int) */
#include <cstdlib>    /* std::exit(int) */
#include <string>
#include <cstring>    /* std::strlen(const char*) */
#include <cctype>     /* std::tolower(int) */
#include <sstream>

namespace {
  // Unfortunately there is no easy way to get the CPU L1 and L2 cache
  // size, these values are close for most x86-64 CPUs in 2011
  const uint32_t L1_CACHE_SIZE = 64;
  const uint32_t L2_CACHE_SIZE = 512;
  const uint64_t L2_THRESHOLD = ipow(10, 11) * 5;

  bool quietMode = false;
  bool showExpressionResults = false;

  uint64_t start = 0;         /* lower bound for sieving */
  uint64_t stop = 0;          /* upper bound for sieving */
  uint32_t sieveSize = 0;     /* sieve size in KiloBytes */
  uint32_t flags = 0;         /* settings */

  int maxThreads = ParallelPrimeSieve::getMaxThreads();
  int threads = -1;

  std::string primes[7] = { "Prime numbers", "Twin primes", "Prime triplets",
    "Prime quadruplets", "Prime quintuplets", "Prime sextuplets",
    "Prime septuplets" };
}

void version() {
  std::cout << "primesieve 2.0, <http://primesieve.googlecode.com>" << std::endl
            << "Copyright (C) 2011 Kim Walisch" << std::endl
            << "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>." << std::endl
            << "This is free software: you are free to change and redistribute it." << std::endl
            << "There is NO WARRANTY, to the extent permitted by law." << std::endl;
  std::exit(EXIT_SUCCESS);
}

void help() {
  std::cout << "Usage: primesieve START STOP [OPTION]..." << std::endl
            << "Use the sieve of Eratosthenes to find the prime numbers and prime" << std::endl
            << "k-tuplets between START and STOP < 2^64" << std::endl
            << std::endl
            << "Examples:" << std::endl
            << "  primesieve 1 10000000 -p1" << std::endl
            << "  primesieve 1 1e11 -s 32" << std::endl
            << "  primesieve 1e18 1e18+2**32 -c1234567" << std::endl
            << std::endl
            << "Options:" << std::endl
            << "  -c[N]        Count prime numbers and/or prime k-tuplets," << std::endl
            << "               e.g -c1 count prime numbers, -c3 count prime triplets, ..." << std::endl
            << "               N >= 1 and N <= 7" << std::endl
            << "  -p[N]        Print prime numbers or prime k-tuplets," << std::endl
            << "               e.g -p1 print prime numbers, -p2 print twin primes, ..." << std::endl
            << "               N >= 1 and N <= 7" << std::endl
            << "  -q           Quiet mode, print less output" << std::endl
            << "  -s <SIZE>    Set the sieve size in KiloBytes, e.g. -s 256," << std::endl
            << "               set SIZE to your CPU's L1/L2 cache size for best performance" << std::endl
            << "               SIZE >= 1 and SIZE <= 8192" << std::endl
            << "  -t <THREADS> Set the number of threads for sieving, e.g. -t 4," << std::endl
            << "               THREADS >= 1 and THREADS <= " << maxThreads << " (CPU max threads)" << std::endl
            << "  -test        Run various sieving tests and exit" << std::endl
            << "  -v           Print version and license information and exit" << std::endl;
  std::exit(EXIT_SUCCESS);
}

void exprError(const std::string &str) {
  std::cerr << "Error: \"" << str
            << "\" is not a valid arithmetic expression" << std::endl
            << "Try `primesieve -help' for more information." << std::endl;
  std::exit(EXIT_FAILURE);
}

bool isDigits(const std::string &str) {
  if (str.length() == 0)
    return false;
  return str.find_first_not_of("0123456789") == std::string::npos;
}

/**
 * Process the command-line options.
 * @see help(void)
 */
void processOptions(int argc, char* argv[]) {
  if (argc < 2 || argc > 20)
    help();
  ExpressionParser<uint64_t> parser;
  int i = 1;

  // process the START and STOP numbers
  if (argc > 2) {
    if (!isDigits(argv[i]))
      showExpressionResults = true;
    if (!parser.eval(argv[i]))
      exprError(argv[i]);
    start = parser.getResult();
    i++;
    if (!isDigits(argv[i]))
      showExpressionResults = true;
    if (!parser.eval(argv[i]))
      exprError(argv[i]);
    stop = parser.getResult();
    i++;
  }

  // process the options ([OPTION]...)
  for (; i < argc; i++) {
    char* c = argv[i];
    if (*c != '-' && *c != '/')
      help();
    switch (std::tolower(*(++c)++)) {
      case 'c': do {
                  if (*c < '1' || *c > '7')
                    help();
                  flags |= COUNT_PRIMES << (*c - '1');
                } while (*(++c) != 0);
                break;
      case 'p': if (*c < '1' || *c > '7')
                  help();
                flags |= PRINT_PRIMES << (*c - '1');
                quietMode = true;
                break;
      case 'q': quietMode = true;
                break;
      case 's': if (++i >= argc || !parser.eval(argv[i]))
                  help();
                sieveSize = static_cast<uint32_t> (parser.getResult());
                sieveSize = nextHighestPowerOf2(sieveSize);
                break;
      case 't': if (std::string("test").compare(++argv[i]) == 0) {
                  test();
                  std::exit(EXIT_SUCCESS);
                }
                if (++i >= argc || !parser.eval(argv[i]))
                  help();
                threads = static_cast<int> (parser.getResult());
                break;
      case 'v': version();
      default : help();
    }
  }
}

/**
 * Process the command-line options and start sieving.
 */
int main(int argc, char* argv[]) {
  processOptions(argc, argv);
  int width = static_cast<int> (std::strlen("Sieve size"));
  std::cout.setf(std::ios::left);

  // display expression results
  if (!quietMode && showExpressionResults)
    std::cout << std::setw(width) << "START" << " = " << start << std::endl
              << std::setw(width) << "STOP"  << " = " << stop  << std::endl;

  // set default settings
  if ((flags & COUNT_FLAGS) == 0 && (flags & PRINT_FLAGS) == 0)
    flags |= COUNT_PRIMES;
  if (!quietMode && (flags & PRINT_FLAGS) == 0)
    flags |= PRINT_STATUS;
  if (sieveSize == 0)
    sieveSize = (stop < L2_THRESHOLD) ?L1_CACHE_SIZE :L2_CACHE_SIZE;

  if (!quietMode)
    std::cout << std::setw(width) << "Sieve size" << " = " << sieveSize
              << " KiloBytes" << std::endl;
  try {
    ParallelPrimeSieve primeSieve;
    primeSieve.setStartNumber(start);
    primeSieve.setStopNumber(stop);
    primeSieve.setSieveSize(sieveSize);
    primeSieve.setFlags(flags);

    if (threads == -1)
      threads = primeSieve.getIdealThreadCount();
    if (!quietMode)
      std::cout << std::setw(width) << "Threads" << " = " << threads << std::endl;

    // start sieving primes
    primeSieve.sieve(threads);
    if ((flags & PRINT_STATUS) || (flags & PRINT_FLAGS))
      std::cout << std::endl;

    // get max output string length
    width = static_cast<int> (std::strlen("Time elapsed"));
    for (int i = 0; i < primeSieve.COUNTS_SIZE; i++) {
      if (flags & (COUNT_PRIMES << i)) {
        int length = static_cast<int> (primes[i].length());
        if (width < length)
          width = length;
      }
    }
    // print prime count results
    for (int i = 0; i < primeSieve.COUNTS_SIZE; i++) {
      if (flags & (COUNT_PRIMES << i))
        std::cout << std::setw(width) << primes[i] << " : " <<
            primeSieve.getCounts(i) << std::endl;
    }
    std::cout << std::setw(width) << "Time elapsed" << " : " <<
        primeSieve.getTimeElapsed() << " sec" << std::endl;
  }
  catch (std::exception& ex) {
    std::cerr << "Error: " << ex.what() << std::endl
              << "Try `primesieve -help' for more information." << std::endl;
    std::exit(EXIT_FAILURE);
  }
  return 0;
}
<|endoftext|>


<commit_before>/*
 * LRUCache.cpp
 *
 *  Created on: 2014-6-30
 *      Author: hanshuo
 */

#include"LRUCache.h"
#include"VNode.h"
#include"../Database/Database.h"
#include<stdio.h>
#include<algorithm>

int LRUCache::DEFAULT_CAPACITY = 1*1000*1000;

LRUCache::LRUCache(int _capacity)
{
	cout << "LRUCache initial..." << endl;
    this->capacity = _capacity > 0 ? _capacity : LRUCache::DEFAULT_CAPACITY;
    // we should guarantee the cache is big enough.
    this->capacity = std::max(this->capacity, VNode::MAX_CHILD_NUM * 2000);

    this->next = new int[this->capacity + 2];
    this->prev = new int[this->capacity + 2];
    this->keys = new int[this->capacity + 2];
    this->values = new VNode*[this->capacity + 2];
    this->next[LRUCache::START_INDEX] = LRUCache::END_INDEX;
    this->next[LRUCache::END_INDEX] = LRUCache::NULL_INDEX;
    this->prev[LRUCache::START_INDEX] = LRUCache::NULL_INDEX;
    this->prev[LRUCache::END_INDEX] = LRUCache::START_INDEX;
    this->size = 0;
    cout << "LRUCache initial finish" << endl;
}

LRUCache::~LRUCache()
{
    delete []this->next;
    delete []this->prev;
    delete []this->keys;
    delete []this->values;
}

/* load cache's elements from an exist data file. */
bool LRUCache::loadCache(string _filePath)
{
    this->dataFilePath = _filePath;

    FILE* filePtr = fopen(this->dataFilePath.c_str(),"rb");
    if (filePtr == NULL)
    {
        cerr << "error, can not load an exist data file. @LRUCache::loadCache"  << endl;
        return false;
    }

    int defaultLoadSize = this->capacity / 2;
    size_t vNodeSize = sizeof(VNode);
    int flag = 0;

    flag = fseek(filePtr, 0, SEEK_SET);

    if (flag != 0)
    {
        cerr << "error,can't seek to the fileLine. @LRUCache::loadCache" << endl;
        return false;
    }

    int _tmp_cycle_count = 0;

    while (this->size < defaultLoadSize)
    {
        VNode* nodePtr = new VNode();
        bool is_reach_EOF = feof(filePtr);
        bool is_node_read = (fread((char *)nodePtr,vNodeSize,1,filePtr) == 1);

        if (is_reach_EOF || !is_node_read)
        {
            break;
        }

        int pos = LRUCache::DEFAULT_NUM + this->size;
        this->setElem(pos, nodePtr->getFileLine(), nodePtr);

        //debug
        {
            if (_tmp_cycle_count != nodePtr->getFileLine())
            {
                stringstream _ss;
                _ss << "error file line: " << _tmp_cycle_count << " " << nodePtr->getFileLine() << " " << nodePtr->getChildNum() << endl;
                Database::log(_ss.str());
            }
        }

        _tmp_cycle_count ++;
    }

    fclose(filePtr);

    return true;
}

/* create a new empty data file, the original one will be overwrite. */
bool LRUCache::createCache(string _filePath)
{
    this->dataFilePath = _filePath;

    FILE* filePtr = fopen(this->dataFilePath.c_str(),"wb");
    if (filePtr == NULL)
    {
        cerr << "error, can not create a new data file. @LRUCache::createCache"  << endl;
        return false;
    }
    fclose(filePtr);

    return true;
}

/* set the key(node's file line) and value(node's pointer). if the key exists now, the value of this key will be overwritten. */
bool LRUCache::set(int _key, VNode * _value)
{
    map<int,int>::iterator iter = this->key2pos.find(_key);

    // if the _key is found, overwrite its mapping value.
    if (iter != this->key2pos.end())
    {
        int pos = iter->second;
        this->freeElem(pos);
        this->setElem(pos,_key,_value);
    }
    // if the cache is not full now, just put the key-value to the free slot.
    else if (this->size < this->capacity)
    {
        int pos = LRUCache::DEFAULT_NUM + this->size;
        this->setElem(pos,_key,_value);
    }
    // if the cache is full, should swap out the least recently used one to hard disk.
    else
    {
        // write out and free the memory of the least recently used one.
        int pos = this->next[LRUCache::START_INDEX];
        this->writeOut(pos, this->keys[pos]);
        this->freeElem(pos);

        // set the new one to the memory pool.
        this->setElem(pos,_key,_value);
    }
    return false;
}

/* get the value(node's pointer) by key(node's file line). */
VNode* LRUCache::get(int _key)
{
    VNode* ret = NULL;
    map<int,int>::iterator iter = this->key2pos.find(_key);

    if (iter != this->key2pos.end())
    {
        int pos = iter->second;
        ret = this->values[pos];
    }
    // the value is not in memory now, should load it from hard disk.
    else if (this->size < this->capacity)
    {
        int pos = LRUCache::DEFAULT_NUM + this->size;
        if (this->readIn(pos, _key))
        {
            ret = this->values[pos];
        }
    }
    // if the memory pool is full now, should swap out the least recently used one, and swap in the required value.
    else
    {
        int pos = this->next[LRUCache::START_INDEX];
        this->writeOut(pos, this->keys[pos]);
        this->freeElem(pos);

        if (this->readIn(pos, _key))
        {
            ret = this->values[pos];
        }
    }

    return ret;
}

/* update the _key's mapping _value. if the key do not exist, this operation will fail and return false. */
bool LRUCache::update(int _key, VNode* _value)
{
    // should swap it into cache first.
    VNode* valuePtr = this->get(_key);

    if (valuePtr != NULL)
    {
        int pos = this->key2pos[_key];
        if (this->keys[pos] != _key)
        {
            cerr << "error, the pos is wrong. @LRUCache::update"  << endl;
            return false;
        }

        this->values[pos] = _value;

        return true;
    }

    return false;
}

int LRUCache::getCapacity()
{
    return this->capacity;
}
int LRUCache::getRestAmount()
{
    return this->capacity - this->size;
}
void LRUCache::showAmount()
{
    printf(
    		"TotalAmount=%d\tUsedAmount=%d\tUsedPercent=%.2f%%\n",
    		this->capacity, this->size,
    		(double)this->size / this->capacity * 100.0);
}
bool LRUCache:: isFull()
{
    return this->size == this->capacity;
}

/* put the new visited one to the tail */
void LRUCache::refresh(int _pos)
{
    int prevPos,nextPos;

    prevPos = this->prev[_pos];
    nextPos = this->next[_pos];
    this->next[prevPos] = nextPos;
    this->prev[nextPos] = prevPos;

    prevPos = this->prev[LRUCache::END_INDEX];
    nextPos = LRUCache::END_INDEX;

    this->next[prevPos] = _pos;
    this->prev[nextPos] = _pos;

    this->next[_pos] = LRUCache::END_INDEX;
    this->prev[_pos] = prevPos;
}

/* free the memory of the _pos element in cache. */
void LRUCache:: freeElem(int _pos)
{
    delete this->values[_pos];
    this->key2pos.erase(this->keys[_pos]);
    this->keys[_pos] = LRUCache::NULL_INDEX;

    // update the double linked list.
    int prevPos = this->prev[_pos];
    int nextPos = this->next[_pos];
    this->next[prevPos] = nextPos;
    this->prev[nextPos] = prevPos;
    this->next[_pos] = LRUCache::NULL_INDEX;
    this->prev[_pos] = LRUCache::NULL_INDEX;

    this->size --;
}

/* set the memory of the _pos element in cache */
void LRUCache:: setElem(int _pos, int _key, VNode* _value)
{
    this->key2pos[_key] = _pos;
    this->keys[_pos] = _key;
    this->values[_pos] = _value;

    // put the new element to the tail of the linked list.
    int prevPos = this->prev[LRUCache::END_INDEX];
    int nextPos = LRUCache::END_INDEX;
    this->next[prevPos] = _pos;
    this->prev[nextPos] = _pos;
    this->next[_pos] = LRUCache::END_INDEX;
    this->prev[_pos] = prevPos;

    this->size ++;
}

/* just write the values[_pos] to the hard disk, the VNode in memory will not be free. */
bool LRUCache::writeOut(int _pos, int _fileLine)
{
    VNode* nodePtr = this->values[_pos];
    FILE* filePtr = fopen(this->dataFilePath.c_str(),"r+b");

    if (nodePtr == NULL)
    {
        cerr << "error, VNode do not exist. @LRUCache::writeOut" << endl;
        return false;
    }
    if (filePtr == NULL)
    {
        cerr << "error, can't open file. @LRUCache::writeOut" << endl;
        return false;
    }

    if (nodePtr->getFileLine() != _fileLine)
    {
        cerr << "error, fileLine " << _fileLine << "wrong. @LRUCache::writeOut" << endl;
    }

    int line = _fileLine == -1 ? nodePtr->getFileLine() : _fileLine;
    size_t vNodeSize = sizeof(VNode);
    int flag = 0;
    int seekPos = (long long)line * vNodeSize;

    flag = fseek(filePtr, seekPos, SEEK_SET);

    if (flag != 0)
    {
        cerr << "error, can't seek to the fileLine. @LRUCache::writeOut" << endl;
        return false;
    }

    fwrite((char *)nodePtr,vNodeSize,1,filePtr);
    fclose(filePtr);

    return true;
}

/* read the value from hard disk, and put it to the values[_pos].
 * before use it, you must make sure that the _pos element in cache is free(unoccupied).*/
bool LRUCache::readIn(int _pos, int _fileLine)
{
    VNode* nodePtr = new VNode();
    FILE* filePtr = fopen(this->dataFilePath.c_str(),"rb");

    if (nodePtr == NULL)
    {
        cerr << "error, can not new a VNode. @LRUCache::readIn" << endl;
        return false;
    }
    if (filePtr == NULL)
    {
        cerr << "error, can't open " <<
        		"[" << this->dataFilePath << "]" <<
        		". @LRUCache::readIn" << endl;
        return false;
    }

    int line = _fileLine;
    size_t vNodeSize = sizeof(VNode);
    int flag = 0;
    long long seekPos = (long long)line * vNodeSize;

    flag = fseek(filePtr, seekPos, SEEK_SET);

    if (flag != 0)
    {
        cerr << "error,can't seek to the fileLine. @LRUCache::readIn" << endl;
        return false;
    }

    bool is_node_read = (fread((char *)nodePtr,vNodeSize,1,filePtr) == 1);
    fclose(filePtr);

    if (nodePtr == NULL || nodePtr->getFileLine() != _fileLine)
    {
        cerr << "error,node fileLine error. @LRUCache::readIn" << endl;
    }

    this->setElem(_pos,_fileLine,nodePtr);

    return true;
}

/* write out all the elements to hard disk. */
bool LRUCache::flush()
{
    FILE* filePtr = fopen(this->dataFilePath.c_str(),"r+b");

    if (filePtr == NULL)
    {
        cerr << "error, can't open file. @LRUCache::flush" << endl;
        return false;
    }

    int startIndex = LRUCache::DEFAULT_NUM;
    int endIndex = startIndex + this->size;
    size_t vNodeSize = sizeof(VNode);

    for (int i=startIndex;i<endIndex;i++)
    {
        VNode* nodePtr = this->values[i];
        int line = this->keys[i];

        //debug
        {
            if (nodePtr->getFileLine() != line)
            {
                stringstream _ss;
                _ss << "line error at !!!" << line << " " << nodePtr->getFileLine() << endl;
                Database::log(_ss.str());
            }
        }

        if (nodePtr == NULL)
        {
            cerr << "error, VNode do not exist. @LRUCache::flush" << endl;
            return false;
        }

        int flag = 0;
        long long seekPos = (long long)line * vNodeSize;
        flag = fseek(filePtr, seekPos, SEEK_SET);

        if (flag != 0)
        {
            cerr << "error, can't seek to the fileLine. @LRUCache::flush" << endl;
            return false;
        }

        fwrite((char *)nodePtr,vNodeSize,1,filePtr);
    }
    fclose(filePtr);

    return true;
}
<commit_msg>find and fix a bug: change seekPos's data type from int to long long, by considering the situation when VSTree file's size exceed 2G bytes.<commit_after>/*
 * LRUCache.cpp
 *
 *  Created on: 2014-6-30
 *      Author: hanshuo
 */

#include"LRUCache.h"
#include"VNode.h"
#include"../Database/Database.h"
#include<stdio.h>
#include<algorithm>

int LRUCache::DEFAULT_CAPACITY = 1*1000*1000;

LRUCache::LRUCache(int _capacity)
{
	cout << "LRUCache initial..." << endl;
    this->capacity = _capacity > 0 ? _capacity : LRUCache::DEFAULT_CAPACITY;
    // we should guarantee the cache is big enough.
    this->capacity = std::max(this->capacity, VNode::MAX_CHILD_NUM * 2000);

    this->next = new int[this->capacity + 2];
    this->prev = new int[this->capacity + 2];
    this->keys = new int[this->capacity + 2];
    this->values = new VNode*[this->capacity + 2];
    this->next[LRUCache::START_INDEX] = LRUCache::END_INDEX;
    this->next[LRUCache::END_INDEX] = LRUCache::NULL_INDEX;
    this->prev[LRUCache::START_INDEX] = LRUCache::NULL_INDEX;
    this->prev[LRUCache::END_INDEX] = LRUCache::START_INDEX;
    this->size = 0;
    cout << "LRUCache initial finish" << endl;
}

LRUCache::~LRUCache()
{
    delete []this->next;
    delete []this->prev;
    delete []this->keys;
    delete []this->values;
}

/* load cache's elements from an exist data file. */
bool LRUCache::loadCache(string _filePath)
{
    this->dataFilePath = _filePath;

    FILE* filePtr = fopen(this->dataFilePath.c_str(),"rb");
    if (filePtr == NULL)
    {
        cerr << "error, can not load an exist data file. @LRUCache::loadCache"  << endl;
        return false;
    }

    int defaultLoadSize = this->capacity / 2;
    size_t vNodeSize = sizeof(VNode);
    int flag = 0;

    flag = fseek(filePtr, 0, SEEK_SET);

    if (flag != 0)
    {
        cerr << "error,can't seek to the fileLine. @LRUCache::loadCache" << endl;
        return false;
    }

    int _tmp_cycle_count = 0;

    while (this->size < defaultLoadSize)
    {
        VNode* nodePtr = new VNode();
        bool is_reach_EOF = feof(filePtr);
        bool is_node_read = (fread((char *)nodePtr,vNodeSize,1,filePtr) == 1);

        if (is_reach_EOF || !is_node_read)
        {
            break;
        }

        int pos = LRUCache::DEFAULT_NUM + this->size;
        this->setElem(pos, nodePtr->getFileLine(), nodePtr);

        //debug
        {
            if (_tmp_cycle_count != nodePtr->getFileLine())
            {
                stringstream _ss;
                _ss << "error file line: " << _tmp_cycle_count << " " << nodePtr->getFileLine() << " " << nodePtr->getChildNum() << endl;
                Database::log(_ss.str());
            }
        }

        _tmp_cycle_count ++;
    }

    fclose(filePtr);

    return true;
}

/* create a new empty data file, the original one will be overwrite. */
bool LRUCache::createCache(string _filePath)
{
    this->dataFilePath = _filePath;

    FILE* filePtr = fopen(this->dataFilePath.c_str(),"wb");
    if (filePtr == NULL)
    {
        cerr << "error, can not create a new data file. @LRUCache::createCache"  << endl;
        return false;
    }
    fclose(filePtr);

    return true;
}

/* set the key(node's file line) and value(node's pointer). if the key exists now, the value of this key will be overwritten. */
bool LRUCache::set(int _key, VNode * _value)
{
    map<int,int>::iterator iter = this->key2pos.find(_key);

    // if the _key is found, overwrite its mapping value.
    if (iter != this->key2pos.end())
    {
        int pos = iter->second;
        this->freeElem(pos);
        this->setElem(pos,_key,_value);
    }
    // if the cache is not full now, just put the key-value to the free slot.
    else if (this->size < this->capacity)
    {
        int pos = LRUCache::DEFAULT_NUM + this->size;
        this->setElem(pos,_key,_value);
    }
    // if the cache is full, should swap out the least recently used one to hard disk.
    else
    {
        // write out and free the memory of the least recently used one.
        int pos = this->next[LRUCache::START_INDEX];
        this->writeOut(pos, this->keys[pos]);
        this->freeElem(pos);

        // set the new one to the memory pool.
        this->setElem(pos,_key,_value);
    }
    return false;
}

/* get the value(node's pointer) by key(node's file line). */
VNode* LRUCache::get(int _key)
{
    VNode* ret = NULL;
    map<int,int>::iterator iter = this->key2pos.find(_key);

    if (iter != this->key2pos.end())
    {
        int pos = iter->second;
        ret = this->values[pos];
    }
    // the value is not in memory now, should load it from hard disk.
    else if (this->size < this->capacity)
    {
        int pos = LRUCache::DEFAULT_NUM + this->size;
        if (this->readIn(pos, _key))
        {
            ret = this->values[pos];
        }
    }
    // if the memory pool is full now, should swap out the least recently used one, and swap in the required value.
    else
    {
        int pos = this->next[LRUCache::START_INDEX];
        this->writeOut(pos, this->keys[pos]);
        this->freeElem(pos);

        if (this->readIn(pos, _key))
        {
            ret = this->values[pos];
        }
    }

    return ret;
}

/* update the _key's mapping _value. if the key do not exist, this operation will fail and return false. */
bool LRUCache::update(int _key, VNode* _value)
{
    // should swap it into cache first.
    VNode* valuePtr = this->get(_key);

    if (valuePtr != NULL)
    {
        int pos = this->key2pos[_key];
        if (this->keys[pos] != _key)
        {
            cerr << "error, the pos is wrong. @LRUCache::update"  << endl;
            return false;
        }

        this->values[pos] = _value;

        return true;
    }

    return false;
}

int LRUCache::getCapacity()
{
    return this->capacity;
}
int LRUCache::getRestAmount()
{
    return this->capacity - this->size;
}
void LRUCache::showAmount()
{
    printf(
    		"TotalAmount=%d\tUsedAmount=%d\tUsedPercent=%.2f%%\n",
    		this->capacity, this->size,
    		(double)this->size / this->capacity * 100.0);
}
bool LRUCache:: isFull()
{
    return this->size == this->capacity;
}

/* put the new visited one to the tail */
void LRUCache::refresh(int _pos)
{
    int prevPos,nextPos;

    prevPos = this->prev[_pos];
    nextPos = this->next[_pos];
    this->next[prevPos] = nextPos;
    this->prev[nextPos] = prevPos;

    prevPos = this->prev[LRUCache::END_INDEX];
    nextPos = LRUCache::END_INDEX;

    this->next[prevPos] = _pos;
    this->prev[nextPos] = _pos;

    this->next[_pos] = LRUCache::END_INDEX;
    this->prev[_pos] = prevPos;
}

/* free the memory of the _pos element in cache. */
void LRUCache:: freeElem(int _pos)
{
    delete this->values[_pos];
    this->key2pos.erase(this->keys[_pos]);
    this->keys[_pos] = LRUCache::NULL_INDEX;

    // update the double linked list.
    int prevPos = this->prev[_pos];
    int nextPos = this->next[_pos];
    this->next[prevPos] = nextPos;
    this->prev[nextPos] = prevPos;
    this->next[_pos] = LRUCache::NULL_INDEX;
    this->prev[_pos] = LRUCache::NULL_INDEX;

    this->size --;
}

/* set the memory of the _pos element in cache */
void LRUCache:: setElem(int _pos, int _key, VNode* _value)
{
    this->key2pos[_key] = _pos;
    this->keys[_pos] = _key;
    this->values[_pos] = _value;

    // put the new element to the tail of the linked list.
    int prevPos = this->prev[LRUCache::END_INDEX];
    int nextPos = LRUCache::END_INDEX;
    this->next[prevPos] = _pos;
    this->prev[nextPos] = _pos;
    this->next[_pos] = LRUCache::END_INDEX;
    this->prev[_pos] = prevPos;

    this->size ++;
}

/* just write the values[_pos] to the hard disk, the VNode in memory will not be free. */
bool LRUCache::writeOut(int _pos, int _fileLine)
{
    VNode* nodePtr = this->values[_pos];
    FILE* filePtr = fopen(this->dataFilePath.c_str(),"r+b");

    if (nodePtr == NULL)
    {
        cerr << "error, VNode do not exist. @LRUCache::writeOut" << endl;
        return false;
    }
    if (filePtr == NULL)
    {
        cerr << "error, can't open file. @LRUCache::writeOut" << endl;
        return false;
    }

    if (nodePtr->getFileLine() != _fileLine)
    {
        cerr << "error, fileLine " << _fileLine << "wrong. @LRUCache::writeOut" << endl;
    }

    int line = _fileLine == -1 ? nodePtr->getFileLine() : _fileLine;
    size_t vNodeSize = sizeof(VNode);
    int flag = 0;
    long long seekPos = (long long)line * vNodeSize;

    flag = fseek(filePtr, seekPos, SEEK_SET);

    if (flag != 0)
    {
        cerr << "error, can't seek to the fileLine. @LRUCache::writeOut" << endl;
        return false;
    }

    fwrite((char *)nodePtr,vNodeSize,1,filePtr);
    fclose(filePtr);

    return true;
}

/* read the value from hard disk, and put it to the values[_pos].
 * before use it, you must make sure that the _pos element in cache is free(unoccupied).*/
bool LRUCache::readIn(int _pos, int _fileLine)
{
    VNode* nodePtr = new VNode();
    FILE* filePtr = fopen(this->dataFilePath.c_str(),"rb");

    if (nodePtr == NULL)
    {
        cerr << "error, can not new a VNode. @LRUCache::readIn" << endl;
        return false;
    }
    if (filePtr == NULL)
    {
        cerr << "error, can't open " <<
        		"[" << this->dataFilePath << "]" <<
        		". @LRUCache::readIn" << endl;
        return false;
    }

    int line = _fileLine;
    size_t vNodeSize = sizeof(VNode);
    int flag = 0;
    long long seekPos = (long long)line * vNodeSize;

    flag = fseek(filePtr, seekPos, SEEK_SET);

    if (flag != 0)
    {
        cerr << "error,can't seek to the fileLine. @LRUCache::readIn" << endl;
        return false;
    }

    bool is_node_read = (fread((char *)nodePtr,vNodeSize,1,filePtr) == 1);
    fclose(filePtr);

    if (nodePtr == NULL || nodePtr->getFileLine() != _fileLine)
    {
        cerr << "error,node fileLine error. @LRUCache::readIn" << endl;
    }

    this->setElem(_pos,_fileLine,nodePtr);

    return true;
}

/* write out all the elements to hard disk. */
bool LRUCache::flush()
{
    FILE* filePtr = fopen(this->dataFilePath.c_str(),"r+b");

    if (filePtr == NULL)
    {
        cerr << "error, can't open file. @LRUCache::flush" << endl;
        return false;
    }

    int startIndex = LRUCache::DEFAULT_NUM;
    int endIndex = startIndex + this->size;
    size_t vNodeSize = sizeof(VNode);

    for (int i=startIndex;i<endIndex;i++)
    {
        VNode* nodePtr = this->values[i];
        int line = this->keys[i];

        //debug
        {
            if (nodePtr->getFileLine() != line)
            {
                stringstream _ss;
                _ss << "line error at !!!" << line << " " << nodePtr->getFileLine() << endl;
                Database::log(_ss.str());
            }
        }

        if (nodePtr == NULL)
        {
            cerr << "error, VNode do not exist. @LRUCache::flush" << endl;
            return false;
        }

        int flag = 0;
        long long seekPos = (long long)line * vNodeSize;
        flag = fseek(filePtr, seekPos, SEEK_SET);

        if (flag != 0)
        {
            cerr << "error, can't seek to the fileLine. @LRUCache::flush" << endl;
            return false;
        }

        fwrite((char *)nodePtr,vNodeSize,1,filePtr);
    }
    fclose(filePtr);

    return true;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: component.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hbrinkm $ $Date: 2007-02-21 13:36:51 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

/**
  Copyright 2005 Sun Microsystems, Inc.
  */

#ifndef _CPPUHELPTER_FACTORY_
#include <cppuhelper/factory.hxx>
#endif

#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#endif

#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_
#include <cppuhelper/implementationentry.hxx>
#endif

#ifndef INCLUDED_RTFTOK_SCANNERTESTSERVICE_HXX
#include <debugservices/rtftok/ScannerTestService.hxx>
#endif

#ifndef INCLUDED_RTFTOK_XMLSCANNER_HXX
#include <debugservices/rtftok/XMLScanner.hxx>
#endif

#ifndef INCLUDED_XXML_FILEXXMLREADER_HXX
#include <debugservices/xxml/FileXXmlReader.hxx>
#endif

#ifndef INCLUDED_XXML_STORAGEXXMLREADER_HXX
#include <debugservices/xxml/StorageXXmlReader.hxx>
#endif

#ifndef INCLUDED_ODSL_ODSLREADER_HXX
#include <debugservices/odsl/ODSLParser.hxx>
#endif

#ifndef INCLUDED_RTFSL_PARSER_HXX
#include <debugservices/rtfsl/RTFSLParser.hxx>
#endif

#ifndef INCLUDED_DOCTOK_SCANNERTESTSERVICE_HXX
#include <debugservices/doctok/DocTokTestService.hxx>
#endif

#ifndef INCLUDED_DOCTOK_ANALYZESERVICE_HXX
#include <debugservices/doctok/DocTokAnalyzeService.hxx>
#endif

#ifndef INCLUDED_OOXML_SCANNERTESTSERVICE_HXX
#include <debugservices/ooxml/OOXMLTestService.hxx>
#endif

using namespace com::sun::star;

extern "C"
{
/* shared lib exports implemented with helpers */
static struct ::cppu::ImplementationEntry s_component_entries [] =
{//uno -l writerfilter.uno.dll -c debugservices.rtftok.ScannerTestService -- a b c
    RTFTOK_SCANNERTESTSERVICE_COMPONENT_ENTRY, /* debugservices.rtftok.ScannerTestService */
    RTFTOK_XMLSCANNER_COMPONENT_ENTRY, /* debugservices.rtftok.XMLScanner */
    XXML_FILEXXMLREADER_COMPONENT_ENTRY, /* debugservices.xxml.FileXXmlReader */
    XXML_STORAGEXXMLREADER_COMPONENT_ENTRY, /* debugservices.xxml.StorageXXmlReader */
    ODSL_ODSLREADER_COMPONENT_ENTRY, /* debugservices.odsl.ODSLReader */
    RTFSL_PARSER_COMPONENT_ENTRY, /* debugservices.rtfsl.RTFSLParser */
    DOCTOK_SCANNERTESTSERVICE_COMPONENT_ENTRY, /* debugservices.doctok.ScannerTestService */
    DOCTOK_ANALYZESERVICE_COMPONENT_ENTRY, /* debugservices.doctok.AnalyzeService */
    OOXML_SCANNERTESTSERVICE_COMPONENT_ENTRY, /* debugservices.ooxml.ScannerTestService */
    { 0, 0, 0, 0, 0, 0 } // terminate with NULL
};

    void SAL_CALL component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

sal_Bool SAL_CALL component_writeInfo( ::com::sun::star::lang::XMultiServiceFactory * xMgr, ::com::sun::star::registry::XRegistryKey * xRegistry )
{
    return ::cppu::component_writeInfoHelper( xMgr, xRegistry, s_component_entries );
}

void * SAL_CALL component_getFactory(sal_Char const * implName, ::com::sun::star::lang::XMultiServiceFactory * xMgr, ::com::sun::star::registry::XRegistryKey * xRegistry )
{
    return ::cppu::component_getFactoryHelper(implName, xMgr, xRegistry, s_component_entries );
}

}
<commit_msg>INTEGRATION: CWS xmlfilter02 (1.5.12); FILE MERGED 2007/12/07 12:47:51 hbrinkm 1.5.12.4: debugservices.ooxml.ScannerFastTestService removed 2007/12/07 09:41:03 hbrinkm 1.5.12.3: debugservices.ooxml.ScannerFastTestService removed 2007/10/09 09:32:08 hbrinkm 1.5.12.2: analyze service for ooxml 2007/10/01 10:43:52 os 1.5.12.1: integration of cws writerfilter3 into cws xmlfilter02<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: component.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2008-01-10 12:18:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

/**
  Copyright 2005 Sun Microsystems, Inc.
  */

#ifndef _CPPUHELPTER_FACTORY_
#include <cppuhelper/factory.hxx>
#endif

#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#endif

#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_
#include <cppuhelper/implementationentry.hxx>
#endif

#ifndef INCLUDED_RTFTOK_SCANNERTESTSERVICE_HXX
#include <debugservices/rtftok/ScannerTestService.hxx>
#endif

#ifndef INCLUDED_RTFTOK_XMLSCANNER_HXX
#include <debugservices/rtftok/XMLScanner.hxx>
#endif

#ifndef INCLUDED_XXML_FILEXXMLREADER_HXX
#include <debugservices/xxml/FileXXmlReader.hxx>
#endif

#ifndef INCLUDED_XXML_STORAGEXXMLREADER_HXX
#include <debugservices/xxml/StorageXXmlReader.hxx>
#endif

#ifndef INCLUDED_ODSL_ODSLREADER_HXX
#include <debugservices/odsl/ODSLParser.hxx>
#endif

#ifndef INCLUDED_RTFSL_PARSER_HXX
#include <debugservices/rtfsl/RTFSLParser.hxx>
#endif

#ifndef INCLUDED_DOCTOK_SCANNERTESTSERVICE_HXX
#include <debugservices/doctok/DocTokTestService.hxx>
#endif

#ifndef INCLUDED_DOCTOK_ANALYZESERVICE_HXX
#include <debugservices/doctok/DocTokAnalyzeService.hxx>
#endif

#ifndef INCLUDED_OOXML_SCANNERTESTSERVICE_HXX
#include <debugservices/ooxml/OOXMLTestService.hxx>
#endif

#ifndef INCLUDED_OOXML_ANALYZE_SERVICE_HXX
#include <debugservices/ooxml/OOXMLAnalyzeService.hxx>
#endif

#include <stdio.h>

using namespace com::sun::star;

extern "C"
{
/* shared lib exports implemented with helpers */
static struct ::cppu::ImplementationEntry s_component_entries [] =
{//uno -l writerfilter.uno.dll -c debugservices.rtftok.ScannerTestService -- a b c
    RTFTOK_SCANNERTESTSERVICE_COMPONENT_ENTRY, /* debugservices.rtftok.ScannerTestService */
    RTFTOK_XMLSCANNER_COMPONENT_ENTRY, /* debugservices.rtftok.XMLScanner */
    XXML_FILEXXMLREADER_COMPONENT_ENTRY, /* debugservices.xxml.FileXXmlReader */
    XXML_STORAGEXXMLREADER_COMPONENT_ENTRY, /* debugservices.xxml.StorageXXmlReader */
    ODSL_ODSLREADER_COMPONENT_ENTRY, /* debugservices.odsl.ODSLReader */
    RTFSL_PARSER_COMPONENT_ENTRY, /* debugservices.rtfsl.RTFSLParser */
    DOCTOK_SCANNERTESTSERVICE_COMPONENT_ENTRY, /* debugservices.doctok.ScannerTestService */
    DOCTOK_ANALYZESERVICE_COMPONENT_ENTRY, /* debugservices.doctok.AnalyzeService */
    OOXML_SCANNERTESTSERVICE_COMPONENT_ENTRY, /* debugservices.ooxml.ScannerTestService */
    OOXML_ANALYZESERVICE_COMPONENT_ENTRY, /* debugservices.ooxml.AnalyzeService */
    { 0, 0, 0, 0, 0, 0 } // terminate with NULL
};

    void SAL_CALL component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

sal_Bool SAL_CALL component_writeInfo( ::com::sun::star::lang::XMultiServiceFactory * xMgr, ::com::sun::star::registry::XRegistryKey * xRegistry )
{
    return ::cppu::component_writeInfoHelper( xMgr, xRegistry, s_component_entries );
}

void * SAL_CALL component_getFactory(sal_Char const * implName, ::com::sun::star::lang::XMultiServiceFactory * xMgr, ::com::sun::star::registry::XRegistryKey * xRegistry )
{
    fprintf(stderr, "Loading service: %s: ", implName);

    void * pResult = ::cppu::component_getFactoryHelper(implName, xMgr, xRegistry, s_component_entries );

    fprintf(stderr, "%p\n", pResult);

    return pResult;
}

}
<|endoftext|>


<commit_before>#pragma once

namespace QArtm {
class ImageWidget : public QWidget {
    Q_OBJECT
public:
    ImageWidget(QWidget * parent = 0);
    virtual ~ImageWidget();
    QImage& image() { return m_image; }
    void setImage( const QImage& image );
    QPicture& overlay() { return m_overlay; }
    void setOverlay( const QPicture& overlay ) { m_overlay = overlay; update(); }
    void clearOverlay( ) { m_overlay = QPicture(); }

signals:
    void rectSelected( const QRect& rect );
    void pointClicked( const QPoint& point, Qt::MouseButton button );

protected:
    virtual void paintEvent ( QPaintEvent * event );
    virtual QSize sizeHint () const;
    virtual void resizeEvent ( QResizeEvent * event );

    // mouse
    virtual void mousePressEvent( QMouseEvent * event );
    virtual void mouseReleaseEvent( QMouseEvent * event );
    virtual void mouseMoveEvent( QMouseEvent * event );

    QImage m_image;
    QPicture m_overlay;

    class Detail;
    QScopedPointer<Detail> m_detail;
};
}
<commit_msg>setImage/Overlay of ImageWidget are slots<commit_after>#pragma once

namespace QArtm {
class ImageWidget : public QWidget {
    Q_OBJECT
public:
    ImageWidget(QWidget * parent = 0);
    virtual ~ImageWidget();
    QImage& image() { return m_image; }
    QPicture& overlay() { return m_overlay; }
    void clearOverlay( ) { m_overlay = QPicture(); }

public slots:
    void setImage( const QImage& image );
    void setOverlay( const QPicture& overlay ) { m_overlay = overlay; update(); }

signals:
    void rectSelected( const QRect& rect );
    void pointClicked( const QPoint& point, Qt::MouseButton button );

protected:
    virtual void paintEvent ( QPaintEvent * event );
    virtual QSize sizeHint () const;
    virtual void resizeEvent ( QResizeEvent * event );

    // mouse
    virtual void mousePressEvent( QMouseEvent * event );
    virtual void mouseReleaseEvent( QMouseEvent * event );
    virtual void mouseMoveEvent( QMouseEvent * event );

    QImage m_image;
    QPicture m_overlay;

    class Detail;
    QScopedPointer<Detail> m_detail;
};
}
<|endoftext|>


<commit_before>#ifdef SEG_MIN
const int ID = INF;
int f(int a, int b) { return min(a, b); }
#else
const int ID = 0;
int f(int a, int b) { return a + b; }
#endif
struct segment_tree {
    int n; vi data, lazy;
    segment_tree() {}
    segment_tree(const vi &arr) : n(size(arr)), data(4*n), lazy(4*n,INF) {
        mk(arr, 0, n-1, 0); }
    int mk(const vi &arr, int l, int r, int i) {
        if (l == r) return data[i] = arr[l];
        int m = (l + r) / 2;
        return data[i] = f(mk(arr, l, m, 2*i+1), mk(arr, m+1, r, 2*i+2)); }
    int query(int a, int b) { return q(a, b, 0, n-1, 0); }
    int q(int a, int b, int l, int r, int i) {
        propagate(l, r, i);
        if (r < a || b < l) return ID;
        if (a <= l && r <= b) return data[i];
        int m = (l + r) / 2;
        return f(q(a, b, l, m, 2*i+1), q(a, b, m+1, r, 2*i+2)); }
    void update(int i, int v) { u(i, v, 0, n-1, 0); }
    int u(int i, int v, int l, int r, int j) {
        propagate(l, r, j);
        if (r < i || i < l) return data[j];
        if (l == i && r == i) return data[j] = v;
        int m = (l + r) / 2;
        return data[j] = f(u(i, v, l, m, 2*j+1), u(i, v, m+1, r, 2*j+2)); }
    void range_update(int a, int b, int v) { ru(a, b, v, 0, n-1, 0); }
    int ru(int a, int b, int v, int l, int r, int i) {
        propagate(l, r, i);
        if (l > r) return ID;
        if (r < a || b < l) return data[i];
        if (l == r) return data[i] += v;
        if (a <= l && r <= b) return (lazy[i] = v) * (r - l + 1) + data[i];
        int m = (l + r) / 2;
        return data[i] = f(ru(a, b, v, l, m, 2*i+1),
                           ru(a, b, v, m+1, r, 2*i+2));
    }
    void propagate(int l, int r, int i) {
        if (l > r || lazy[i] == INF) return;
        data[i] += lazy[i] * (r - l + 1);
        if (l < r) {
            if (lazy[2*i+1] == INF) lazy[2*i+1] = lazy[i];
            else lazy[2*i+1] += lazy[i];
            if (lazy[2*i+2] == INF) lazy[2*i+2] = lazy[i];
            else lazy[2*i+2] += lazy[i];
        }
        lazy[i] = INF;
    }
};
<commit_msg>Remove redundant code in Segment Tree<commit_after>#ifdef SEG_MIN
const int ID = INF;
int f(int a, int b) { return min(a, b); }
#else
const int ID = 0;
int f(int a, int b) { return a + b; }
#endif
struct segment_tree {
    int n; vi data, lazy;
    segment_tree() {}
    segment_tree(const vi &arr) : n(size(arr)), data(4*n), lazy(4*n,INF) {
        mk(arr, 0, n-1, 0); }
    int mk(const vi &arr, int l, int r, int i) {
        if (l == r) return data[i] = arr[l];
        int m = (l + r) / 2;
        return data[i] = f(mk(arr, l, m, 2*i+1), mk(arr, m+1, r, 2*i+2)); }
    int query(int a, int b) { return q(a, b, 0, n-1, 0); }
    int q(int a, int b, int l, int r, int i) {
        propagate(l, r, i);
        if (r < a || b < l) return ID;
        if (a <= l && r <= b) return data[i];
        int m = (l + r) / 2;
        return f(q(a, b, l, m, 2*i+1), q(a, b, m+1, r, 2*i+2)); }
    void update(int i, int v) { u(i, v, 0, n-1, 0); }
    int u(int i, int v, int l, int r, int j) {
        propagate(l, r, j);
        if (r < i || i < l) return data[j];
        if (l == i && r == i) return data[j] = v;
        int m = (l + r) / 2;
        return data[j] = f(u(i, v, l, m, 2*j+1), u(i, v, m+1, r, 2*j+2)); }
    void range_update(int a, int b, int v) { ru(a, b, v, 0, n-1, 0); }
    int ru(int a, int b, int v, int l, int r, int i) {
        propagate(l, r, i);
        if (l > r) return ID;
        if (r < a || b < l) return data[i];
        if (a <= l && r <= b) return (lazy[i] = v) * (r - l + 1) + data[i];
        int m = (l + r) / 2;
        return data[i] = f(ru(a, b, v, l, m, 2*i+1),
                           ru(a, b, v, m+1, r, 2*i+2));
    }
    void propagate(int l, int r, int i) {
        if (l > r || lazy[i] == INF) return;
        data[i] += lazy[i] * (r - l + 1);
        if (l < r) {
            if (lazy[2*i+1] == INF) lazy[2*i+1] = lazy[i];
            else lazy[2*i+1] += lazy[i];
            if (lazy[2*i+2] == INF) lazy[2*i+2] = lazy[i];
            else lazy[2*i+2] += lazy[i];
        }
        lazy[i] = INF;
    }
};
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: LegendHelper.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 18:18:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CHART2_TOOLS_LEGENDHELPER_HXX
#define _CHART2_TOOLS_LEGENDHELPER_HXX

// header for class OUString
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _COM_SUN_STAR_CHART2_XLEGEND_HPP_
#include <com/sun/star/chart2/XLegend.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XDIAGRAM_HPP_
#include <com/sun/star/chart2/XDiagram.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

//-----------------------------------------------------------------------------
/**
*/

class LegendHelper
{
public:
    static ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XLegend >
        getLegend( const ::com::sun::star::uno::Reference<
                       ::com::sun::star::frame::XModel >& xModel
                 , const ::com::sun::star::uno::Reference<
                       ::com::sun::star::uno::XComponentContext >& xContext = 0
                 , bool bCreate = false );

    /** returns <FALSE/>, if either there is no legend at the diagram, or there
        is a legend which has a "Show" property of value <FALSE/>. Otherwise,
        <TRUE/> is returned.
     */
    static bool hasLegend( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > & xDiagram );
};

//.............................................................................
} //namespace chart
//.............................................................................
#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.7.126); FILE MERGED 2008/04/01 15:04:12 thb 1.7.126.3: #i85898# Stripping all external header guards 2008/04/01 10:50:28 thb 1.7.126.2: #i85898# Stripping all external header guards 2008/03/28 16:43:54 rt 1.7.126.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: LegendHelper.hxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _CHART2_TOOLS_LEGENDHELPER_HXX
#define _CHART2_TOOLS_LEGENDHELPER_HXX

// header for class OUString
#include <rtl/ustring.hxx>
#include <com/sun/star/chart2/XLegend.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>

//.............................................................................
namespace chart
{
//.............................................................................

//-----------------------------------------------------------------------------
/**
*/

class LegendHelper
{
public:
    static ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XLegend >
        getLegend( const ::com::sun::star::uno::Reference<
                       ::com::sun::star::frame::XModel >& xModel
                 , const ::com::sun::star::uno::Reference<
                       ::com::sun::star::uno::XComponentContext >& xContext = 0
                 , bool bCreate = false );

    /** returns <FALSE/>, if either there is no legend at the diagram, or there
        is a legend which has a "Show" property of value <FALSE/>. Otherwise,
        <TRUE/> is returned.
     */
    static bool hasLegend( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > & xDiagram );
};

//.............................................................................
} //namespace chart
//.............................................................................
#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <memory>
#include <thread>
#include <fstream>

#include "bm_sim/queue.h"
#include "bm_sim/packet.h"
#include "bm_sim/parser.h"
#include "bm_sim/tables.h"
#include "bm_sim/switch.h"
#include "bm_sim/event_logger.h"

#include "simple_router.h"
#include "primitives.h"
#include "simplelog.h"

#include "bm_runtime/bm_runtime.h"

class SimpleSwitch : public Switch {
public:
  SimpleSwitch(transmit_fn_t transmit_fn)
    : input_buffer(1024), output_buffer(128), transmit_fn(transmit_fn) {}

  int receive(int port_num, const char *buffer, int len) {
    static int pkt_id = 0;

    Packet *packet =
      new Packet(port_num, pkt_id++, 0, len, PacketBuffer(2048, buffer, len));

    ELOGGER->packet_in(*packet);

    input_buffer.push_front(std::unique_ptr<Packet>(packet));
    return 0;
  }

  void start_and_return() {
    std::thread t1(&SimpleSwitch::pipeline_thread, this);
    t1.detach();
    std::thread t2(&SimpleSwitch::transmit_thread, this);
    t2.detach();
  }

private:
  void pipeline_thread();
  void transmit_thread();

private:
  Queue<std::unique_ptr<Packet> > input_buffer;
  Queue<std::unique_ptr<Packet> > output_buffer;
  transmit_fn_t transmit_fn;
};

void SimpleSwitch::transmit_thread() {
  while(1) {
    std::unique_ptr<Packet> packet;
    output_buffer.pop_back(&packet);
    ELOGGER->packet_out(*packet);
    SIMPLELOG << "transmitting packet " << packet->get_packet_id() << std::endl;
    transmit_fn(packet->get_egress_port(), packet->data(), packet->get_data_size());
  }
}

void SimpleSwitch::pipeline_thread() {
  Pipeline *ingress_mau = this->get_pipeline("ingress");
  Pipeline *egress_mau = this->get_pipeline("egress");
  Parser *parser = this->get_parser("parser");
  Deparser *deparser = this->get_deparser("deparser");
  PHV *phv;

  while(1) {
    std::unique_ptr<Packet> packet;
    input_buffer.pop_back(&packet);
    phv = packet->get_phv();
    SIMPLELOG << "processing packet " << packet->get_packet_id() << std::endl;

    parser->parse(packet.get());
    ingress_mau->apply(packet.get());

    int egress_port = phv->get_field("standard_metadata.egress_port").get_int();
    SIMPLELOG << "egress port is " << egress_port << std::endl;

    if(egress_port == 0) {
      SIMPLELOG << "dropping packet\n";
    }
    else {
      packet->set_egress_port(egress_port);
      egress_mau->apply(packet.get());
      deparser->deparse(packet.get());
      output_buffer.push_front(std::move(packet));
    }
  }
}

/* Switch instance */

static SimpleSwitch *simple_switch;

int packet_accept(int port_num, const char *buffer, int len) {
  return simple_switch->receive(port_num, buffer, len);
}

void start_processing(transmit_fn_t transmit_fn) {
  simple_switch = new SimpleSwitch(transmit_fn);
  simple_switch->init_objects("simple_router.json");

  bm_runtime::start_server(simple_switch, 9090);

  // add_test_entry();

  simple_switch->start_and_return();
}

<commit_msg>updated simple_router target to support config_swap (meant as an example)<commit_after>#include <iostream>
#include <memory>
#include <thread>
#include <fstream>

#include "bm_sim/queue.h"
#include "bm_sim/packet.h"
#include "bm_sim/parser.h"
#include "bm_sim/tables.h"
#include "bm_sim/switch.h"
#include "bm_sim/event_logger.h"

#include "simple_router.h"
#include "primitives.h"
#include "simplelog.h"

#include "bm_runtime/bm_runtime.h"

class SimpleSwitch : public Switch {
public:
  SimpleSwitch(transmit_fn_t transmit_fn)
    : Switch(true), // enable_switch = true
      input_buffer(1024), output_buffer(128), transmit_fn(transmit_fn) {}

  int receive(int port_num, const char *buffer, int len) {
    static int pkt_id = 0;

    Packet *packet =
      new Packet(port_num, pkt_id++, 0, len, PacketBuffer(2048, buffer, len));

    ELOGGER->packet_in(*packet);

    input_buffer.push_front(std::unique_ptr<Packet>(packet));
    return 0;
  }

  void start_and_return() {
    std::thread t1(&SimpleSwitch::pipeline_thread, this);
    t1.detach();
    std::thread t2(&SimpleSwitch::transmit_thread, this);
    t2.detach();
  }

private:
  void pipeline_thread();
  void transmit_thread();

private:
  Queue<std::unique_ptr<Packet> > input_buffer;
  Queue<std::unique_ptr<Packet> > output_buffer;
  transmit_fn_t transmit_fn;
};

void SimpleSwitch::transmit_thread() {
  while(1) {
    std::unique_ptr<Packet> packet;
    output_buffer.pop_back(&packet);
    ELOGGER->packet_out(*packet);
    SIMPLELOG << "transmitting packet " << packet->get_packet_id() << std::endl;
    transmit_fn(packet->get_egress_port(), packet->data(), packet->get_data_size());
  }
}

void SimpleSwitch::pipeline_thread() {
  Pipeline *ingress_mau = this->get_pipeline("ingress");
  Pipeline *egress_mau = this->get_pipeline("egress");
  Parser *parser = this->get_parser("parser");
  Deparser *deparser = this->get_deparser("deparser");
  PHV *phv;

  while(1) {
    std::unique_ptr<Packet> packet;
    input_buffer.pop_back(&packet);
    phv = packet->get_phv();
    SIMPLELOG << "processing packet " << packet->get_packet_id() << std::endl;

    // swap is enabled, so update pointers if needed
    if(this->do_swap() == 0) { // a swap took place
      ingress_mau = this->get_pipeline("ingress");
      egress_mau = this->get_pipeline("egress");
      parser = this->get_parser("parser");
      deparser = this->get_deparser("deparser");
    }

    parser->parse(packet.get());
    ingress_mau->apply(packet.get());

    int egress_port = phv->get_field("standard_metadata.egress_port").get_int();
    SIMPLELOG << "egress port is " << egress_port << std::endl;

    if(egress_port == 0) {
      SIMPLELOG << "dropping packet\n";
    }
    else {
      packet->set_egress_port(egress_port);
      egress_mau->apply(packet.get());
      deparser->deparse(packet.get());
      output_buffer.push_front(std::move(packet));
    }
  }
}

/* Switch instance */

static SimpleSwitch *simple_switch;

int packet_accept(int port_num, const char *buffer, int len) {
  return simple_switch->receive(port_num, buffer, len);
}

void start_processing(transmit_fn_t transmit_fn) {
  simple_switch = new SimpleSwitch(transmit_fn);
  simple_switch->init_objects("simple_router.json");

  bm_runtime::start_server(simple_switch, 9090);

  // add_test_entry();

  simple_switch->start_and_return();
}

<|endoftext|>