<commit_before>/*************************************
** Tsunagari Tile Engine            **
** window.cpp                       **
** Copyright 2016-2017 Paul Merrill **
*************************************/

// **********
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
// **********

#include "av/sdl2/window.h"

#include <chrono>
#include <thread>

#include "av/sdl2/error.h"
#include "core/client-conf.h"
#include "core/log.h"
#include "core/measure.h"
#include "core/world.h"
#include "util/optional.h"

#define CHECK(x)  if (!(x)) { return false; }

static SDL2GameWindow globalWindow;

GameWindow* GameWindow::create() {
    return globalWindow.init() ? &globalWindow
                               : nullptr;
}

GameWindow& GameWindow::instance() {
    return globalWindow;
}

SDL2GameWindow& SDL2GameWindow::instance() {
    return globalWindow;
}

time_t GameWindow::time() {
    std::chrono::time_point<std::chrono::steady_clock> start = globalWindow.start;
    std::chrono::time_point<std::chrono::steady_clock> end = std::chrono::steady_clock::now();
    return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}

SDL_Renderer* SDL2GetRenderer() {
    return globalWindow.renderer;
}

SDL2GameWindow::SDL2GameWindow()
    : renderer(nullptr),
      translation(0.0, 0.0),
      scaling(0.0, 0.0),
      window(nullptr),
      transform(Transform::identity()) {}

bool SDL2GameWindow::init() {
    {
        //TimeMeasure m("Initializing SDL2");
        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
            sdlDie("SDL2GameWindow", "SDL_Init");
            return false;
        }
    }

    {
        //TimeMeasure m("Created SDL2 window");

        int width = conf.windowSize.x;
        int height = conf.windowSize.y;

        Uint32 flags = SDL_WINDOW_HIDDEN;
        if (conf.fullscreen) {
            flags |= SDL_WINDOW_FULLSCREEN;
        }

        window = SDL_CreateWindow("Tsunagari",
                                  SDL_WINDOWPOS_UNDEFINED,
                                  SDL_WINDOWPOS_UNDEFINED,
                                  width, height, flags);

        if (window == nullptr) {
            sdlDie("SDL2GameWindow", "SDL_CreateWindow");
            return false;
        }
    }

    {
        //TimeMeasure m("Created SDL2 renderer");

        Uint32 flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;

        renderer = SDL_CreateRenderer(window, -1, flags);

        if (renderer == nullptr) {
            sdlDie("SDL2GameWindow", "SDL_CreateRenderer");
            return false;
        }
    }

    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);

    return true;
}

unsigned SDL2GameWindow::width() const {
    int w, h;
    SDL_GetWindowSize(window, &w, &h);
    return static_cast<unsigned>(w);
}

unsigned SDL2GameWindow::height() const {
    int w, h;
    SDL_GetWindowSize(window, &w, &h);
    return static_cast<unsigned>(h);
}

void SDL2GameWindow::setCaption(const std::string& caption) {
    SDL_SetWindowTitle(window, caption.c_str());
}

void SDL2GameWindow::mainLoop() {
    SDL_ShowWindow(window);
    while (window != nullptr) {
        handleEvents();
        World::instance().update(time());
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xFF);
        SDL_RenderClear(renderer);
        World::instance().draw();
        SDL_RenderPresent(renderer);
    }
}

void SDL2GameWindow::handleEvents() {
    SDL_Event event;

    while (SDL_PollEvent(&event)) {
        handleEvent(event);
    }
}

void SDL2GameWindow::handleEvent(const SDL_Event& event) {
    KeyboardKey key;

    switch (event.type) {
    case SDL_KEYUP:
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym) {
        case SDLK_ESCAPE: key = KBEscape; break;
        case SDLK_LCTRL: key = KBLeftControl; break;
        case SDLK_RCTRL: key = KBRightControl; break;
        case SDLK_LSHIFT: key = KBLeftShift; break;
        case SDLK_RSHIFT: key = KBRightShift; break;
        case SDLK_SPACE: key = KBSpace; break;
        case SDLK_LEFT: key = KBLeftArrow; break;
        case SDLK_RIGHT: key = KBRightArrow; break;
        case SDLK_UP: key = KBUpArrow; break;
        case SDLK_DOWN: key = KBDownArrow; break;
        default: return;
        }
        if (event.type == SDL_KEYUP) {
            emitKeyUp(key);
        }
        else if (event.type == SDL_KEYDOWN) {
            emitKeyDown(key);
        }
        break;

    case SDL_QUIT:
        SDL_DestroyWindow(window);
        exit(0);
        return;

    default:
        return;
    }
}

void SDL2GameWindow::drawRect(double x1, double x2, double y1, double y2,
              uint32_t argb) {
    auto a = static_cast<Uint8>((argb >> 24) & 0xFF);
    auto r = static_cast<Uint8>((argb >> 16) & 0xFF);
    auto g = static_cast<Uint8>((argb >>  8) & 0xFF);
    auto b = static_cast<Uint8>((argb >>  0) & 0xFF);

    SDL_Rect rect{static_cast<int>(x1),
                  static_cast<int>(y1),
                  static_cast<int>(x2 - x1),
                  static_cast<int>(y2 - y1)};

    SDL_SetRenderDrawColor(renderer, r, g, b, a);
    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
    SDL_RenderFillRect(renderer, &rect);
}

void SDL2GameWindow::scale(double x, double y, std::function<void()> op) {
    assert_(x == y);

    Transform prev = transform;

    auto factor = static_cast<float>(x);

    transform = Transform::scale(factor) * transform;
    updateTransform();

    op();

    transform = prev;
    updateTransform();
}

void SDL2GameWindow::translate(double x, double y, std::function<void()> op) {
    Transform prev = transform;

    transform = Transform::translate(static_cast<float>(x),
                                     static_cast<float>(y)) * transform;
    updateTransform();

    op();

    transform = prev;
    updateTransform();
}

void SDL2GameWindow::clip(double x, double y, double width, double height,
                          std::function<void()> op) {
    op();
}

void SDL2GameWindow::close() {
    SDL_DestroyWindow(window);
    window = nullptr;
}

void SDL2GameWindow::updateTransform() {
    int w, h;

    SDL_GetWindowSize(window, &w, &h);

    double xScale = transform[0];
    double yScale = transform[5];
    double x = transform[12];
    double y = transform[13];

    translation = {x / xScale, y / yScale};
    scaling = {xScale, yScale};
}
<commit_msg>av/sdl2: Skip redraws if no redraw needed<commit_after>/*************************************
** Tsunagari Tile Engine            **
** window.cpp                       **
** Copyright 2016-2017 Paul Merrill **
*************************************/

// **********
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
// **********

#include "av/sdl2/window.h"

#include <chrono>
#include <thread>

#include "av/sdl2/error.h"
#include "core/client-conf.h"
#include "core/log.h"
#include "core/measure.h"
#include "core/world.h"
#include "util/optional.h"

#define CHECK(x)  if (!(x)) { return false; }

static SDL2GameWindow globalWindow;

GameWindow* GameWindow::create() {
    return globalWindow.init() ? &globalWindow
                               : nullptr;
}

GameWindow& GameWindow::instance() {
    return globalWindow;
}

SDL2GameWindow& SDL2GameWindow::instance() {
    return globalWindow;
}

time_t GameWindow::time() {
    std::chrono::time_point<std::chrono::steady_clock> start = globalWindow.start;
    std::chrono::time_point<std::chrono::steady_clock> end = std::chrono::steady_clock::now();
    return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}

SDL_Renderer* SDL2GetRenderer() {
    return globalWindow.renderer;
}

SDL2GameWindow::SDL2GameWindow()
    : renderer(nullptr),
      translation(0.0, 0.0),
      scaling(0.0, 0.0),
      window(nullptr),
      transform(Transform::identity()) {}

bool SDL2GameWindow::init() {
    {
        //TimeMeasure m("Initializing SDL2");
        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
            sdlDie("SDL2GameWindow", "SDL_Init");
            return false;
        }
    }

    {
        //TimeMeasure m("Created SDL2 window");

        int width = conf.windowSize.x;
        int height = conf.windowSize.y;

        Uint32 flags = SDL_WINDOW_HIDDEN;
        if (conf.fullscreen) {
            flags |= SDL_WINDOW_FULLSCREEN;
        }

        window = SDL_CreateWindow("Tsunagari",
                                  SDL_WINDOWPOS_UNDEFINED,
                                  SDL_WINDOWPOS_UNDEFINED,
                                  width, height, flags);

        if (window == nullptr) {
            sdlDie("SDL2GameWindow", "SDL_CreateWindow");
            return false;
        }
    }

    {
        //TimeMeasure m("Created SDL2 renderer");

        Uint32 flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;

        renderer = SDL_CreateRenderer(window, -1, flags);

        if (renderer == nullptr) {
            sdlDie("SDL2GameWindow", "SDL_CreateRenderer");
            return false;
        }
    }

    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);

    return true;
}

unsigned SDL2GameWindow::width() const {
    int w, h;
    SDL_GetWindowSize(window, &w, &h);
    return static_cast<unsigned>(w);
}

unsigned SDL2GameWindow::height() const {
    int w, h;
    SDL_GetWindowSize(window, &w, &h);
    return static_cast<unsigned>(h);
}

void SDL2GameWindow::setCaption(const std::string& caption) {
    SDL_SetWindowTitle(window, caption.c_str());
}

static int getRefreshRate(SDL_Window* window) {
    // SDL_GetWindowDisplayIndex computes which display the window is on each
    // time.
    int display = SDL_GetWindowDisplayIndex(window);
    SDL_DisplayMode mode;
    SDL_GetCurrentDisplayMode(display, &mode);
    return mode.refresh_rate;
}

void SDL2GameWindow::mainLoop() {
    SDL_ShowWindow(window);
    while (window != nullptr) {
        handleEvents();
        World::instance().update(time());
        if (World::instance().needsRedraw()) {
            SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xFF);
            SDL_RenderClear(renderer);
            World::instance().draw();
            SDL_RenderPresent(renderer);
        } else {
            // TODO: Question: How do we handle freesync and gsync?
            std::chrono::duration<float> frameLength(1.0 / getRefreshRate(window));
            std::this_thread::sleep_for(frameLength);
        }
    }
}

void SDL2GameWindow::handleEvents() {
    SDL_Event event;

    while (SDL_PollEvent(&event)) {
        handleEvent(event);
    }
}

void SDL2GameWindow::handleEvent(const SDL_Event& event) {
    KeyboardKey key;

    switch (event.type) {
    case SDL_KEYUP:
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym) {
        case SDLK_ESCAPE: key = KBEscape; break;
        case SDLK_LCTRL: key = KBLeftControl; break;
        case SDLK_RCTRL: key = KBRightControl; break;
        case SDLK_LSHIFT: key = KBLeftShift; break;
        case SDLK_RSHIFT: key = KBRightShift; break;
        case SDLK_SPACE: key = KBSpace; break;
        case SDLK_LEFT: key = KBLeftArrow; break;
        case SDLK_RIGHT: key = KBRightArrow; break;
        case SDLK_UP: key = KBUpArrow; break;
        case SDLK_DOWN: key = KBDownArrow; break;
        default: return;
        }
        if (event.type == SDL_KEYUP) {
            emitKeyUp(key);
        }
        else if (event.type == SDL_KEYDOWN) {
            emitKeyDown(key);
        }
        break;

    case SDL_QUIT:
        SDL_DestroyWindow(window);
        exit(0);
        return;

    default:
        return;
    }
}

void SDL2GameWindow::drawRect(double x1, double x2, double y1, double y2,
              uint32_t argb) {
    auto a = static_cast<Uint8>((argb >> 24) & 0xFF);
    auto r = static_cast<Uint8>((argb >> 16) & 0xFF);
    auto g = static_cast<Uint8>((argb >>  8) & 0xFF);
    auto b = static_cast<Uint8>((argb >>  0) & 0xFF);

    SDL_Rect rect{static_cast<int>(x1),
                  static_cast<int>(y1),
                  static_cast<int>(x2 - x1),
                  static_cast<int>(y2 - y1)};

    SDL_SetRenderDrawColor(renderer, r, g, b, a);
    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
    SDL_RenderFillRect(renderer, &rect);
}

void SDL2GameWindow::scale(double x, double y, std::function<void()> op) {
    assert_(x == y);

    Transform prev = transform;

    auto factor = static_cast<float>(x);

    transform = Transform::scale(factor) * transform;
    updateTransform();

    op();

    transform = prev;
    updateTransform();
}

void SDL2GameWindow::translate(double x, double y, std::function<void()> op) {
    Transform prev = transform;

    transform = Transform::translate(static_cast<float>(x),
                                     static_cast<float>(y)) * transform;
    updateTransform();

    op();

    transform = prev;
    updateTransform();
}

void SDL2GameWindow::clip(double x, double y, double width, double height,
                          std::function<void()> op) {
    op();
}

void SDL2GameWindow::close() {
    SDL_DestroyWindow(window);
    window = nullptr;
}

void SDL2GameWindow::updateTransform() {
    int w, h;

    SDL_GetWindowSize(window, &w, &h);

    double xScale = transform[0];
    double yScale = transform[5];
    double x = transform[12];
    double y = transform[13];

    translation = {x / xScale, y / yScale};
    scaling = {xScale, yScale};
}
<|endoftext|>


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

  This source file is part of the OpenQube project.

  Copyright 2008-2010 Marcus D. Hanwell

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "basissetloader.h"

#include "gaussianset.h"
#include "slaterset.h"
#include "gamessukout.h"
#include "gaussianfchk.h"
#include "mopacaux.h"
#include "molden.h"
#include "gamessus.h"
#include "cube.h"

#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QStringList>

namespace OpenQube {

QString BasisSetLoader::MatchBasisSet(const QString& filename)
{
  QString matchedFile;
  if (filename.isEmpty())
    return matchedFile;

  QFileInfo parentInfo(filename);
  // Look for files with the same basename, but different extensions
  QDir parentDir = parentInfo.dir();
  QStringList nameFilters;
  nameFilters << parentInfo.baseName() + ".*";

  QStringList matchingFiles = parentDir.entryList(nameFilters,
                                                  QDir::Readable | QDir::Files);
  matchingFiles.prepend(parentInfo.fileName());

  // Iterate through the matches and see if we find a suitable file
  foreach(const QString &fileName, matchingFiles) {
    QString fullFileName = parentInfo.path() + '/' + fileName;
    QFileInfo info(fullFileName);
    QString completeSuffix = info.completeSuffix();

    if (completeSuffix.contains("fchk", Qt::CaseInsensitive)
        || completeSuffix.contains("fch", Qt::CaseInsensitive)
        || completeSuffix.contains("fck", Qt::CaseInsensitive)) {
      return fullFileName;
    }
    else if (completeSuffix.contains("gukout", Qt::CaseInsensitive)) {
      return fullFileName;
    }
    else if (completeSuffix.contains("aux", Qt::CaseInsensitive)) {
      return fullFileName;
    }
    else if (completeSuffix.contains("molden", Qt::CaseInsensitive)
        || completeSuffix.contains("mold", Qt::CaseInsensitive)
        || completeSuffix.contains("molf", Qt::CaseInsensitive)) {
     return fullFileName;
    }
    else if (completeSuffix.contains("gamess", Qt::CaseInsensitive)) {
      return fullFileName;
    }
  }
  return matchedFile;
}

BasisSet * BasisSetLoader::LoadBasisSet(const QString& filename)
{
  // Here we assume that the file name is correct, and attempt to load it.
  QFileInfo info(filename);
  QString completeSuffix = info.completeSuffix();
  if (completeSuffix.contains("fchk", Qt::CaseInsensitive)
      || completeSuffix.contains("fch", Qt::CaseInsensitive)
      || completeSuffix.contains("fck", Qt::CaseInsensitive)) {
    GaussianSet *gaussian = new GaussianSet;
    GaussianFchk fchk(filename, gaussian);

    return gaussian;
  }
  else if (completeSuffix.contains("gukout", Qt::CaseInsensitive)) {
    GaussianSet *gaussian = new GaussianSet;
    GamessukOut gukout(filename, gaussian);
    return gaussian;
  }
  else if (completeSuffix.contains("aux", Qt::CaseInsensitive)) {
    SlaterSet *slater = new SlaterSet;
    MopacAux aux(filename, slater);
    return slater;
  }
  else if (completeSuffix.contains("molden", Qt::CaseInsensitive)
      || completeSuffix.contains("mold", Qt::CaseInsensitive)
      || completeSuffix.contains("molf", Qt::CaseInsensitive)) {
   GaussianSet *gaussian = new GaussianSet;
   MoldenFile mold(filename, gaussian);
   return gaussian;
  }
  else if (completeSuffix.contains("gamess", Qt::CaseInsensitive)) {
    GaussianSet *gaussian = new GaussianSet;
    GAMESSUSOutput(filename, gaussian);
    return gaussian;
  }

  return 0;
}

} // End namespace
<commit_msg>Accept gamess or gamout as a file extension.<commit_after>/******************************************************************************

  This source file is part of the OpenQube project.

  Copyright 2008-2010 Marcus D. Hanwell

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "basissetloader.h"

#include "gaussianset.h"
#include "slaterset.h"
#include "gamessukout.h"
#include "gaussianfchk.h"
#include "mopacaux.h"
#include "molden.h"
#include "gamessus.h"
#include "cube.h"

#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QStringList>

namespace OpenQube {

QString BasisSetLoader::MatchBasisSet(const QString& filename)
{
  QString matchedFile;
  if (filename.isEmpty())
    return matchedFile;

  QFileInfo parentInfo(filename);
  // Look for files with the same basename, but different extensions
  QDir parentDir = parentInfo.dir();
  QStringList nameFilters;
  nameFilters << parentInfo.baseName() + ".*";

  QStringList matchingFiles = parentDir.entryList(nameFilters,
                                                  QDir::Readable | QDir::Files);
  matchingFiles.prepend(parentInfo.fileName());

  // Iterate through the matches and see if we find a suitable file
  foreach(const QString &fileName, matchingFiles) {
    QString fullFileName = parentInfo.path() + '/' + fileName;
    QFileInfo info(fullFileName);
    QString completeSuffix = info.completeSuffix();

    if (completeSuffix.contains("fchk", Qt::CaseInsensitive)
        || completeSuffix.contains("fch", Qt::CaseInsensitive)
        || completeSuffix.contains("fck", Qt::CaseInsensitive)) {
      return fullFileName;
    }
    else if (completeSuffix.contains("gamout", Qt::CaseInsensitive)
             || completeSuffix.contains("gamess", Qt::CaseInsensitive)) {
      return fullFileName;
    }
    else if (completeSuffix.contains("gukout", Qt::CaseInsensitive)) {
      return fullFileName;
    }
    else if (completeSuffix.contains("aux", Qt::CaseInsensitive)) {
      return fullFileName;
    }
    else if (completeSuffix.contains("molden", Qt::CaseInsensitive)
        || completeSuffix.contains("mold", Qt::CaseInsensitive)
        || completeSuffix.contains("molf", Qt::CaseInsensitive)) {
     return fullFileName;
    }
  }
  return matchedFile;
}

BasisSet * BasisSetLoader::LoadBasisSet(const QString& filename)
{
  // Here we assume that the file name is correct, and attempt to load it.
  QFileInfo info(filename);
  QString completeSuffix = info.completeSuffix();
  if (completeSuffix.contains("fchk", Qt::CaseInsensitive)
      || completeSuffix.contains("fch", Qt::CaseInsensitive)
      || completeSuffix.contains("fck", Qt::CaseInsensitive)) {
    GaussianSet *gaussian = new GaussianSet;
    GaussianFchk fchk(filename, gaussian);

    return gaussian;
  }
  else if (completeSuffix.contains("gamout", Qt::CaseInsensitive)
           || completeSuffix.contains("gamess", Qt::CaseInsensitive)) {
    GaussianSet *gaussian = new GaussianSet;
    GAMESSUSOutput gamout(filename, gaussian);
    return gaussian;
  }
  else if (completeSuffix.contains("gukout", Qt::CaseInsensitive)) {
    GaussianSet *gaussian = new GaussianSet;
    GamessukOut gukout(filename, gaussian);
    return gaussian;
  }
  else if (completeSuffix.contains("aux", Qt::CaseInsensitive)) {
    SlaterSet *slater = new SlaterSet;
    MopacAux aux(filename, slater);
    return slater;
  }
  else if (completeSuffix.contains("molden", Qt::CaseInsensitive)
      || completeSuffix.contains("mold", Qt::CaseInsensitive)
      || completeSuffix.contains("molf", Qt::CaseInsensitive)) {
   GaussianSet *gaussian = new GaussianSet;
   MoldenFile mold(filename, gaussian);
   return gaussian;
  }

  return 0;
}

} // End namespace
<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2012 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include "recommender_base.hpp"

using std::make_pair;
using std::pair;
using std::string;
using std::vector;

namespace jubatus {
namespace core {
namespace recommender {

class recommender_impl : public recommender_base {
 public:
  recommender_impl()
      : recommender_base() {
    // make mock
    orig_.set("r1", "a1", 1.0);
    orig_.set("r1", "a2", 1.0);

    orig_.set("r2", "b1", 1.0);
    orig_.set("r2", "b2", 1.0);

    orig_.set("r3", "a1", 1.0);
    orig_.set("r3", "b1", 1.0);
  }

  void similar_row(
      const common::sfv_t& query,
      vector<pair<string, float> >& ids,
      size_t ret_num) const {
    ids.clear();
    ids.push_back(make_pair("r1", 2.0));
    ids.push_back(make_pair("r3", 1.0));
  }

  void neighbor_row(
      const common::sfv_t& query,
      vector<pair<string, float> >& ids,
      size_t ret_num) const {
    ids.clear();
    ids.push_back(make_pair("r1", 1.0));
    ids.push_back(make_pair("r3", 2.0));
  }

  void clear() {
  }

  void clear_row(const string& id) {
  }

  void update_row(const string& id, const sfv_diff_t& diff) {
  }

  void get_all_row_ids(vector<string>& ids) const {
    ids.clear();
    ids.push_back("r1");
    ids.push_back("r2");
    ids.push_back("r3");
  }

  string type() const {
    return string("recommender_impl");
  }

  framework::mixable* get_mixable() const {}

  void pack(framework::packer&) const {
  }
  void unpack(msgpack::object) {
  }
};

TEST(recommender_base, complete_row) {
  recommender_impl r;
  common::sfv_t q;
  common::sfv_t ret;
  r.complete_row(q, ret);
  ASSERT_EQ(3u, ret.size());
  EXPECT_EQ("a1", ret[0].first);
  EXPECT_EQ("a2", ret[1].first);
  EXPECT_EQ("b1", ret[2].first);
}

TEST(recommender_base, get_all_row_ids) {
  vector<string> ids;
  recommender_impl r;
  r.get_all_row_ids(ids);
  ASSERT_EQ(3u, ids.size());
  sort(ids.begin(), ids.end());
  EXPECT_EQ("r1", ids[0]);
  EXPECT_EQ("r2", ids[1]);
  EXPECT_EQ("r3", ids[2]);
}

TEST(recommender_base, decode_row) {
  recommender_impl r;
  common::sfv_t v;
  r.decode_row("r1", v);
  ASSERT_EQ(2u, v.size());
  EXPECT_EQ("a1", v[0].first);
  EXPECT_EQ(1.0, v[0].second);
  EXPECT_EQ("a2", v[1].first);
  EXPECT_EQ(1.0, v[1].second);

  r.decode_row("r", v);
  ASSERT_TRUE(v.empty());
}

TEST(recommender_base, calc_l2norm) {
  recommender_impl r;
  common::sfv_t q;
  q.push_back(make_pair("a1", 1.0));
  q.push_back(make_pair("a2", 2.0));
  q.push_back(make_pair("a3", 3.0));

  EXPECT_FLOAT_EQ(std::sqrt(1.0 + 4.0 + 9.0), r.calc_l2norm(q));
}

TEST(recommender_base, calc_similality) {
  recommender_impl r;
  common::sfv_t q1;
  common::sfv_t q2;

  q1.push_back(make_pair("c1", 1.0));
  q1.push_back(make_pair("c2", 2.0));
  q1.push_back(make_pair("c3", 3.0));

  q2.push_back(make_pair("c4", 2.0));
  q2.push_back(make_pair("c3", 3.0));
  q2.push_back(make_pair("c2", 3.0));

  EXPECT_FLOAT_EQ(
      (2.0 * 3.0 + 3.0 * 3.0) / r.calc_l2norm(q1) / r.calc_l2norm(q2),
      r.calc_similality(q1, q2));
}

}  // namespace recommender
}  // namespace core
}  // namespace jubatus
<commit_msg>fix compiler warning<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2012 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include "recommender_base.hpp"

using std::make_pair;
using std::pair;
using std::string;
using std::vector;

namespace jubatus {
namespace core {
namespace recommender {

class recommender_impl : public recommender_base {
 public:
  recommender_impl()
      : recommender_base() {
    // make mock
    orig_.set("r1", "a1", 1.0);
    orig_.set("r1", "a2", 1.0);

    orig_.set("r2", "b1", 1.0);
    orig_.set("r2", "b2", 1.0);

    orig_.set("r3", "a1", 1.0);
    orig_.set("r3", "b1", 1.0);
  }

  void similar_row(
      const common::sfv_t& query,
      vector<pair<string, float> >& ids,
      size_t ret_num) const {
    ids.clear();
    ids.push_back(make_pair("r1", 2.0));
    ids.push_back(make_pair("r3", 1.0));
  }

  void neighbor_row(
      const common::sfv_t& query,
      vector<pair<string, float> >& ids,
      size_t ret_num) const {
    ids.clear();
    ids.push_back(make_pair("r1", 1.0));
    ids.push_back(make_pair("r3", 2.0));
  }

  void clear() {
  }

  void clear_row(const string& id) {
  }

  void update_row(const string& id, const sfv_diff_t& diff) {
  }

  void get_all_row_ids(vector<string>& ids) const {
    ids.clear();
    ids.push_back("r1");
    ids.push_back("r2");
    ids.push_back("r3");
  }

  string type() const {
    return string("recommender_impl");
  }

  framework::mixable* get_mixable() const {
    return NULL;
  }

  void pack(framework::packer&) const {
  }
  void unpack(msgpack::object) {
  }
};

TEST(recommender_base, complete_row) {
  recommender_impl r;
  common::sfv_t q;
  common::sfv_t ret;
  r.complete_row(q, ret);
  ASSERT_EQ(3u, ret.size());
  EXPECT_EQ("a1", ret[0].first);
  EXPECT_EQ("a2", ret[1].first);
  EXPECT_EQ("b1", ret[2].first);
}

TEST(recommender_base, get_all_row_ids) {
  vector<string> ids;
  recommender_impl r;
  r.get_all_row_ids(ids);
  ASSERT_EQ(3u, ids.size());
  sort(ids.begin(), ids.end());
  EXPECT_EQ("r1", ids[0]);
  EXPECT_EQ("r2", ids[1]);
  EXPECT_EQ("r3", ids[2]);
}

TEST(recommender_base, decode_row) {
  recommender_impl r;
  common::sfv_t v;
  r.decode_row("r1", v);
  ASSERT_EQ(2u, v.size());
  EXPECT_EQ("a1", v[0].first);
  EXPECT_EQ(1.0, v[0].second);
  EXPECT_EQ("a2", v[1].first);
  EXPECT_EQ(1.0, v[1].second);

  r.decode_row("r", v);
  ASSERT_TRUE(v.empty());
}

TEST(recommender_base, calc_l2norm) {
  recommender_impl r;
  common::sfv_t q;
  q.push_back(make_pair("a1", 1.0));
  q.push_back(make_pair("a2", 2.0));
  q.push_back(make_pair("a3", 3.0));

  EXPECT_FLOAT_EQ(std::sqrt(1.0 + 4.0 + 9.0), r.calc_l2norm(q));
}

TEST(recommender_base, calc_similality) {
  recommender_impl r;
  common::sfv_t q1;
  common::sfv_t q2;

  q1.push_back(make_pair("c1", 1.0));
  q1.push_back(make_pair("c2", 2.0));
  q1.push_back(make_pair("c3", 3.0));

  q2.push_back(make_pair("c4", 2.0));
  q2.push_back(make_pair("c3", 3.0));
  q2.push_back(make_pair("c2", 3.0));

  EXPECT_FLOAT_EQ(
      (2.0 * 3.0 + 3.0 * 3.0) / r.calc_l2norm(q1) / r.calc_l2norm(q2),
      r.calc_similality(q1, q2));
}

}  // namespace recommender
}  // namespace core
}  // namespace jubatus
<|endoftext|>


<commit_before>// Copyright (c) 2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "blockencodings.h"
#include "consensus/consensus.h"
#include "consensus/validation.h"
#include "chainparams.h"
#include "hash.h"
#include "random.h"
#include "streams.h"
#include "txmempool.h"
#include "main.h"
#include "util.h"

#include <unordered_map>

#define MIN_TRANSACTION_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION))

CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block) :
        nonce(GetRand(std::numeric_limits<uint64_t>::max())),
        shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) {
    FillShortTxIDSelector();
    //TODO: Use our mempool prior to block acceptance to predictively fill more than just the coinbase
    prefilledtxn[0] = {0, block.vtx[0]};
    for (size_t i = 1; i < block.vtx.size(); i++) {
        const CTransaction& tx = block.vtx[i];
        shorttxids[i - 1] = GetShortID(tx.GetHash());
    }
}

void CBlockHeaderAndShortTxIDs::FillShortTxIDSelector() const {
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << header << nonce;
    CSHA256 hasher;
    hasher.Write((unsigned char*)&(*stream.begin()), stream.end() - stream.begin());
    uint256 shorttxidhash;
    hasher.Finalize(shorttxidhash.begin());
    shorttxidk0 = shorttxidhash.GetUint64(0);
    shorttxidk1 = shorttxidhash.GetUint64(1);
}

uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256& txhash) const {
    static_assert(SHORTTXIDS_LENGTH == 6, "shorttxids calculation assumes 6-byte shorttxids");
    return SipHashUint256(shorttxidk0, shorttxidk1, txhash) & 0xffffffffffffL;
}

ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock) {
    if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty()))
        return READ_STATUS_INVALID;
    if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_SIZE / MIN_TRANSACTION_SIZE)
        return READ_STATUS_INVALID;

    assert(header.IsNull() && txn_available.empty());
    header = cmpctblock.header;
    txn_available.resize(cmpctblock.BlockTxCount());

    int32_t lastprefilledindex = -1;
    for (size_t i = 0; i < cmpctblock.prefilledtxn.size(); i++) {
        if (cmpctblock.prefilledtxn[i].tx.IsNull())
            return READ_STATUS_INVALID;

        lastprefilledindex += cmpctblock.prefilledtxn[i].index + 1; //index is a uint16_t, so cant overflow here
        if (lastprefilledindex > std::numeric_limits<uint16_t>::max())
            return READ_STATUS_INVALID;
        if ((uint32_t)lastprefilledindex > cmpctblock.shorttxids.size() + i) {
            // If we are inserting a tx at an index greater than our full list of shorttxids
            // plus the number of prefilled txn we've inserted, then we have txn for which we
            // have neither a prefilled txn or a shorttxid!
            return READ_STATUS_INVALID;
        }
        txn_available[lastprefilledindex] = std::make_shared<CTransaction>(cmpctblock.prefilledtxn[i].tx);
    }
    prefilled_count = cmpctblock.prefilledtxn.size();

    // Calculate map of txids -> positions and check mempool to see what we have (or dont)
    // Because well-formed cmpctblock messages will have a (relatively) uniform distribution
    // of short IDs, any highly-uneven distribution of elements can be safely treated as a
    // READ_STATUS_FAILED.
    std::unordered_map<uint64_t, uint16_t> shorttxids(cmpctblock.shorttxids.size());
    uint16_t index_offset = 0;
    for (size_t i = 0; i < cmpctblock.shorttxids.size(); i++) {
        while (txn_available[i + index_offset])
            index_offset++;
        shorttxids[cmpctblock.shorttxids[i]] = i + index_offset;
        // Bucket selection is a simple Binomial distribution. If we assume blocks of
        // 10,000 transactions, allowing up to 12 elements per bucket should only fail
        // once every ~1.3 million blocks and once every 74,000 blocks in a worst-case
        // 16,000-transaction block.
        if (shorttxids.bucket_size(shorttxids.bucket(cmpctblock.shorttxids[i])) > 12)
            return READ_STATUS_FAILED;
    }
    // TODO: in the shortid-collision case, we should instead request both transactions
    // which collided. Falling back to full-block-request here is overkill.
    if (shorttxids.size() != cmpctblock.shorttxids.size())
        return READ_STATUS_FAILED; // Short ID collision

    std::vector<bool> have_txn(txn_available.size());
    LOCK(pool->cs);
    for (CTxMemPool::txiter it = pool->mapTx.begin(); it != pool->mapTx.end(); it++) {
        std::unordered_map<uint64_t, uint16_t>::iterator idit = shorttxids.find(cmpctblock.GetShortID(it->GetTx().GetHash()));
        if (idit != shorttxids.end()) {
            if (!have_txn[idit->second]) {
                txn_available[idit->second] = it->GetSharedTx();
                have_txn[idit->second]  = true;
                mempool_count++;
            } else {
                // If we find two mempool txn that match the short id, just request it.
                // This should be rare enough that the extra bandwidth doesn't matter,
                // but eating a round-trip due to FillBlock failure would be annoying
                if (txn_available[idit->second]) {
                    txn_available[idit->second].reset();
                    mempool_count--;
                }
            }
        }
        // Though ideally we'd continue scanning for the two-txn-match-shortid case,
        // the performance win of an early exit here is too good to pass up and worth
        // the extra risk.
        if (mempool_count == shorttxids.size())
            break;
    }

    LogPrint("cmpctblock", "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), cmpctblock.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION));

    return READ_STATUS_OK;
}

bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const {
    assert(!header.IsNull());
    assert(index < txn_available.size());
    return txn_available[index] ? true : false;
}

ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransaction>& vtx_missing) const {
    assert(!header.IsNull());
    block = header;
    block.vtx.resize(txn_available.size());

    size_t tx_missing_offset = 0;
    for (size_t i = 0; i < txn_available.size(); i++) {
        if (!txn_available[i]) {
            if (vtx_missing.size() <= tx_missing_offset)
                return READ_STATUS_INVALID;
            block.vtx[i] = vtx_missing[tx_missing_offset++];
        } else
            block.vtx[i] = *txn_available[i];
    }
    if (vtx_missing.size() != tx_missing_offset)
        return READ_STATUS_INVALID;

    CValidationState state;
    if (!CheckBlock(block, state, Params().GetConsensus())) {
        // TODO: We really want to just check merkle tree manually here,
        // but that is expensive, and CheckBlock caches a block's
        // "checked-status" (in the CBlock?). CBlock should be able to
        // check its own merkle root and cache that check.
        if (state.CorruptionPossible())
            return READ_STATUS_FAILED; // Possible Short ID collision
        return READ_STATUS_INVALID;
    }

    LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool and %lu txn requested\n", header.GetHash().ToString(), prefilled_count, mempool_count, vtx_missing.size());
    if (vtx_missing.size() < 5) {
        for(const CTransaction& tx : vtx_missing)
            LogPrint("cmpctblock", "Reconstructed block %s required tx %s\n", header.GetHash().ToString(), tx.GetHash().ToString());
    }

    return READ_STATUS_OK;
}
<commit_msg>Use vTxHashes to optimize InitData significantly<commit_after>// Copyright (c) 2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "blockencodings.h"
#include "consensus/consensus.h"
#include "consensus/validation.h"
#include "chainparams.h"
#include "hash.h"
#include "random.h"
#include "streams.h"
#include "txmempool.h"
#include "main.h"
#include "util.h"

#include <unordered_map>

#define MIN_TRANSACTION_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION))

CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block) :
        nonce(GetRand(std::numeric_limits<uint64_t>::max())),
        shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) {
    FillShortTxIDSelector();
    //TODO: Use our mempool prior to block acceptance to predictively fill more than just the coinbase
    prefilledtxn[0] = {0, block.vtx[0]};
    for (size_t i = 1; i < block.vtx.size(); i++) {
        const CTransaction& tx = block.vtx[i];
        shorttxids[i - 1] = GetShortID(tx.GetHash());
    }
}

void CBlockHeaderAndShortTxIDs::FillShortTxIDSelector() const {
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << header << nonce;
    CSHA256 hasher;
    hasher.Write((unsigned char*)&(*stream.begin()), stream.end() - stream.begin());
    uint256 shorttxidhash;
    hasher.Finalize(shorttxidhash.begin());
    shorttxidk0 = shorttxidhash.GetUint64(0);
    shorttxidk1 = shorttxidhash.GetUint64(1);
}

uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256& txhash) const {
    static_assert(SHORTTXIDS_LENGTH == 6, "shorttxids calculation assumes 6-byte shorttxids");
    return SipHashUint256(shorttxidk0, shorttxidk1, txhash) & 0xffffffffffffL;
}

ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock) {
    if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty()))
        return READ_STATUS_INVALID;
    if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_SIZE / MIN_TRANSACTION_SIZE)
        return READ_STATUS_INVALID;

    assert(header.IsNull() && txn_available.empty());
    header = cmpctblock.header;
    txn_available.resize(cmpctblock.BlockTxCount());

    int32_t lastprefilledindex = -1;
    for (size_t i = 0; i < cmpctblock.prefilledtxn.size(); i++) {
        if (cmpctblock.prefilledtxn[i].tx.IsNull())
            return READ_STATUS_INVALID;

        lastprefilledindex += cmpctblock.prefilledtxn[i].index + 1; //index is a uint16_t, so cant overflow here
        if (lastprefilledindex > std::numeric_limits<uint16_t>::max())
            return READ_STATUS_INVALID;
        if ((uint32_t)lastprefilledindex > cmpctblock.shorttxids.size() + i) {
            // If we are inserting a tx at an index greater than our full list of shorttxids
            // plus the number of prefilled txn we've inserted, then we have txn for which we
            // have neither a prefilled txn or a shorttxid!
            return READ_STATUS_INVALID;
        }
        txn_available[lastprefilledindex] = std::make_shared<CTransaction>(cmpctblock.prefilledtxn[i].tx);
    }
    prefilled_count = cmpctblock.prefilledtxn.size();

    // Calculate map of txids -> positions and check mempool to see what we have (or dont)
    // Because well-formed cmpctblock messages will have a (relatively) uniform distribution
    // of short IDs, any highly-uneven distribution of elements can be safely treated as a
    // READ_STATUS_FAILED.
    std::unordered_map<uint64_t, uint16_t> shorttxids(cmpctblock.shorttxids.size());
    uint16_t index_offset = 0;
    for (size_t i = 0; i < cmpctblock.shorttxids.size(); i++) {
        while (txn_available[i + index_offset])
            index_offset++;
        shorttxids[cmpctblock.shorttxids[i]] = i + index_offset;
        // Bucket selection is a simple Binomial distribution. If we assume blocks of
        // 10,000 transactions, allowing up to 12 elements per bucket should only fail
        // once every ~1.3 million blocks and once every 74,000 blocks in a worst-case
        // 16,000-transaction block.
        if (shorttxids.bucket_size(shorttxids.bucket(cmpctblock.shorttxids[i])) > 12)
            return READ_STATUS_FAILED;
    }
    // TODO: in the shortid-collision case, we should instead request both transactions
    // which collided. Falling back to full-block-request here is overkill.
    if (shorttxids.size() != cmpctblock.shorttxids.size())
        return READ_STATUS_FAILED; // Short ID collision

    std::vector<bool> have_txn(txn_available.size());
    LOCK(pool->cs);
    const std::vector<std::pair<uint256, CTxMemPool::txiter> >& vTxHashes = pool->vTxHashes;
    for (size_t i = 0; i < vTxHashes.size(); i++) {
        uint64_t shortid = cmpctblock.GetShortID(vTxHashes[i].first);
        std::unordered_map<uint64_t, uint16_t>::iterator idit = shorttxids.find(shortid);
        if (idit != shorttxids.end()) {
            if (!have_txn[idit->second]) {
                txn_available[idit->second] = vTxHashes[i].second->GetSharedTx();
                have_txn[idit->second]  = true;
                mempool_count++;
            } else {
                // If we find two mempool txn that match the short id, just request it.
                // This should be rare enough that the extra bandwidth doesn't matter,
                // but eating a round-trip due to FillBlock failure would be annoying
                if (txn_available[idit->second]) {
                    txn_available[idit->second].reset();
                    mempool_count--;
                }
            }
        }
        // Though ideally we'd continue scanning for the two-txn-match-shortid case,
        // the performance win of an early exit here is too good to pass up and worth
        // the extra risk.
        if (mempool_count == shorttxids.size())
            break;
    }

    LogPrint("cmpctblock", "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), cmpctblock.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION));

    return READ_STATUS_OK;
}

bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const {
    assert(!header.IsNull());
    assert(index < txn_available.size());
    return txn_available[index] ? true : false;
}

ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransaction>& vtx_missing) const {
    assert(!header.IsNull());
    block = header;
    block.vtx.resize(txn_available.size());

    size_t tx_missing_offset = 0;
    for (size_t i = 0; i < txn_available.size(); i++) {
        if (!txn_available[i]) {
            if (vtx_missing.size() <= tx_missing_offset)
                return READ_STATUS_INVALID;
            block.vtx[i] = vtx_missing[tx_missing_offset++];
        } else
            block.vtx[i] = *txn_available[i];
    }
    if (vtx_missing.size() != tx_missing_offset)
        return READ_STATUS_INVALID;

    CValidationState state;
    if (!CheckBlock(block, state, Params().GetConsensus())) {
        // TODO: We really want to just check merkle tree manually here,
        // but that is expensive, and CheckBlock caches a block's
        // "checked-status" (in the CBlock?). CBlock should be able to
        // check its own merkle root and cache that check.
        if (state.CorruptionPossible())
            return READ_STATUS_FAILED; // Possible Short ID collision
        return READ_STATUS_INVALID;
    }

    LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool and %lu txn requested\n", header.GetHash().ToString(), prefilled_count, mempool_count, vtx_missing.size());
    if (vtx_missing.size() < 5) {
        for(const CTransaction& tx : vtx_missing)
            LogPrint("cmpctblock", "Reconstructed block %s required tx %s\n", header.GetHash().ToString(), tx.GetHash().ToString());
    }

    return READ_STATUS_OK;
}
<|endoftext|>


<commit_before>/*****************************************************************************************
 *                                                                                *
 * OpenSpace                                                                             *
 *                                                                                *
 * Copyright (c) 2014                                                                    *
 *                                                                                *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

// open space includes
#include <openspace/rendering/renderablevolume.h>

#include <ghoul/opengl/texturereader.h>
#include <ghoul/filesystem/filesystem.h>

#include <openspace/engine/openspaceengine.h>
#include <sgct.h>

#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <type_traits>

namespace {
    std::string _loggerCat = "RenderableVolume";

    bool hasEnding (std::string const &fullString, std::string const &ending)
    {
        if (fullString.length() >= ending.length()) {
            return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
        } else {
            return false;
        }
    }

    template<typename T>
    T stringToNumber(const std::string& number, std::function<T(T)> f = nullptr) {
        static_assert(std::is_integral<T>::value || std::is_floating_point<T>::value,
                      "Must be integral or floating point");
        std::stringstream ss;
        T templateNumber = {0};
        ss << number;
        ss >> templateNumber;
        if( ! f)
            return templateNumber;

        return f(templateNumber);

    }

}

namespace openspace {

RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary) {

    // get path if available
    _relativePath = "";
    if(dictionary.hasKey("Path")) {
       dictionary.getValue("Path", _relativePath);
       _relativePath += "/";
    }
}

RenderableVolume::~RenderableVolume() {
}

std::string RenderableVolume::findPath(const std::string& path) {
    std::string tmp = absPath(path);
    if(FileSys.fileExists(tmp))
        return tmp;

    tmp = absPath(_relativePath + path);
    if(FileSys.fileExists(tmp))
        return tmp;

    LERROR("Could not find file '" << path << "'");

    return "";
}

ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) {
    ghoul::RawVolumeReader::ReadHints hints;
    hints._dimensions = glm::ivec3(1, 1, 1);
    hints._format = ghoul::opengl::Texture::Format::Red;
    hints._internalFormat = GL_R8;

    // parse hints
    double tempValue;
    if (dictionary.hasKey("Dimensions.1") && dictionary.getValue("Dimensions.1", tempValue)) {
        int intVal = static_cast<int>(tempValue);
        if(intVal > 0)
            hints._dimensions[0] = intVal;
    }
    if (dictionary.hasKey("Dimensions.2") && dictionary.getValue("Dimensions.2", tempValue)) {
        int intVal = static_cast<int>(tempValue);
        if(intVal > 0)
            hints._dimensions[1] = intVal;
    }
    if (dictionary.hasKey("Dimensions.3") && dictionary.getValue("Dimensions.3", tempValue)) {
        int intVal = static_cast<int>(tempValue);
        if(intVal > 0)
            hints._dimensions[2] = intVal;
    }

    std::string format;
    if (dictionary.hasKey("Format") && dictionary.getValue("Format", format)) {
        if(format == "RED") {
            hints._format = ghoul::opengl::Texture::Format::Red;
        } else if(format == "RG") {
            hints._format = ghoul::opengl::Texture::Format::RG;
        } else if(format == "RGB") {
            hints._format = ghoul::opengl::Texture::Format::RGB;
        } else if(format == "RGBA") {
            hints._format = ghoul::opengl::Texture::Format::RGBA;
        }
    }

    format = "";
    if (dictionary.hasKey("InternalFormat") && dictionary.getValue("InternalFormat", format)) {
        if(format == "R8") {
            hints._internalFormat = GL_R8;
        } else if(format == "RG8") {
            hints._internalFormat = GL_RG8;
        } else if(format == "RGB8") {
            hints._internalFormat = GL_RGB8;
        } else if(format == "RGBA8") {
            hints._internalFormat = GL_RGB8;
        } else if(format == "R32F") {
            hints._internalFormat = GL_R32F;
        } else if(format == "RG32F") {
            hints._internalFormat = GL_RG32F;
        } else if(format == "RGB32F") {
            hints._internalFormat = GL_RGB32F;
        } else if(format == "RGBA32F") {
            hints._internalFormat = GL_RGB32F;
        }
    }
    return hints;
}

ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string& filepath) {

    std::string f = absPath(filepath);

    if ( ! FileSys.fileExists(f)) {
        return nullptr;
    }

    // check if not a txt based texture
    if ( ! hasEnding(filepath, ".txt")) {
        return ghoul::opengl::loadTexture(f);
    }

    // it is a txt based texture
    std::ifstream in;
    in.open(filepath.c_str());
    if (!in.is_open()) {
        LERROR("Could not open file " << f);
        return nullptr;
    }

    int width = 512;
    float lower = 0.0f;
    float upper = 1.0f;

    struct mappingKey {
        float position{0.0f};
        glm::vec4 color{0.0f,0.0f,0.0f,0.0f};

        mappingKey(float p, const glm::vec4& c): position(p), color(c){};
        mappingKey(float p): position(p), color(glm::vec4(0.0f)){};
        bool operator<(const mappingKey& rhs) {return position < rhs.position;};
    };

    std::vector<mappingKey> mappingKeys;

    auto widthValidator = [](size_t in) { if(in > 0) return in; return static_cast<size_t>(1); };
    auto upperLowerValidator = [](float in) { return glm::clamp(in, 0.0f, 1.0f); };
    auto intensityValidator = [](float in) { if(in > 0.0f) return in; return 1.0f; };

    std::string line;
    while (std::getline(in, line)) {

        float intensity = 1.0f;
        glm::vec4 rgba = glm::vec4(0.0f);
        // tokenize the line
        std::istringstream iss(line);
        std::vector<std::string> tokens{std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{}};

        size_t tokenSize =tokens.size();
        if (tokenSize > 0) {
            std::string key = tokens.at(0);
            if(key == "width" && tokenSize == 2) {
                width = stringToNumber<int>(tokens.at(1),widthValidator);
            } else if(key == "lower" && tokenSize == 2) {
                lower = stringToNumber<float>(tokens.at(1),upperLowerValidator);
            } else if(key == "upper" && tokenSize == 2) {
                upper = stringToNumber<float>(tokens.at(1),upperLowerValidator);
            } else if(key == "mappingkey" && tokenSize == 6) {
                intensity = stringToNumber<float>(tokens.at(1), intensityValidator);
                for(int i = 0; i < 4; ++i)
                    rgba[i] = stringToNumber<float>(tokens.at(i+2));

                mappingKeys.push_back({intensity, rgba});
            }
        }
    }
    in.close();

    if (mappingKeys.size() < 1) {
        return nullptr;
    }

    mappingKeys.insert(mappingKeys.begin(), {lower});
    mappingKeys.push_back({upper});

    for(auto key: mappingKeys) {
        glm::vec4 rgba = key.color;
        LDEBUG("i: " << key.position << ", rgba: (" << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << ")");
    }

    // allocate new float array with zeros
    float* transferFunction = new float[width*4]();
    for (int i = 0; i < 4*width; ++i) {
        transferFunction[i] = 0.0f;
    }

    size_t lowerIndex = static_cast<size_t>(floorf(lower*static_cast<float>(width)));
    size_t upperIndex = static_cast<size_t>(floorf(upper*static_cast<float>(width)));

//    LDEBUG("width: " << width);
//    LDEBUG("lower: " << lower);
//    LDEBUG("upper: " << upper);
//    LDEBUG("lowerIndex: " << lowerIndex);
//    LDEBUG("upperIndex: " << upperIndex);

    auto prevKey = mappingKeys.begin();
    auto currentKey = prevKey + 1;
    auto lastKey = mappingKeys.end() -1;

    for (size_t i=lowerIndex; i<upperIndex; i++) {

        float fpos = static_cast<float>(i)/static_cast<float>(width);

        if (fpos > (*currentKey).position) {
            prevKey = currentKey;
            currentKey++;
            if (currentKey == mappingKeys.end()) {
                currentKey = lastKey;
            }
        }

        float dist = fpos-(*prevKey).position;
        float weight = dist/((*currentKey).position-(*prevKey).position);

        //LDEBUG("fpos: " << fpos);
        //LDEBUG("(*prevKey).position: " << (*prevKey).position);
        //LDEBUG("(*currentKey).position: " << (*currentKey).position);
        //LDEBUG("weight: " << weight);

        for (size_t channel=0; channel<4; ++channel) {
            size_t position = 4*i + channel;
            // Interpolate linearly between prev and next mapping key

            //LDEBUG("i: " << i);
            //LDEBUG("position: " << position);
            //LDEBUG("(*prevKey).first " << (*prevKey).first);
            //LDEBUG("(*currentKey).first " << (*currentKey).first);
            //LDEBUG("dist: " << dist);
            //LDEBUG("weight: " << weight);
            float value =
            ((*prevKey).color[channel]*(1.f-weight) + (*currentKey).color[channel]*weight)/255.f;
            transferFunction[position] = value;

            //LDEBUG("["<< position <<"] " << value);

        }
        LDEBUG(weight << ", (" <<
               transferFunction[4*i+0] << ", " <<
               transferFunction[4*i+1] << ", " <<
               transferFunction[4*i+2] << ", " <<
               transferFunction[4*i+3] << ")");
    }

     return new ghoul::opengl::Texture(transferFunction, glm::size3_t(width,1,1),ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT);
}

} // namespace openspace<commit_msg>OpenCL fix in ghoul<commit_after>/*****************************************************************************************
 *                                                                                *
 * OpenSpace                                                                             *
 *                                                                                *
 * Copyright (c) 2014                                                                    *
 *                                                                                *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

// open space includes
#include <openspace/rendering/renderablevolume.h>

#include <ghoul/opengl/texturereader.h>
#include <ghoul/filesystem/filesystem.h>

#include <openspace/engine/openspaceengine.h>
#include <sgct.h>

#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <type_traits>

namespace {
    std::string _loggerCat = "RenderableVolume";

    bool hasEnding (std::string const &fullString, std::string const &ending)
    {
        if (fullString.length() >= ending.length()) {
            return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
        } else {
            return false;
        }
    }

    template<typename T>
    T stringToNumber(const std::string& number, std::function<T(T)> f = nullptr) {
        static_assert(std::is_integral<T>::value || std::is_floating_point<T>::value,
                      "Must be integral or floating point");
        std::stringstream ss;
        T templateNumber = {0};
        ss << number;
        ss >> templateNumber;
        if( ! f)
            return templateNumber;

        return f(templateNumber);

    }

}

namespace openspace {

RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary) {

    // get path if available
    _relativePath = "";
    if(dictionary.hasKey("Path")) {
       dictionary.getValue("Path", _relativePath);
       _relativePath += "/";
    }
}

RenderableVolume::~RenderableVolume() {
}

std::string RenderableVolume::findPath(const std::string& path) {
    std::string tmp = absPath(path);
    if(FileSys.fileExists(tmp))
        return tmp;

    tmp = absPath(_relativePath + path);
    if(FileSys.fileExists(tmp))
        return tmp;

    LERROR("Could not find file '" << path << "'");

    return "";
}

ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) {
    ghoul::RawVolumeReader::ReadHints hints;
    hints._dimensions = glm::ivec3(1, 1, 1);
    hints._format = ghoul::opengl::Texture::Format::Red;
    hints._internalFormat = GL_R8;

    // parse hints
    double tempValue;
    if (dictionary.hasKey("Dimensions.1") && dictionary.getValue("Dimensions.1", tempValue)) {
        int intVal = static_cast<int>(tempValue);
        if(intVal > 0)
            hints._dimensions[0] = intVal;
    }
    if (dictionary.hasKey("Dimensions.2") && dictionary.getValue("Dimensions.2", tempValue)) {
        int intVal = static_cast<int>(tempValue);
        if(intVal > 0)
            hints._dimensions[1] = intVal;
    }
    if (dictionary.hasKey("Dimensions.3") && dictionary.getValue("Dimensions.3", tempValue)) {
        int intVal = static_cast<int>(tempValue);
        if(intVal > 0)
            hints._dimensions[2] = intVal;
    }

    std::string format;
    if (dictionary.hasKey("Format") && dictionary.getValue("Format", format)) {
        if(format == "RED") {
            hints._format = ghoul::opengl::Texture::Format::Red;
        } else if(format == "RG") {
            hints._format = ghoul::opengl::Texture::Format::RG;
        } else if(format == "RGB") {
            hints._format = ghoul::opengl::Texture::Format::RGB;
        } else if(format == "RGBA") {
            hints._format = ghoul::opengl::Texture::Format::RGBA;
        }
    }

    format = "";
    if (dictionary.hasKey("InternalFormat") && dictionary.getValue("InternalFormat", format)) {
        if(format == "R8") {
            hints._internalFormat = GL_R8;
        } else if(format == "RG8") {
            hints._internalFormat = GL_RG8;
        } else if(format == "RGB8") {
            hints._internalFormat = GL_RGB8;
        } else if(format == "RGBA8") {
            hints._internalFormat = GL_RGB8;
        } else if(format == "R32F") {
            hints._internalFormat = GL_R32F;
        } else if(format == "RG32F") {
            hints._internalFormat = GL_RG32F;
        } else if(format == "RGB32F") {
            hints._internalFormat = GL_RGB32F;
        } else if(format == "RGBA32F") {
            hints._internalFormat = GL_RGB32F;
        }
    }
    return hints;
}

ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string& filepath) {

    std::string f = absPath(filepath);

    if ( ! FileSys.fileExists(f)) {
        return nullptr;
    }

    // check if not a txt based texture
    if ( ! hasEnding(filepath, ".txt")) {
        return ghoul::opengl::loadTexture(f);;
    }

    // it is a txt based texture
    std::ifstream in;
    in.open(filepath.c_str());
    if (!in.is_open()) {
        LERROR("Could not open file " << f);
        return nullptr;
    }

    int width = 512;
    float lower = 0.0f;
    float upper = 1.0f;

    struct mappingKey {
        float position{0.0f};
        glm::vec4 color{0.0f,0.0f,0.0f,0.0f};

        mappingKey(float p, const glm::vec4& c): position(p), color(c){};
        mappingKey(float p): position(p), color(glm::vec4(0.0f)){};
        bool operator<(const mappingKey& rhs) {return position < rhs.position;};
    };

    std::vector<mappingKey> mappingKeys;

    auto widthValidator = [](size_t in) { if(in > 0) return in; return static_cast<size_t>(1); };
    auto upperLowerValidator = [](float in) { return glm::clamp(in, 0.0f, 1.0f); };
    auto intensityValidator = [](float in) { if(in > 0.0f) return in; return 1.0f; };

    std::string line;
    while (std::getline(in, line)) {

        float intensity = 1.0f;
        glm::vec4 rgba = glm::vec4(0.0f);
        // tokenize the line
        std::istringstream iss(line);
        std::vector<std::string> tokens{std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{}};

        size_t tokenSize =tokens.size();
        if (tokenSize > 0) {
            std::string key = tokens.at(0);
            if(key == "width" && tokenSize == 2) {
                width = stringToNumber<int>(tokens.at(1),widthValidator);
            } else if(key == "lower" && tokenSize == 2) {
                lower = stringToNumber<float>(tokens.at(1),upperLowerValidator);
            } else if(key == "upper" && tokenSize == 2) {
                upper = stringToNumber<float>(tokens.at(1),upperLowerValidator);
            } else if(key == "mappingkey" && tokenSize == 6) {
                intensity = stringToNumber<float>(tokens.at(1), intensityValidator);
                for(int i = 0; i < 4; ++i)
                    rgba[i] = stringToNumber<float>(tokens.at(i+2));

                mappingKeys.push_back({intensity, rgba});
            }
        }
    }
    in.close();

    if (mappingKeys.size() < 1) {
        return nullptr;
    }

    mappingKeys.insert(mappingKeys.begin(), {lower});
    mappingKeys.push_back({upper});

    for(auto key: mappingKeys) {
        glm::vec4 rgba = key.color;
//        LDEBUG("i: " << key.position << ", rgba: (" << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << ")");
    }

    // allocate new float array with zeros
    float* transferFunction = new float[width*4]();
    for (int i = 0; i < 4*width; ++i) {
        transferFunction[i] = 0.0f;
    }

    size_t lowerIndex = static_cast<size_t>(floorf(lower*static_cast<float>(width)));
    size_t upperIndex = static_cast<size_t>(floorf(upper*static_cast<float>(width)));

//    LDEBUG("width: " << width);
//    LDEBUG("lower: " << lower);
//    LDEBUG("upper: " << upper);
//    LDEBUG("lowerIndex: " << lowerIndex);
//    LDEBUG("upperIndex: " << upperIndex);

    auto prevKey = mappingKeys.begin();
    auto currentKey = prevKey + 1;
    auto lastKey = mappingKeys.end() -1;

    for (size_t i=lowerIndex; i<upperIndex; i++) {

        float fpos = static_cast<float>(i)/static_cast<float>(width);

        if (fpos > (*currentKey).position) {
            prevKey = currentKey;
            currentKey++;
            if (currentKey == mappingKeys.end()) {
                currentKey = lastKey;
            }
        }

        float dist = fpos-(*prevKey).position;
        float weight = dist/((*currentKey).position-(*prevKey).position);

        //LDEBUG("fpos: " << fpos);
        //LDEBUG("(*prevKey).position: " << (*prevKey).position);
        //LDEBUG("(*currentKey).position: " << (*currentKey).position);
        //LDEBUG("weight: " << weight);

        for (size_t channel=0; channel<4; ++channel) {
            size_t position = 4*i + channel;
            // Interpolate linearly between prev and next mapping key

            //LDEBUG("i: " << i);
            //LDEBUG("position: " << position);
            //LDEBUG("(*prevKey).first " << (*prevKey).first);
            //LDEBUG("(*currentKey).first " << (*currentKey).first);
            //LDEBUG("dist: " << dist);
            //LDEBUG("weight: " << weight);
            float value =
            ((*prevKey).color[channel]*(1.f-weight) + (*currentKey).color[channel]*weight)/255.f;
            transferFunction[position] = value;

            //LDEBUG("["<< position <<"] " << value);

        }
//        LDEBUG(weight << ", (" <<
//               transferFunction[4*i+0] << ", " <<
//               transferFunction[4*i+1] << ", " <<
//               transferFunction[4*i+2] << ", " <<
//               transferFunction[4*i+3] << ")");
    }

    return new ghoul::opengl::Texture(transferFunction,
    		glm::size3_t(width,1,1),ghoul::opengl::Texture::Format::RGBA,
    		GL_RGBA, GL_FLOAT);;
}

} // namespace openspace
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 SUSE LLC
 *
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, contact Novell, Inc.
 *
 * To contact Novell about this file by physical or electronic mail, you may
 * find current contact information at www.novell.com.
 */

#include <iostream>

#include "storage/Devices/DmRaidImpl.h"
#include "storage/Devicegraph.h"
#include "storage/Storage.h"
#include "storage/Prober.h"
#include "storage/SystemInfo/SystemInfo.h"
#include "storage/Utils/Exception.h"
#include "storage/Utils/StorageTmpl.h"
#include "storage/Utils/StorageTypes.h"
#include "storage/Utils/StorageDefines.h"
#include "storage/Utils/XmlFile.h"
#include "storage/Utils/SystemCmd.h"
#include "storage/UsedFeatures.h"
#include "storage/Holders/User.h"
#include "storage/Utils/StorageTypes.h"

namespace storage
{

    using namespace std;

    const char* DeviceTraits<DmRaid>::classname = "DmRaid";

    DmRaid::Impl::Impl(const string& name)
	: Partitionable::Impl(name), rotational(false)
    {
	if (!is_valid_name(name))
	    ST_THROW(Exception("invalid DmRaid name"));

	set_range(Partitionable::Impl::default_range);

	set_dm_table_name(name.substr(strlen(DEVMAPPERDIR "/")));
    }

    DmRaid::Impl::Impl(const string& name, const Region& region)
	: Partitionable::Impl(name, region, Partitionable::Impl::default_range),
	  rotational(false)
    {
	if (!is_valid_name(name))
	    ST_THROW(Exception("invalid DmRaid name"));

	set_dm_table_name(name.substr(strlen(DEVMAPPERDIR "/")));
    }

    DmRaid::Impl::Impl(const xmlNode* node)
	: Partitionable::Impl(node), rotational(false)
    {
	getChildValue(node, "rotational", rotational);
    }

    void
    DmRaid::Impl::check() const
    {
	Partitionable::Impl::check();

	if (get_region().get_start() != 0)
	    cerr << "dm raid region start not zero" << endl;

	if (!is_valid_name(get_name()))
	    ST_THROW(Exception("invalid name"));
    }

    bool
    DmRaid::Impl::is_valid_name(const string& name)
    {
	return boost::starts_with(name, DEVMAPPERDIR "/");
    }

    bool
    DmRaid::Impl::activate_dm_raids(const ActivateCallbacks* activate_callbacks)
    {
	y2mil("activate_dm_raids");

	string cmd_line = DMRAIDBIN " --activate yes --no_partitions";
	cout << cmd_line << endl;

	SystemCmd cmd(cmd_line);
	if (cmd.retcode() != 0)
	    ST_THROW(Exception("activate dmraid failed"));

	SystemCmd(UDEVADMBIN_SETTLE);

	return true;
    }

    void
    DmRaid::Impl::probe_dm_raids(Prober& prober)
    {
	const CmdDmraid& cmd_dm_raid = prober.get_system_info().getCmdDmraid();

	for (const string& dm_name : cmd_dm_raid.get_entries())
	{
	    DmRaid* dm_raid = DmRaid::create(prober.get_probed(), DEVMAPPERDIR "/" + dm_name);
	    dm_raid->get_impl().probe_pass_1a(prober);
	}
    }

    void
    DmRaid::Impl::probe_pass_1a(Prober& prober)
    {
	Partitionable::Impl::probe_pass_1a(prober);

	const File rotational_file = prober.get_system_info().getFile(SYSFSDIR + get_sysfs_path() +
								      "/queue/rotational");
	rotational = rotational_file.get_int() != 0;
    }

    void
    DmRaid::Impl::probe_pass_1b(Prober& prober)
    {
	const CmdDmraid& cmd_dmraid = prober.get_system_info().getCmdDmraid();

	const CmdDmraid::Entry& entry = cmd_dmraid.get_entry(get_dm_table_name());

	for (const string& device : entry.devices)
	{
	    BlkDevice* blk_device = BlkDevice::Impl::find_by_name(prober.get_probed(), device,
								  prober.get_system_info());
	    User::create(prober.get_probed(), blk_device, get_non_impl());
	}
    }

    uint64_t
    DmRaid::Impl::used_features() const
    {
	return UF_DMRAID | Partitionable::Impl::used_features();
    }

    void
    DmRaid::Impl::save(xmlNode* node) const
    {
	Partitionable::Impl::save(node);

	setChildValueIf(node, "rotational", rotational, rotational);
    }

    void
    DmRaid::Impl::add_create_actions(Actiongraph::Impl& actiongraph) const
    {
	ST_THROW(Exception("cannot create dm raid"));
    }

    void
    DmRaid::Impl::add_delete_actions(Actiongraph::Impl& actiongraph) const
    {
	ST_THROW(Exception("cannot delete dm raid"));
    }

    bool
    DmRaid::Impl::equal(const Device::Impl& rhs_base) const
    {
	const Impl& rhs = dynamic_cast<const Impl&>(rhs_base);

	if (!Partitionable::Impl::equal(rhs))
	    return false;

	return rotational == rhs.rotational;
    }

    void
    DmRaid::Impl::log_diff(std::ostream& log, const Device::Impl& rhs_base) const
    {
	const Impl& rhs = dynamic_cast<const Impl&>(rhs_base);

	Partitionable::Impl::log_diff(log, rhs);

	storage::log_diff(log, "rotational", rotational, rhs.rotational);
    }

    void
    DmRaid::Impl::print(std::ostream& out) const
    {
	Partitionable::Impl::print(out);

	if (rotational)
	    out << " rotational";
    }

    void
    DmRaid::Impl::process_udev_ids(vector<string>& udev_ids) const
    {
	erase_if(udev_ids, [](const string& udev_id) {
	    return !boost::starts_with(udev_id, "raid-");
	});
    }

    bool
    compare_by_name(const DmRaid* lhs, const DmRaid* rhs)
    {
	return lhs->get_name() < rhs->get_name();
    }

}
<commit_msg>- fixed DM RAID activation<commit_after>/*
 * Copyright (c) 2017 SUSE LLC
 *
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, contact Novell, Inc.
 *
 * To contact Novell about this file by physical or electronic mail, you may
 * find current contact information at www.novell.com.
 */

#include <iostream>

#include "storage/Devices/DmRaidImpl.h"
#include "storage/Devicegraph.h"
#include "storage/Storage.h"
#include "storage/Prober.h"
#include "storage/SystemInfo/SystemInfo.h"
#include "storage/Utils/Exception.h"
#include "storage/Utils/StorageTmpl.h"
#include "storage/Utils/StorageTypes.h"
#include "storage/Utils/StorageDefines.h"
#include "storage/Utils/XmlFile.h"
#include "storage/Utils/SystemCmd.h"
#include "storage/UsedFeatures.h"
#include "storage/Holders/User.h"
#include "storage/Utils/StorageTypes.h"

namespace storage
{

    using namespace std;

    const char* DeviceTraits<DmRaid>::classname = "DmRaid";

    DmRaid::Impl::Impl(const string& name)
	: Partitionable::Impl(name), rotational(false)
    {
	if (!is_valid_name(name))
	    ST_THROW(Exception("invalid DmRaid name"));

	set_range(Partitionable::Impl::default_range);

	set_dm_table_name(name.substr(strlen(DEVMAPPERDIR "/")));
    }

    DmRaid::Impl::Impl(const string& name, const Region& region)
	: Partitionable::Impl(name, region, Partitionable::Impl::default_range),
	  rotational(false)
    {
	if (!is_valid_name(name))
	    ST_THROW(Exception("invalid DmRaid name"));

	set_dm_table_name(name.substr(strlen(DEVMAPPERDIR "/")));
    }

    DmRaid::Impl::Impl(const xmlNode* node)
	: Partitionable::Impl(node), rotational(false)
    {
	getChildValue(node, "rotational", rotational);
    }

    void
    DmRaid::Impl::check() const
    {
	Partitionable::Impl::check();

	if (get_region().get_start() != 0)
	    cerr << "dm raid region start not zero" << endl;

	if (!is_valid_name(get_name()))
	    ST_THROW(Exception("invalid name"));
    }

    bool
    DmRaid::Impl::is_valid_name(const string& name)
    {
	return boost::starts_with(name, DEVMAPPERDIR "/");
    }

    bool
    DmRaid::Impl::activate_dm_raids(const ActivateCallbacks* activate_callbacks)
    {
	y2mil("activate_dm_raids");

	string cmd_line = DMRAIDBIN " --activate yes --no_partitions";
	cout << cmd_line << endl;

	SystemCmd cmd(cmd_line);

	if (cmd.retcode() == 0)
	    SystemCmd(UDEVADMBIN_SETTLE);

	return cmd.retcode() == 0;
    }

    void
    DmRaid::Impl::probe_dm_raids(Prober& prober)
    {
	const CmdDmraid& cmd_dm_raid = prober.get_system_info().getCmdDmraid();

	for (const string& dm_name : cmd_dm_raid.get_entries())
	{
	    DmRaid* dm_raid = DmRaid::create(prober.get_probed(), DEVMAPPERDIR "/" + dm_name);
	    dm_raid->get_impl().probe_pass_1a(prober);
	}
    }

    void
    DmRaid::Impl::probe_pass_1a(Prober& prober)
    {
	Partitionable::Impl::probe_pass_1a(prober);

	const File rotational_file = prober.get_system_info().getFile(SYSFSDIR + get_sysfs_path() +
								      "/queue/rotational");
	rotational = rotational_file.get_int() != 0;
    }

    void
    DmRaid::Impl::probe_pass_1b(Prober& prober)
    {
	const CmdDmraid& cmd_dmraid = prober.get_system_info().getCmdDmraid();

	const CmdDmraid::Entry& entry = cmd_dmraid.get_entry(get_dm_table_name());

	for (const string& device : entry.devices)
	{
	    BlkDevice* blk_device = BlkDevice::Impl::find_by_name(prober.get_probed(), device,
								  prober.get_system_info());
	    User::create(prober.get_probed(), blk_device, get_non_impl());
	}
    }

    uint64_t
    DmRaid::Impl::used_features() const
    {
	return UF_DMRAID | Partitionable::Impl::used_features();
    }

    void
    DmRaid::Impl::save(xmlNode* node) const
    {
	Partitionable::Impl::save(node);

	setChildValueIf(node, "rotational", rotational, rotational);
    }

    void
    DmRaid::Impl::add_create_actions(Actiongraph::Impl& actiongraph) const
    {
	ST_THROW(Exception("cannot create dm raid"));
    }

    void
    DmRaid::Impl::add_delete_actions(Actiongraph::Impl& actiongraph) const
    {
	ST_THROW(Exception("cannot delete dm raid"));
    }

    bool
    DmRaid::Impl::equal(const Device::Impl& rhs_base) const
    {
	const Impl& rhs = dynamic_cast<const Impl&>(rhs_base);

	if (!Partitionable::Impl::equal(rhs))
	    return false;

	return rotational == rhs.rotational;
    }

    void
    DmRaid::Impl::log_diff(std::ostream& log, const Device::Impl& rhs_base) const
    {
	const Impl& rhs = dynamic_cast<const Impl&>(rhs_base);

	Partitionable::Impl::log_diff(log, rhs);

	storage::log_diff(log, "rotational", rotational, rhs.rotational);
    }

    void
    DmRaid::Impl::print(std::ostream& out) const
    {
	Partitionable::Impl::print(out);

	if (rotational)
	    out << " rotational";
    }

    void
    DmRaid::Impl::process_udev_ids(vector<string>& udev_ids) const
    {
	erase_if(udev_ids, [](const string& udev_id) {
	    return !boost::starts_with(udev_id, "raid-");
	});
    }

    bool
    compare_by_name(const DmRaid* lhs, const DmRaid* rhs)
    {
	return lhs->get_name() < rhs->get_name();
    }

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: propertybaghelper.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 09:59:04 $
 *
 *  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 FORMS_PROPERTYBAGHELPER_HXX
#define FORMS_PROPERTYBAGHELPER_HXX

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
/** === end UNO includes === **/

#include <comphelper/propertybag.hxx>
#include <comphelper/propagg.hxx>

#include <boost/noncopyable.hpp>

//........................................................................
namespace frm
{
//........................................................................

    //====================================================================
    //= class IPropertyBagHelperContext
    //====================================================================
    class SAL_NO_VTABLE IPropertyBagHelperContext
    {
    public:
        virtual ::osl::Mutex&   getMutex() = 0;

        virtual void            describeFixedAndAggregateProperties(
            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rFixedProperties,
            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rAggregateProperties
        ) const = 0;

        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet >
                                getPropertiesInterface() = 0;
    };

    //====================================================================
    //= class PropertyBagHelper
    //====================================================================
    class PropertyBagHelper : public ::boost::noncopyable
    {
    private:
        IPropertyBagHelperContext&                      m_rContext;
        ::comphelper::OPropertyArrayAggregationHelper*  m_pPropertyArrayHelper;
        ::comphelper::PropertyBag                       m_aDynamicProperties;
        bool                                            m_bDisposed;

    public:
        PropertyBagHelper( IPropertyBagHelperContext& _rContext );
        ~PropertyBagHelper();

        // XComponent equivalent
        void    dispose();

        // OPropertySetHelper equivalent
        inline ::comphelper::OPropertyArrayAggregationHelper& getInfoHelper() const;

        // XPropertyContainer equivalent
        void addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const ::com::sun::star::uno::Any& _rInitialValue );
        void removeProperty( const ::rtl::OUString& _rName );

        // XPropertyAccess equivalent
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues();
        void setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rProps );

        // forwards to m_aDynamicProperties
        inline void getDynamicFastPropertyValue( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _out_rValue ) const;
        inline bool convertDynamicFastPropertyValue( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rNewValue, ::com::sun::star::uno::Any& _out_rConvertedValue, ::com::sun::star::uno::Any& _out_rCurrentValue ) const;
        inline void setDynamicFastPropertyValue( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue );
        inline void getDynamicPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _out_rValue ) const;
        inline bool hasDynamicPropertyByName( const ::rtl::OUString& _rName ) const;
        inline bool hasDynamicPropertyByHandle( sal_Int32 _nHandle ) const;

    private:
        void    impl_nts_checkDisposed_throw() const;

        /** invalidates our property set info, so subsequent calls to impl_ts_getArrayHelper and thus
            getInfoHelper will return a newly created instance
        */
        void    impl_nts_invalidatePropertySetInfo();

        /** returns the IPropertyArrayHelper instance used by |this|
        */
        ::comphelper::OPropertyArrayAggregationHelper& impl_ts_getArrayHelper() const;

        /** finds a free property handle
            @param _rPropertyName
                the name of the property to find a handle for. If possible, the handle as determined by
                our ConcreteInfoService instance will be used
        */
        sal_Int32   impl_findFreeHandle( const ::rtl::OUString& _rPropertyName );
    };

    //--------------------------------------------------------------------
    inline ::comphelper::OPropertyArrayAggregationHelper& PropertyBagHelper::getInfoHelper() const
    {
        return impl_ts_getArrayHelper();
    }

    //--------------------------------------------------------------------
    inline void PropertyBagHelper::getDynamicFastPropertyValue( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _out_rValue ) const
    {
        m_aDynamicProperties.getFastPropertyValue( _nHandle, _out_rValue );
    }

    //--------------------------------------------------------------------
    inline bool PropertyBagHelper::convertDynamicFastPropertyValue( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rNewValue, ::com::sun::star::uno::Any& _out_rConvertedValue, ::com::sun::star::uno::Any& _out_rCurrentValue ) const
    {
        return m_aDynamicProperties.convertFastPropertyValue( _nHandle, _rNewValue, _out_rConvertedValue, _out_rCurrentValue );
    }

    //--------------------------------------------------------------------
    inline void PropertyBagHelper::setDynamicFastPropertyValue( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
    {
        m_aDynamicProperties.setFastPropertyValue( _nHandle, _rValue );
    }

    //--------------------------------------------------------------------
    inline void PropertyBagHelper::getDynamicPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _out_rValue ) const
    {
        m_aDynamicProperties.getPropertyDefaultByHandle( _nHandle, _out_rValue );
    }

    //--------------------------------------------------------------------
    inline bool PropertyBagHelper::hasDynamicPropertyByName( const ::rtl::OUString& _rName ) const
    {
        return m_aDynamicProperties.hasPropertyByName( _rName );
    }

    //--------------------------------------------------------------------
    inline bool PropertyBagHelper::hasDynamicPropertyByHandle( sal_Int32 _nHandle ) const
    {
        return m_aDynamicProperties.hasPropertyByHandle( _nHandle );
    }

//........................................................................
} // namespace frm
//........................................................................

#endif // FORMS_PROPERTYBAGHELPER_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.2.78); FILE MERGED 2008/04/01 12:30:28 thb 1.2.78.2: #i85898# Stripping all external header guards 2008/03/31 13:11:39 rt 1.2.78.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: propertybaghelper.hxx,v $
 * $Revision: 1.3 $
 *
 * 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 FORMS_PROPERTYBAGHELPER_HXX
#define FORMS_PROPERTYBAGHELPER_HXX

/** === begin UNO includes === **/
#include <com/sun/star/beans/PropertyValue.hpp>
/** === end UNO includes === **/

#include <comphelper/propertybag.hxx>
#include <comphelper/propagg.hxx>

#include <boost/noncopyable.hpp>

//........................................................................
namespace frm
{
//........................................................................

    //====================================================================
    //= class IPropertyBagHelperContext
    //====================================================================
    class SAL_NO_VTABLE IPropertyBagHelperContext
    {
    public:
        virtual ::osl::Mutex&   getMutex() = 0;

        virtual void            describeFixedAndAggregateProperties(
            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rFixedProperties,
            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rAggregateProperties
        ) const = 0;

        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet >
                                getPropertiesInterface() = 0;
    };

    //====================================================================
    //= class PropertyBagHelper
    //====================================================================
    class PropertyBagHelper : public ::boost::noncopyable
    {
    private:
        IPropertyBagHelperContext&                      m_rContext;
        ::comphelper::OPropertyArrayAggregationHelper*  m_pPropertyArrayHelper;
        ::comphelper::PropertyBag                       m_aDynamicProperties;
        bool                                            m_bDisposed;

    public:
        PropertyBagHelper( IPropertyBagHelperContext& _rContext );
        ~PropertyBagHelper();

        // XComponent equivalent
        void    dispose();

        // OPropertySetHelper equivalent
        inline ::comphelper::OPropertyArrayAggregationHelper& getInfoHelper() const;

        // XPropertyContainer equivalent
        void addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const ::com::sun::star::uno::Any& _rInitialValue );
        void removeProperty( const ::rtl::OUString& _rName );

        // XPropertyAccess equivalent
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues();
        void setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rProps );

        // forwards to m_aDynamicProperties
        inline void getDynamicFastPropertyValue( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _out_rValue ) const;
        inline bool convertDynamicFastPropertyValue( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rNewValue, ::com::sun::star::uno::Any& _out_rConvertedValue, ::com::sun::star::uno::Any& _out_rCurrentValue ) const;
        inline void setDynamicFastPropertyValue( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue );
        inline void getDynamicPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _out_rValue ) const;
        inline bool hasDynamicPropertyByName( const ::rtl::OUString& _rName ) const;
        inline bool hasDynamicPropertyByHandle( sal_Int32 _nHandle ) const;

    private:
        void    impl_nts_checkDisposed_throw() const;

        /** invalidates our property set info, so subsequent calls to impl_ts_getArrayHelper and thus
            getInfoHelper will return a newly created instance
        */
        void    impl_nts_invalidatePropertySetInfo();

        /** returns the IPropertyArrayHelper instance used by |this|
        */
        ::comphelper::OPropertyArrayAggregationHelper& impl_ts_getArrayHelper() const;

        /** finds a free property handle
            @param _rPropertyName
                the name of the property to find a handle for. If possible, the handle as determined by
                our ConcreteInfoService instance will be used
        */
        sal_Int32   impl_findFreeHandle( const ::rtl::OUString& _rPropertyName );
    };

    //--------------------------------------------------------------------
    inline ::comphelper::OPropertyArrayAggregationHelper& PropertyBagHelper::getInfoHelper() const
    {
        return impl_ts_getArrayHelper();
    }

    //--------------------------------------------------------------------
    inline void PropertyBagHelper::getDynamicFastPropertyValue( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _out_rValue ) const
    {
        m_aDynamicProperties.getFastPropertyValue( _nHandle, _out_rValue );
    }

    //--------------------------------------------------------------------
    inline bool PropertyBagHelper::convertDynamicFastPropertyValue( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rNewValue, ::com::sun::star::uno::Any& _out_rConvertedValue, ::com::sun::star::uno::Any& _out_rCurrentValue ) const
    {
        return m_aDynamicProperties.convertFastPropertyValue( _nHandle, _rNewValue, _out_rConvertedValue, _out_rCurrentValue );
    }

    //--------------------------------------------------------------------
    inline void PropertyBagHelper::setDynamicFastPropertyValue( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
    {
        m_aDynamicProperties.setFastPropertyValue( _nHandle, _rValue );
    }

    //--------------------------------------------------------------------
    inline void PropertyBagHelper::getDynamicPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _out_rValue ) const
    {
        m_aDynamicProperties.getPropertyDefaultByHandle( _nHandle, _out_rValue );
    }

    //--------------------------------------------------------------------
    inline bool PropertyBagHelper::hasDynamicPropertyByName( const ::rtl::OUString& _rName ) const
    {
        return m_aDynamicProperties.hasPropertyByName( _rName );
    }

    //--------------------------------------------------------------------
    inline bool PropertyBagHelper::hasDynamicPropertyByHandle( sal_Int32 _nHandle ) const
    {
        return m_aDynamicProperties.hasPropertyByHandle( _nHandle );
    }

//........................................................................
} // namespace frm
//........................................................................

#endif // FORMS_PROPERTYBAGHELPER_HXX

<|endoftext|>