<commit_before>#include "engine.h"
#include "flags.h"
#include "storage/capacitor.h"
#include "storage/inner_readers.h"
#include "storage/memstorage.h"
#include "storage/page_manager.h"
#include "storage/subscribe.h"
#include "utils/exception.h"
#include "utils/locker.h"
#include <algorithm>
#include <cassert>

using namespace dariadb;
using namespace dariadb::storage;

class Engine::Private {
public:
  Private(const PageManager::Params &page_storage_params,
          dariadb::storage::Capacitor::Params cap_params,
          dariadb::storage::Engine::Limits limits)
      : /*mem_storage{new MemoryStorage()},*/ _page_manager_params(page_storage_params),
        _cap_params(cap_params), _limits(limits) {
    _subscribe_notify.start();
    PageManager::start(_page_manager_params);
    mem_cap = new Capacitor(PageManager::instance(), _cap_params);
    //mem_storage_raw = dynamic_cast<MemoryStorage *>(mem_storage.get());
  }
  ~Private() {
    _subscribe_notify.stop();
    this->flush();
    delete mem_cap;
    PageManager::stop();
  }

  Time minTime() {
    std::lock_guard<std::recursive_mutex> lg(_locker);
    auto pmin = PageManager::instance()->minTime();
    auto cmin = mem_cap->minTime();
    return std::min(pmin, cmin);
  }

  Time maxTime() {
    std::lock_guard<std::recursive_mutex> lg(_locker);
    auto pmax = PageManager::instance()->maxTime();
    auto cmax = mem_cap->maxTime();
    return std::max(pmax, cmax);
  }

  bool minMaxTime(dariadb::Id id, dariadb::Time *minResult, dariadb::Time *maxResult) {
    std::lock_guard<std::recursive_mutex> lg(_locker);
    dariadb::Time subMin1, subMax1;
    auto pr = PageManager::instance()->minMaxTime(id, &subMin1, &subMax1);
    dariadb::Time subMin2, subMax2;
    auto mr = mem_cap->minMaxTime(id, &subMin2, &subMax2);

    if (!pr) {
      *minResult = subMin2;
      *maxResult = subMax2;
      return mr;
    }
    if (!mr) {
      *minResult = subMin1;
      *maxResult = subMax1;
      return pr;
    }
    *minResult = std::min(subMin1, subMin2);
    *maxResult = std::max(subMax1, subMax2);
    return true;
  }

  append_result append(const Meas &value) {
    append_result result{};
    // result = PageManager::instance()->append(value);
    result = mem_cap->append(value);
    if (result.writed == 1) {
      _subscribe_notify.on_append(value);
    }

    return result;
  }

  void subscribe(const IdArray &ids, const Flag &flag, const ReaderClb_ptr &clbk) {
    auto new_s = std::make_shared<SubscribeInfo>(ids, flag, clbk);
    _subscribe_notify.add(new_s);
  }

  Reader_ptr currentValue(const IdArray &ids, const Flag &flag) {
    return mem_cap->currentValue(ids, flag);
  }

  void flush() {
    std::lock_guard<std::recursive_mutex> lg(_locker);
    this->mem_cap->flush();
    PageManager::instance()->flush();
  }

  Engine::QueueSizes queue_size() const {
    QueueSizes result;
    result.page = PageManager::instance()->in_queue_size();
    result.cap = this->mem_cap->in_queue_size();
    return result;
  }

  class UnionReader : public Reader {
  public:
    UnionReader() { cap_reader = page_reader = nullptr; }
    // Inherited via Reader
    bool isEnd() const override {
      return (page_reader == nullptr || page_reader->isEnd()) &&
             (cap_reader == nullptr || cap_reader->isEnd());
    }

    IdArray getIds() const override {
      dariadb::IdSet idset;
      if (page_reader != nullptr) {
        auto sub_res = page_reader->getIds();
        for (auto id : sub_res) {
          idset.insert(id);
        }
      }
      {
        if (cap_reader != nullptr) {
          auto sub_res = cap_reader->getIds();
          for (auto id : sub_res) {
            idset.insert(id);
          }
        }
      }
      return dariadb::IdArray{idset.begin(), idset.end()};
    }

    void readNext(ReaderClb *clb) override {
      if (page_reader != nullptr && !page_reader->isEnd()) {
        page_reader->readNext(clb);
      } else {
        if (cap_reader != nullptr && !cap_reader->isEnd()) {
          cap_reader->readNext(clb);
        }
      }
    }
    Reader_ptr clone() const override {
      UnionReader *raw_res = new UnionReader();
      if (this->page_reader != nullptr) {
        raw_res->page_reader = this->page_reader->clone();
      }
      if (this->cap_reader != nullptr) {
        raw_res->cap_reader = this->cap_reader->clone();
      }
      return Reader_ptr(raw_res);
    }

    void reset() override {
      if (page_reader != nullptr) {
        page_reader->reset();
      }
      if (cap_reader != nullptr) {
        cap_reader->reset();
      }
    }

    Reader_ptr page_reader;
    Reader_ptr cap_reader;
  };

  class UnionReaderSet : public Reader {
  public:
    std::list<Reader_ptr> _readers;
    std::list<Reader_ptr>::iterator it;
    bool _is_end;
    UnionReaderSet() {}
    ~UnionReaderSet() { _readers.clear(); }

    void add_rdr(const Reader_ptr &cptr) {
      _readers.push_back(cptr);
      reset();
    }

    IdArray getIds() const override {
      IdSet subresult;
      for (auto r : _readers) {
        IdArray ids = r->getIds();
        for (auto id : ids) {
          subresult.insert(id);
        }
      }
      return IdArray{subresult.begin(), subresult.end()};
    }

    bool isEnd() const override { return _is_end; }

    void readNext(ReaderClb *clb) override {
      (*it)->readNext(clb);
      if ((*it)->isEnd()) {
        ++it;
        if (it == _readers.end()) {
          _is_end = true;
        }
      }
    }

    Reader_ptr clone() const override {
      UnionReaderSet *res = new UnionReaderSet;
      for (auto r : _readers) {
        res->add_rdr(r->clone());
      }
      return Reader_ptr{res};
    }
    void reset() override {
      it = _readers.begin();
      _is_end = false;
      for (auto &c : _readers) {
        c->reset();
      }
    }
  };

  // Inherited via MeasStorage
  Reader_ptr readInterval(const QueryInterval &q) {
    UnionReaderSet *raw_result = new UnionReaderSet();

    for (auto id : q.ids) {
      InnerReader *raw_rdr = new InnerReader(q.flag, q.from, q.to);
      UnionReader *raw_res = new UnionReader();
      raw_res->page_reader = Reader_ptr{raw_rdr};
      raw_rdr->_ids.push_back(id);

      dariadb::Time minT, maxT;
      QueryInterval local_q = q;
      local_q.ids.clear();
      local_q.ids.push_back(id);
      if (!mem_cap->minMaxTime(id, &minT, &maxT)) {
        auto chunkLinks = PageManager::instance()->chunksByIterval(local_q);
        auto page_cursor = PageManager::instance()->readLinks(chunkLinks);
        raw_rdr->add(page_cursor);
      } else {

        if (minT <= q.from && maxT >= q.to) {
          auto mc_reader = mem_cap->readInterval(local_q);
          raw_res->cap_reader = Reader_ptr{mc_reader};
        } else {
          local_q.to = minT;
          auto chunkLinks = PageManager::instance()->chunksByIterval(local_q);
          auto page_cursor = PageManager::instance()->readLinks(chunkLinks);
          raw_rdr->add(page_cursor);
          local_q.from = minT;
          local_q.to = q.to;

          auto mc_reader = mem_cap->readInterval(local_q);
          raw_res->cap_reader = Reader_ptr{mc_reader};
        }
      }
      raw_result->add_rdr(Reader_ptr{raw_res});
    }
    return Reader_ptr(raw_result);
  }

  Reader_ptr readInTimePoint(const QueryTimePoint &q) {
    UnionReaderSet *raw_result = new UnionReaderSet();
    for (auto id : q.ids) {
      dariadb::Time minT, maxT;
      QueryTimePoint local_q = q;
      local_q.ids.clear();
      local_q.ids.push_back(id);

      if (mem_cap->minMaxTime(id, &minT, &maxT) &&
          utils::inInterval(minT, maxT, local_q.time_point)) {
        auto subres = mem_cap->readInTimePoint(local_q);
        raw_result->add_rdr(subres);
      } else {
        auto id2meas = PageManager::instance()->valuesBeforeTimePoint(local_q);

        TP_Reader *raw_tp_reader = new TP_Reader;
        if (!id2meas.empty()) {
          raw_tp_reader->_ids.resize(id2meas.size());
          for (auto kv : id2meas) {
            raw_tp_reader->_values.push_back(kv.second);
            raw_tp_reader->_ids.push_back(kv.first);
          }
        } else {
          if (id2meas.empty()) {
            raw_tp_reader->_ids.resize(size_t(1));
            auto e = Meas::empty(id);
            e.flag = Flags::_NO_DATA;
            e.time = q.time_point;
            raw_tp_reader->_values.push_back(e);
            raw_tp_reader->_ids.push_back(id);
          }
        }
        raw_tp_reader->reset();
        Reader_ptr subres{raw_tp_reader};
        raw_result->add_rdr(subres);
      }
    }
    return Reader_ptr(raw_result);
  }

protected:
//  std::shared_ptr<MemoryStorage> mem_storage;
  //storage::MemoryStorage *mem_storage_raw;
  storage::Capacitor *mem_cap;

  storage::PageManager::Params _page_manager_params;
  dariadb::storage::Capacitor::Params _cap_params;
  dariadb::storage::Engine::Limits _limits;

  mutable std::recursive_mutex _locker;
  SubscribeNotificator _subscribe_notify;
};

Engine::Engine(storage::PageManager::Params page_manager_params,
               dariadb::storage::Capacitor::Params cap_params,
               const dariadb::storage::Engine::Limits &limits)
    : _impl{new Engine::Private(page_manager_params, cap_params, limits)} {}

Engine::~Engine() {
  _impl = nullptr;
}

Time Engine::minTime() {
  return _impl->minTime();
}

Time Engine::maxTime() {
  return _impl->maxTime();
}
bool Engine::minMaxTime(dariadb::Id id, dariadb::Time *minResult,
                        dariadb::Time *maxResult) {
  return _impl->minMaxTime(id, minResult, maxResult);
}

append_result Engine::append(const Meas &value) {
  return _impl->append(value);
}

void Engine::subscribe(const IdArray &ids, const Flag &flag, const ReaderClb_ptr &clbk) {
  _impl->subscribe(ids, flag, clbk);
}

Reader_ptr Engine::currentValue(const IdArray &ids, const Flag &flag) {
  return _impl->currentValue(ids, flag);
}

void Engine::flush() {
  _impl->flush();
}

Engine::QueueSizes Engine::queue_size() const {
  return _impl->queue_size();
}

// Reader_ptr dariadb::storage::Engine::readInterval(Time from, Time to){
//	return _impl->readInterval(from, to);
//}

// Reader_ptr dariadb::storage::Engine::readInTimePoint(Time time_point) {
//	return _impl->readInTimePoint(time_point);
//}

Reader_ptr Engine::readInterval(const QueryInterval &q) {
  return _impl->readInterval(q);
}

Reader_ptr Engine::readInTimePoint(const QueryTimePoint &q) {
  return _impl->readInTimePoint(q);
}
<commit_msg>indent.<commit_after>#include "engine.h"
#include "flags.h"
#include "storage/capacitor.h"
#include "storage/inner_readers.h"
#include "storage/memstorage.h"
#include "storage/page_manager.h"
#include "storage/subscribe.h"
#include "utils/exception.h"
#include "utils/locker.h"
#include <algorithm>
#include <cassert>

using namespace dariadb;
using namespace dariadb::storage;

class UnionReader : public Reader {
public:
  UnionReader() { cap_reader = page_reader = nullptr; }
  // Inherited via Reader
  bool isEnd() const override {
    return (page_reader == nullptr || page_reader->isEnd()) &&
           (cap_reader == nullptr || cap_reader->isEnd());
  }

  IdArray getIds() const override {
    dariadb::IdSet idset;
    if (page_reader != nullptr) {
      auto sub_res = page_reader->getIds();
      for (auto id : sub_res) {
        idset.insert(id);
      }
    }
    {
      if (cap_reader != nullptr) {
        auto sub_res = cap_reader->getIds();
        for (auto id : sub_res) {
          idset.insert(id);
        }
      }
    }
    return dariadb::IdArray{idset.begin(), idset.end()};
  }

  void readNext(ReaderClb *clb) override {
    if (page_reader != nullptr && !page_reader->isEnd()) {
      page_reader->readNext(clb);
    } else {
      if (cap_reader != nullptr && !cap_reader->isEnd()) {
        cap_reader->readNext(clb);
      }
    }
  }
  Reader_ptr clone() const override {
    UnionReader *raw_res = new UnionReader();
    if (this->page_reader != nullptr) {
      raw_res->page_reader = this->page_reader->clone();
    }
    if (this->cap_reader != nullptr) {
      raw_res->cap_reader = this->cap_reader->clone();
    }
    return Reader_ptr(raw_res);
  }

  void reset() override {
    if (page_reader != nullptr) {
      page_reader->reset();
    }
    if (cap_reader != nullptr) {
      cap_reader->reset();
    }
  }

  Reader_ptr page_reader;
  Reader_ptr cap_reader;
};

class UnionReaderSet : public Reader {
public:
  std::list<Reader_ptr> _readers;
  std::list<Reader_ptr>::iterator it;
  bool _is_end;
  UnionReaderSet() {}
  ~UnionReaderSet() { _readers.clear(); }

  void add_rdr(const Reader_ptr &cptr) {
    _readers.push_back(cptr);
    reset();
  }

  IdArray getIds() const override {
    IdSet subresult;
    for (auto r : _readers) {
      IdArray ids = r->getIds();
      for (auto id : ids) {
        subresult.insert(id);
      }
    }
    return IdArray{subresult.begin(), subresult.end()};
  }

  bool isEnd() const override { return _is_end; }

  void readNext(ReaderClb *clb) override {
    (*it)->readNext(clb);
    if ((*it)->isEnd()) {
      ++it;
      if (it == _readers.end()) {
        _is_end = true;
      }
    }
  }

  Reader_ptr clone() const override {
    UnionReaderSet *res = new UnionReaderSet;
    for (auto r : _readers) {
      res->add_rdr(r->clone());
    }
    return Reader_ptr{res};
  }
  void reset() override {
    it = _readers.begin();
    _is_end = false;
    for (auto &c : _readers) {
      c->reset();
    }
  }
};

class Engine::Private {
public:
  Private(const PageManager::Params &page_storage_params,
          dariadb::storage::Capacitor::Params cap_params,
          dariadb::storage::Engine::Limits limits)
      : /*mem_storage{new MemoryStorage()},*/ _page_manager_params(page_storage_params),
        _cap_params(cap_params), _limits(limits) {
    _subscribe_notify.start();
    PageManager::start(_page_manager_params);
    mem_cap = new Capacitor(PageManager::instance(), _cap_params);
    // mem_storage_raw = dynamic_cast<MemoryStorage *>(mem_storage.get());
  }
  ~Private() {
    _subscribe_notify.stop();
    this->flush();
    delete mem_cap;
    PageManager::stop();
  }

  Time minTime() {
    std::lock_guard<std::recursive_mutex> lg(_locker);
    auto pmin = PageManager::instance()->minTime();
    auto cmin = mem_cap->minTime();
    return std::min(pmin, cmin);
  }

  Time maxTime() {
    std::lock_guard<std::recursive_mutex> lg(_locker);
    auto pmax = PageManager::instance()->maxTime();
    auto cmax = mem_cap->maxTime();
    return std::max(pmax, cmax);
  }

  bool minMaxTime(dariadb::Id id, dariadb::Time *minResult, dariadb::Time *maxResult) {
    std::lock_guard<std::recursive_mutex> lg(_locker);
    dariadb::Time subMin1, subMax1;
    auto pr = PageManager::instance()->minMaxTime(id, &subMin1, &subMax1);
    dariadb::Time subMin2, subMax2;
    auto mr = mem_cap->minMaxTime(id, &subMin2, &subMax2);

    if (!pr) {
      *minResult = subMin2;
      *maxResult = subMax2;
      return mr;
    }
    if (!mr) {
      *minResult = subMin1;
      *maxResult = subMax1;
      return pr;
    }
    *minResult = std::min(subMin1, subMin2);
    *maxResult = std::max(subMax1, subMax2);
    return true;
  }

  append_result append(const Meas &value) {
    append_result result{};
    // result = PageManager::instance()->append(value);
    result = mem_cap->append(value);
    if (result.writed == 1) {
      _subscribe_notify.on_append(value);
    }

    return result;
  }

  void subscribe(const IdArray &ids, const Flag &flag, const ReaderClb_ptr &clbk) {
    auto new_s = std::make_shared<SubscribeInfo>(ids, flag, clbk);
    _subscribe_notify.add(new_s);
  }

  Reader_ptr currentValue(const IdArray &ids, const Flag &flag) {
    return mem_cap->currentValue(ids, flag);
  }

  void flush() {
    std::lock_guard<std::recursive_mutex> lg(_locker);
    this->mem_cap->flush();
    PageManager::instance()->flush();
  }

  Engine::QueueSizes queue_size() const {
    QueueSizes result;
    result.page = PageManager::instance()->in_queue_size();
    result.cap = this->mem_cap->in_queue_size();
    return result;
  }

  // Inherited via MeasStorage
  Reader_ptr readInterval(const QueryInterval &q) {
    UnionReaderSet *raw_result = new UnionReaderSet();

    for (auto id : q.ids) {
      InnerReader *raw_rdr = new InnerReader(q.flag, q.from, q.to);
      UnionReader *raw_res = new UnionReader();
      raw_res->page_reader = Reader_ptr{raw_rdr};
      raw_rdr->_ids.push_back(id);

      dariadb::Time minT, maxT;
      QueryInterval local_q = q;
      local_q.ids.clear();
      local_q.ids.push_back(id);
      if (!mem_cap->minMaxTime(id, &minT, &maxT)) {
        auto chunkLinks = PageManager::instance()->chunksByIterval(local_q);
        auto page_cursor = PageManager::instance()->readLinks(chunkLinks);
        raw_rdr->add(page_cursor);
      } else {

        if (minT <= q.from && maxT >= q.to) {
          auto mc_reader = mem_cap->readInterval(local_q);
          raw_res->cap_reader = Reader_ptr{mc_reader};
        } else {
          local_q.to = minT;
          auto chunkLinks = PageManager::instance()->chunksByIterval(local_q);
          auto page_cursor = PageManager::instance()->readLinks(chunkLinks);
          raw_rdr->add(page_cursor);
          local_q.from = minT;
          local_q.to = q.to;

          auto mc_reader = mem_cap->readInterval(local_q);
          raw_res->cap_reader = Reader_ptr{mc_reader};
        }
      }
      raw_result->add_rdr(Reader_ptr{raw_res});
    }
    return Reader_ptr(raw_result);
  }

  Reader_ptr readInTimePoint(const QueryTimePoint &q) {
    UnionReaderSet *raw_result = new UnionReaderSet();
    for (auto id : q.ids) {
      dariadb::Time minT, maxT;
      QueryTimePoint local_q = q;
      local_q.ids.clear();
      local_q.ids.push_back(id);

      if (mem_cap->minMaxTime(id, &minT, &maxT) &&
          utils::inInterval(minT, maxT, local_q.time_point)) {
        auto subres = mem_cap->readInTimePoint(local_q);
        raw_result->add_rdr(subres);
      } else {
        auto id2meas = PageManager::instance()->valuesBeforeTimePoint(local_q);

        TP_Reader *raw_tp_reader = new TP_Reader;
        if (!id2meas.empty()) {
          raw_tp_reader->_ids.resize(id2meas.size());
          for (auto kv : id2meas) {
            raw_tp_reader->_values.push_back(kv.second);
            raw_tp_reader->_ids.push_back(kv.first);
          }
        } else {
          if (id2meas.empty()) {
            raw_tp_reader->_ids.resize(size_t(1));
            auto e = Meas::empty(id);
            e.flag = Flags::_NO_DATA;
            e.time = q.time_point;
            raw_tp_reader->_values.push_back(e);
            raw_tp_reader->_ids.push_back(id);
          }
        }
        raw_tp_reader->reset();
        Reader_ptr subres{raw_tp_reader};
        raw_result->add_rdr(subres);
      }
    }
    return Reader_ptr(raw_result);
  }

protected:
  //  std::shared_ptr<MemoryStorage> mem_storage;
  // storage::MemoryStorage *mem_storage_raw;
  storage::Capacitor *mem_cap;

  storage::PageManager::Params _page_manager_params;
  dariadb::storage::Capacitor::Params _cap_params;
  dariadb::storage::Engine::Limits _limits;

  mutable std::recursive_mutex _locker;
  SubscribeNotificator _subscribe_notify;
};

Engine::Engine(storage::PageManager::Params page_manager_params,
               dariadb::storage::Capacitor::Params cap_params,
               const dariadb::storage::Engine::Limits &limits)
    : _impl{new Engine::Private(page_manager_params, cap_params, limits)} {}

Engine::~Engine() {
  _impl = nullptr;
}

Time Engine::minTime() {
  return _impl->minTime();
}

Time Engine::maxTime() {
  return _impl->maxTime();
}
bool Engine::minMaxTime(dariadb::Id id, dariadb::Time *minResult,
                        dariadb::Time *maxResult) {
  return _impl->minMaxTime(id, minResult, maxResult);
}

append_result Engine::append(const Meas &value) {
  return _impl->append(value);
}

void Engine::subscribe(const IdArray &ids, const Flag &flag, const ReaderClb_ptr &clbk) {
  _impl->subscribe(ids, flag, clbk);
}

Reader_ptr Engine::currentValue(const IdArray &ids, const Flag &flag) {
  return _impl->currentValue(ids, flag);
}

void Engine::flush() {
  _impl->flush();
}

Engine::QueueSizes Engine::queue_size() const {
  return _impl->queue_size();
}

// Reader_ptr dariadb::storage::Engine::readInterval(Time from, Time to){
//	return _impl->readInterval(from, to);
//}

// Reader_ptr dariadb::storage::Engine::readInTimePoint(Time time_point) {
//	return _impl->readInTimePoint(time_point);
//}

Reader_ptr Engine::readInterval(const QueryInterval &q) {
  return _impl->readInterval(q);
}

Reader_ptr Engine::readInTimePoint(const QueryTimePoint &q) {
  return _impl->readInTimePoint(q);
}
<|endoftext|>


<commit_before>/*
 * Entry point for the raytracer binary.
 * Autor: Dino Wernli
 */

#include <fstream>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/text_format.h>
#include <memory>
#include <streambuf>
#include <string>

#include "listener/bmp_exporter.h"
#include "listener/ppm_exporter.h"
#include "listener/progress_listener.h"
#include "proto/config/renderer_config.pb.h"
#include "proto/config/scene_config.pb.h"
#include "proto/scene/scene_data.pb.h"
#include "renderer/renderer.h"
#include "scene/scene.h"

using raytracer::RendererConfig;
using raytracer::SceneConfig;

// Renderer config flags.
DEFINE_bool(shadows, true, "Whether or not shadows are rendered");

DEFINE_uint64(recursion_depth, 10, "How deep to evaluate reflective and "
                                   "refractive rays");

DEFINE_uint64(rays_per_pixel, 1, "The number of randomly jittered rays to "
                                 "shoot through each pixel");

DEFINE_bool(use_kd_tree, true, "Whether or not to use a KdTree in the scene");

DEFINE_uint64(worker_threads, 8, "Number of rendering worker threads to use");

// Camera config flags.
DEFINE_int32(image_resolution_x, -1, "Optional override for the horizontal "
                                      "resolution of the image");

DEFINE_int32(image_resolution_y, -1, "Optional override for the vertical "
                                      "resolution of the image");

// Output flags.
DEFINE_string(bmp_file, "image", "If <file> is passed, a BMP image will be "
                                  "saved at 'output/<file>.bmp'");

DEFINE_string(ppm_file, "", "If <file> is passed, a PPM image will be saved at "
                            "'output/<file>.ppm'");

DEFINE_string(scene_data, "data/scene/quadrics_tori.sd",
                          "A file from which to parse the items in the scene");

/* General Todos:

TODO(dinow): Add textures, perlin noise
TODO(dinow): Add supersampling (as preparation for global illumination).
TODO(dinow): Add possibility to load renderer config from file.
TODO(dinow): Rename proto namespace to "config" or "proto".
TODO(dinow): Put everything else in namespace "raytracer".
TODO(dinow): Implement a GUI and/or webserver.
TODO(dinow): Implement statistics (intersection counting).
TODO(dinow): Remove the default values from the object constructors.
             Leave them only in the protos. Or leave them in both but always
             pass the arguments.
*/

bool LoadSceneData(const std::string& path, raytracer::SceneData* output) {
  std::ifstream stream(path);
  if (!stream.is_open()) {
    return false;
  }
  std::string string((std::istreambuf_iterator<char>(stream)),
                      std::istreambuf_iterator<char>());
  return google::protobuf::TextFormat::ParseFromString(string, output);
}

int main(int argc, char **argv) {
  // LOG(INFO): Always logged.
  // DVLOG(i): Only compiled in if DEBUG flag set, logged if log level is >= i.
  //
  // Always run "GLOG_logtostderr=1 ./build/raytracer" (assumed below).
  // Run "GLOG_v=i ./build/raytracer" for verbose logging up to level i.
  google::InitGoogleLogging(argv[0]);

  // Initializes the flags libraray. The last argument tells the library to
  // remove the flags from argc and argv, so that only real arguments remain.
  google::ParseCommandLineFlags(&argc, &argv, true);

  // Load the configuration from the passed arguments.
  SceneConfig scene_config;
  if (FLAGS_use_kd_tree) {
    scene_config.mutable_kd_tree_config();
  }
  if (FLAGS_scene_data.empty()) {
    LOG(ERROR) << "Failed to load scene data, no file provided";
    return EXIT_FAILURE;
  }
  if (LoadSceneData(FLAGS_scene_data, scene_config.mutable_scene_data())) {
    LOG(INFO) << "Loaded scene data from: " << FLAGS_scene_data;
  } else {
    LOG(ERROR) << "Failed to load scene data from: " << FLAGS_scene_data;
    return EXIT_FAILURE;
  }

  auto& camera_config = *(scene_config.mutable_scene_data()->mutable_camera());
  if (FLAGS_image_resolution_x > 0) {
    camera_config.set_resolution_x(FLAGS_image_resolution_x);
  }
  if (FLAGS_image_resolution_y > 0) {
    camera_config.set_resolution_y(FLAGS_image_resolution_y);
  }

  // Build the scene from the config.
  std::unique_ptr<Scene> scene(Scene::FromConfig(scene_config));

  // Load renderer config from flags.
  RendererConfig renderer_config;
  renderer_config.set_threads(FLAGS_worker_threads);
  renderer_config.set_shadows(FLAGS_shadows);
  renderer_config.set_recursion_depth(FLAGS_recursion_depth);
  renderer_config.set_rays_per_pixel(FLAGS_rays_per_pixel);

  // Build a renderer from the config.
  std::unique_ptr<Renderer> renderer(Renderer::FromConfig(renderer_config));

  renderer->AddListener(new ProgressListener());
  if (!FLAGS_bmp_file.empty()) {
    renderer->AddListener(new BmpExporter("output/" + FLAGS_bmp_file + ".bmp"));
  }
  if (!FLAGS_ppm_file.empty()) {
    renderer->AddListener(new PpmExporter("output/" + FLAGS_ppm_file + ".ppm"));
  }

  // Render the image.
  renderer->Render(scene.get());

  // Free all memory in the various Google libraries.
  google::protobuf::ShutdownProtobufLibrary();
  google::ShutdownGoogleLogging();
  google::ShutDownCommandLineFlags();
  return EXIT_SUCCESS;
}
<commit_msg>Remove confusing flag documentation.<commit_after>/*
 * Entry point for the raytracer binary.
 * Autor: Dino Wernli
 */

#include <fstream>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/text_format.h>
#include <memory>
#include <streambuf>
#include <string>

#include "listener/bmp_exporter.h"
#include "listener/ppm_exporter.h"
#include "listener/progress_listener.h"
#include "proto/config/renderer_config.pb.h"
#include "proto/config/scene_config.pb.h"
#include "proto/scene/scene_data.pb.h"
#include "renderer/renderer.h"
#include "scene/scene.h"

using raytracer::RendererConfig;
using raytracer::SceneConfig;

// Renderer config flags.
DEFINE_bool(shadows, true, "Whether or not shadows are rendered");

DEFINE_uint64(recursion_depth, 10, "How deep to evaluate reflective and "
                                   "refractive rays");

DEFINE_uint64(rays_per_pixel, 1, "The number of randomly jittered rays to "
                                 "shoot through each pixel");

DEFINE_bool(use_kd_tree, true, "Whether or not to use a KdTree in the scene");

DEFINE_uint64(worker_threads, 8, "Number of rendering worker threads to use");

// Camera config flags.
DEFINE_int32(image_resolution_x, -1, "Optional override for the horizontal "
                                      "resolution of the image");

DEFINE_int32(image_resolution_y, -1, "Optional override for the vertical "
                                      "resolution of the image");

// Output flags.
DEFINE_string(bmp_file, "image", "If <file> is passed, a BMP image will be "
                                  "saved at 'output/<file>.bmp'");

DEFINE_string(ppm_file, "", "If <file> is passed, a PPM image will be saved at "
                            "'output/<file>.ppm'");

DEFINE_string(scene_data, "data/scene/quadrics_tori.sd",
                          "A file from which to parse the items in the scene");

/* General Todos:

TODO(dinow): Add textures, perlin noise
TODO(dinow): Add possibility to load renderer config from file.
TODO(dinow): Rename proto namespace to "config" or "proto".
TODO(dinow): Put everything else in namespace "raytracer".
TODO(dinow): Implement a GUI and/or webserver.
TODO(dinow): Implement statistics (intersection counting).
TODO(dinow): Remove the default values from the object constructors.
             Leave them only in the protos. Or leave them in both but always
             pass the arguments.
*/

bool LoadSceneData(const std::string& path, raytracer::SceneData* output) {
  std::ifstream stream(path);
  if (!stream.is_open()) {
    return false;
  }
  std::string string((std::istreambuf_iterator<char>(stream)),
                      std::istreambuf_iterator<char>());
  return google::protobuf::TextFormat::ParseFromString(string, output);
}

int main(int argc, char **argv) {
  // LOG(INFO): Always logged.
  // DVLOG(i): Only compiled in if DEBUG flag set.
  //
  // Run <binary name> --logtostderr to see log output.
  // Run <binary name> --logtostderr --v=<i> for DVLOG(j) message for j <= i.
  google::InitGoogleLogging(argv[0]);
  google::ParseCommandLineFlags(&argc, &argv, true);

  DVLOG(1) << "TEST";

  // Load the configuration from the passed arguments.
  SceneConfig scene_config;
  if (FLAGS_use_kd_tree) {
    scene_config.mutable_kd_tree_config();
  }
  if (FLAGS_scene_data.empty()) {
    LOG(ERROR) << "Failed to load scene data, no file provided";
    return EXIT_FAILURE;
  }
  if (LoadSceneData(FLAGS_scene_data, scene_config.mutable_scene_data())) {
    LOG(INFO) << "Loaded scene data from: " << FLAGS_scene_data;
  } else {
    LOG(ERROR) << "Failed to load scene data from: " << FLAGS_scene_data;
    return EXIT_FAILURE;
  }

  auto& camera_config = *(scene_config.mutable_scene_data()->mutable_camera());
  if (FLAGS_image_resolution_x > 0) {
    camera_config.set_resolution_x(FLAGS_image_resolution_x);
  }
  if (FLAGS_image_resolution_y > 0) {
    camera_config.set_resolution_y(FLAGS_image_resolution_y);
  }

  // Build the scene from the config.
  std::unique_ptr<Scene> scene(Scene::FromConfig(scene_config));

  // Load renderer config from flags.
  RendererConfig renderer_config;
  renderer_config.set_threads(FLAGS_worker_threads);
  renderer_config.set_shadows(FLAGS_shadows);
  renderer_config.set_recursion_depth(FLAGS_recursion_depth);
  renderer_config.set_rays_per_pixel(FLAGS_rays_per_pixel);

  // Build a renderer from the config.
  std::unique_ptr<Renderer> renderer(Renderer::FromConfig(renderer_config));

  renderer->AddListener(new ProgressListener());
  if (!FLAGS_bmp_file.empty()) {
    renderer->AddListener(new BmpExporter("output/" + FLAGS_bmp_file + ".bmp"));
  }
  if (!FLAGS_ppm_file.empty()) {
    renderer->AddListener(new PpmExporter("output/" + FLAGS_ppm_file + ".ppm"));
  }

  // Render the image.
  renderer->Render(scene.get());

  // Free all memory in the various Google libraries.
  google::protobuf::ShutdownProtobufLibrary();
  google::ShutdownGoogleLogging();
  google::ShutDownCommandLineFlags();
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include <iostream>
#include <boost/config.hpp>
#include <fcntl.h>
#include <stdio.h>

int test_main();

extern bool tests_failure;

#include "libtorrent/assert.hpp"
#include <signal.h>

void sig_handler(int sig)
{
	char stack_text[10000];
	print_backtrace(stack_text, sizeof(stack_text), 30);
	char const* sig_name = 0;
	switch (sig)
	{
#define SIG(x) case x: sig_name = #x; break
		SIG(SIGSEGV);
		SIG(SIGBUS);
		SIG(SIGILL);
		SIG(SIGABRT);
		SIG(SIGFPE);
		SIG(SIGSYS);
#undef SIG
	};
	fprintf(stderr, "signal: %s caught:\n%s\n", sig_name, stack_text);
	exit(138);
}

int main()
{
#ifdef O_NONBLOCK
	// on darwin, stdout is set to non-blocking mode by default
	// which sometimes causes tests to fail with EAGAIN just
	// by printing logs
	int flags = fcntl(fileno(stdout), F_GETFL, 0);
	fcntl(fileno(stdout), F_SETFL, flags & ~O_NONBLOCK);
	flags = fcntl(fileno(stderr), F_GETFL, 0);
	fcntl(fileno(stderr), F_SETFL, flags & ~O_NONBLOCK);
#endif

	signal(SIGSEGV, &sig_handler);
	signal(SIGBUS, &sig_handler);
	signal(SIGILL, &sig_handler);
	signal(SIGABRT, &sig_handler);
	signal(SIGFPE, &sig_handler);
	signal(SIGSYS, &sig_handler);

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		test_main();
#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception const& e)
	{
		std::cerr << "Terminated with exception: \"" << e.what() << "\"\n";
		tests_failure = true;
	}
	catch (...)
	{
		std::cerr << "Terminated with unknown exception\n";
		tests_failure = true;
	}
#endif
	fflush(stdout);
	fflush(stderr);
	return tests_failure ? 1 : 0;
}

<commit_msg>fix windows unit test build<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include <iostream>
#include <boost/config.hpp>
#include <fcntl.h>
#include <stdio.h>

int test_main();

extern bool tests_failure;

#include "libtorrent/assert.hpp"
#include <signal.h>

void sig_handler(int sig)
{
	char stack_text[10000];
	print_backtrace(stack_text, sizeof(stack_text), 30);
	char const* sig_name = 0;
	switch (sig)
	{
#define SIG(x) case x: sig_name = #x; break
		SIG(SIGSEGV);
#ifdef SIGBUS
		SIG(SIGBUS);
#endif
		SIG(SIGILL);
		SIG(SIGABRT);
		SIG(SIGFPE);
#ifdef SIGSYS
		SIG(SIGSYS);
#endif
#undef SIG
	};
	fprintf(stderr, "signal: %s caught:\n%s\n", sig_name, stack_text);
	exit(138);
}

int main()
{
#ifdef O_NONBLOCK
	// on darwin, stdout is set to non-blocking mode by default
	// which sometimes causes tests to fail with EAGAIN just
	// by printing logs
	int flags = fcntl(fileno(stdout), F_GETFL, 0);
	fcntl(fileno(stdout), F_SETFL, flags & ~O_NONBLOCK);
	flags = fcntl(fileno(stderr), F_GETFL, 0);
	fcntl(fileno(stderr), F_SETFL, flags & ~O_NONBLOCK);
#endif

	signal(SIGSEGV, &sig_handler);
#ifdef SIGBUS
	signal(SIGBUS, &sig_handler);
#endif
	signal(SIGILL, &sig_handler);
	signal(SIGABRT, &sig_handler);
	signal(SIGFPE, &sig_handler);
#ifdef SIGSYS
	signal(SIGSYS, &sig_handler);
#endif

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		test_main();
#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception const& e)
	{
		std::cerr << "Terminated with exception: \"" << e.what() << "\"\n";
		tests_failure = true;
	}
	catch (...)
	{
		std::cerr << "Terminated with unknown exception\n";
		tests_failure = true;
	}
#endif
	fflush(stdout);
	fflush(stderr);
	return tests_failure ? 1 : 0;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <vector>

#include "libx6adc.h"
#include "constants.h"
#include "X6_1000.h"

using namespace std;

// N-wide hex output with 0x
template <unsigned int N>
std::ostream& hexn(std::ostream& out) {
  return out << "0x" << std::hex << std::setw(N) << std::setfill('0');
}

int main ()
{
  cout << "BBN X6-1000 Test Executable" << endl;

  set_logging_level(5);

  int numDevices;
  numDevices = get_num_devices();

  cout << numDevices << " X6 device" << (numDevices > 1 ? "s": "")  << " found" << endl;

  if (numDevices < 1)
  	return 0;

  // char s[] = "stdout";
  // set_log(s);

  cout << "Attempting to initialize libaps" << endl;

  int rc;
  rc = connect_by_ID(0);

  cout << "connect(0) returned " << rc << endl;

  cout << "Firmware revision: " << read_firmware_version(0) << endl;

  cout << "current logic temperature method 1 = " << get_logic_temperature(0, 0) << endl;
  cout << "current logic temperature method 2 = " << get_logic_temperature(0, 1) << endl;

  cout << "ADC0 stream ID: " << hexn<8> << read_register(0, 0x0800, 64) << endl;
  cout << "ADC1 stream ID: " << hexn<8> << read_register(0, 0x0800, 65) << std::dec << endl;

  cout << "current PLL frequency = " << get_sampleRate(0)/1e6 << " MHz" << endl;

  cout << "Set sample rate to 100 MHz" << endl;

  set_sampleRate(0,100e6);

  cout << "current PLL frequency = " << get_sampleRate(0)/1e6 << " MHz" << endl;

  cout << "Set sample rate back to 1000 MHz" << endl;

  set_sampleRate(0,1e9);

  cout << "current PLL frequency = " << get_sampleRate(0)/1e6 << " MHz" << endl;

  cout << "setting trigger source = EXTERNAL_TRIGGER" << endl;

  set_trigger_source(0, X6_1000::EXTERNAL_TRIGGER);

  cout << "get trigger source returns " << ((get_trigger_source(0) == X6_1000::SOFTWARE_TRIGGER) ? "SOFTWARE_TRIGGER" : "EXTERNAL_TRIGGER") << endl;

  cout << "Enabling physical channel 1" << endl;
  enable_stream(0, 1, 0, 0);

  cout << "setting averager parameters to record 10 segments of 1024 samples" << endl;

  set_averager_settings(0, 1024, 10, 1, 1);

  cout << "Acquiring" << endl;

  acquire(0);

  cout << "Waiting for acquisition to complete" << endl;
  int success = wait_for_acquisition(0, 1);
  if (success == X6_OK) {
    cout << "Acquistion finished" << endl;
  } else if (success == X6_1000::TIMEOUT) {
    cout << "Acquisition timed out" << endl;
  } else {
    cout << "Unknown error in wait_for_acquisition" << endl;
  }

  cout << "Transferring waveform ch1" << endl;
  vector<double> buffer(10240);
  ChannelTuple rawch = {1, 0, 0};
  ChannelTuple channels[1] = {rawch};
  transfer_waveform(0, channels, 1, buffer.data(), 10240);

  cout << "Stopping" << endl;

  stop(0);

  rc = disconnect(0);

  cout << "disconnect(0) returned " << rc << endl;

  return 0;
}<commit_msg>Updated C test bench.<commit_after>#include <iostream>
#include <iomanip>
#include <vector>

#include "libx6adc.h"
#include "constants.h"
#include "X6_1000.h"

using namespace std;

// N-wide hex output with 0x
template <unsigned int N>
std::ostream& hexn(std::ostream& out) {
  return out << "0x" << std::hex << std::setw(N) << std::setfill('0');
}

int main ()
{
  cout << "BBN X6-1000 Test Executable" << endl;

  set_logging_level(8);

  int numDevices;
  numDevices = get_num_devices();

  cout << numDevices << " X6 device" << (numDevices > 1 ? "s": "")  << " found" << endl;

  if (numDevices < 1)
  	return 0;

  // char s[] = "stdout";
  // set_log(s);

  cout << "Attempting to initialize libaps" << endl;

  int rc;
  rc = connect_by_ID(0);

  cout << "connect(0) returned " << rc << endl;

  cout << "Firmware revision: " << read_firmware_version(0) << endl;

  cout << "current logic temperature method 1 = " << get_logic_temperature(0, 0) << endl;
  cout << "current logic temperature method 2 = " << get_logic_temperature(0, 1) << endl;

  cout << "ADC0 stream ID: " << hexn<8> << read_register(0, 0x0800, 64) << endl;
  cout << "ADC1 stream ID: " << hexn<8> << read_register(0, 0x0800, 65) << std::dec << endl;

  cout << "current PLL frequency = " << get_sampleRate(0)/1e6 << " MHz" << endl;

  // cout << "Set sample rate to 100 MHz" << endl;

  // set_sampleRate(0,100e6);

  // cout << "current PLL frequency = " << get_sampleRate(0)/1e6 << " MHz" << endl;

  // cout << "Set sample rate back to 1000 MHz" << endl;

  // set_sampleRate(0,1e9);

  // cout << "current PLL frequency = " << get_sampleRate(0)/1e6 << " MHz" << endl;

  cout << "setting trigger source = EXTERNAL_TRIGGER" << endl;

  set_trigger_source(0, X6_1000::EXTERNAL_TRIGGER);

  cout << "get trigger source returns " << ((get_trigger_source(0) == X6_1000::SOFTWARE_TRIGGER) ? "SOFTWARE_TRIGGER" : "EXTERNAL_TRIGGER") << endl;

  cout << "Enabling physical channel 1" << endl;
  enable_stream(0, 1, 0, 0);
  enable_stream(0, 1, 1, 0);
  enable_stream(0, 1, 1, 1);
  enable_stream(0, 1, 2, 0);
  enable_stream(0, 1, 2, 1);
  enable_stream(0, 2, 0, 0);
  enable_stream(0, 2, 1, 0);
  enable_stream(0, 2, 1, 1);
  enable_stream(0, 2, 2, 0);
  enable_stream(0, 2, 2, 1);

  cout << "Writing kernel lengths" << endl;
  write_register(0, 0x2000, 24+1-1, 2);
  write_register(0, 0x2000, 24+2-1, 2);
  write_register(0, 0x2100, 24+1-1, 2);
  write_register(0, 0x2100, 24+2-1, 2);

  cout << "setting averager parameters to record 10 segments of 1024 samples" << endl;

  set_averager_settings(0, 2048, 9, 1, 1);

  cout << "Acquiring" << endl;

  acquire(0);

  cout << "Waiting for acquisition to complete" << endl;
  int success = wait_for_acquisition(0, 2);
  if (success == X6_OK) {
    cout << "Acquistion finished" << endl;
  } else if (success == X6_1000::TIMEOUT) {
    cout << "Acquisition timed out" << endl;
  } else {
    cout << "Unknown error in wait_for_acquisition" << endl;
  }

  cout << "Transferring waveform ch1" << endl;
  vector<double> buffer;
  ChannelTuple rawch = {1, 0, 0};
  ChannelTuple channels[1] = {rawch};
  int bufsize = get_buffer_size(0, channels, 1);
  buffer.resize(bufsize);
  transfer_waveform(0, channels, 1, buffer.data(), buffer.size());

  cout << "Stopping" << endl;

  stop(0);

  rc = disconnect(0);

  cout << "disconnect(0) returned " << rc << endl;

  return 0;
}<|endoftext|>


<commit_before>
/*
    This file is part of the "pfkutils" tools written by Phil Knaack
    (pfk@pfk.org).
    Copyright (C) 2008  Phillip F Knaack

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

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

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/** \file PageCache.cc
 * \brief Implements PageCache and PageIOFileDescriptor.
 * \author Phillip F Knaack */

/** \page PageCache PageCache object

The PageIO interface is consumed by a PageCache object.  This is a
cache of PageCachePage objects up to a maximum number.  The method
PageCache::get() will retrieve a page from the cache if it is in
cache, or fetch it from the PageIO interface if it is not (and add it
to the cache).  A page returned by PageCache::get() is in the \c locked
state with a \c reference \c count greator than 0.  When the caller is
done using the page object, it must call PageCache::release() to
return the page to the cache.  This decreases the reference count on
the page.  When the PageCache::flush() method is called, all pages
currently in cache are synced up with the backend storage, by invoking
the PageIO interface to write any pages marked as dirty.

If the number of pages cached in PageCache reaches the maximum, then a
true \c Least-Recently-Used (LRU) algorithm is used to determine which
old page to remove from cache.  If the oldest page is clean (in sync
with the PageIO backend storage) then the memory is simply freed.  If
the oldest page is dirty, then PageIO::put_page() is invoked prior to
freeing the page memory.

When the \c for_write flag is set on a PageCache::get() operation, this
indicates that the user has no intention of using any data currently
stored in the page, and instead intends to write data to the whole
page.  This results in an optimization where the PageIO::get_page()
method is not called, instead an empty PageCachePage is built and
returned to the user.  (Why read a page from the file if you're just
going to throw the data away and write the whole page with new data
anyway?)

\note The maximum count only applies to unlocked pages.  A locked
page does not count against the limit.

Be sure to call PageCachePage::mark_dirty() to ensure that flushes are
written to the file properly.

Next: \ref BlockCache

*/

#include "PageCache.h"
#include "PageCache_internal.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>

PageCache :: PageCache( PageIO * _io, int _max_pages )
{
    io = _io;
    max_pages = _max_pages;
    pgs = new PageCachePageList;
    time( &last_flush );
}

PageCache :: ~PageCache(void)
{
    PCPInt * p;
    flush();
    while ((p = pgs->get_head()) != NULL)
    {
        if (p->is_locked())
        {
            fprintf(stderr, "error page is locked at delete time!\n");
            exit(1);
        }
        pgs->remove(p);
        delete p;
    }
    delete pgs;
}

PageCachePage *
PageCache :: get(int page_number, bool for_write)
{
    PCPInt * ret;
    ret = pgs->find( page_number );
    if (ret != NULL)
    {
        pgs->ref(ret);
        if (for_write)
        {
            memset(ret->ptr, 0, PC_PAGE_SIZE);
            ret->dirty = true;
        }
        return ret;
    }
    ret = new PCPInt( page_number );
    if (for_write)
    {
        memset(ret->ptr, 0, PC_PAGE_SIZE);
        ret->dirty = true;
    }
    else
    {
        if (!io->get_page(ret))
        {
            fprintf(stderr, "error getting page %d\n", page_number);
            exit( 1 );
        }
    }
    pgs->add(ret,true);
    return ret;
}

void
PageCache :: release( PageCachePage * _p, bool dirty )
{
    PCPInt * p = (PCPInt *)_p;
    if (dirty)
        p->dirty = true;
    pgs->deref(p);
    while (pgs->get_lru_cnt() > max_pages)
    {
        p = pgs->get_oldest();
        pgs->remove(p);
        if (p->dirty)
        {
            if (!io->put_page(p))
            {
                fprintf(stderr, "error putting page %d\n",
                        p->page_number);
                exit( 1 );
            }
        }
        delete p;
    }
    time_t now;
    if ( time( &now ) != last_flush )
    {
        last_flush = now;
        flush();
    }
}

void
PageCache :: truncate_pages(int num_pages)
{
    PCPInt * p, * np;
    for (p = pgs->get_head(); p; p = np)
    {
        np = pgs->get_next(p);
        if (p->page_number >= num_pages)
        {
            if (p->is_locked())
            {
                fprintf(stderr, "ERROR: PageCache :: truncate_pages: "
                        "page %d is still locked\n", p->page_number);
                return;
            }
            else
                pgs->remove(p);
        }
    }
    io->truncate_pages(num_pages);
}

/** compare page numbers of two PCPInt objects, for qsort.
 * \param _a the first PCPInt to compare
 * \param _b the second PCPInt to compare
 * \return positive if _a's page number is greator than _b's page number,
 *         negative if _a's page number is less than _b's page number,
 *         or zero if they are equal.
 * \relates PageCache
 *
 * This function compares two PCPInt objects.  Its purpose is to be a
 * utility function to the standard C library function qsort, to assist
 * qsort in sorting an array of PCPInt objects.  */

static int
page_compare( const void * _a, const void * _b )
{
    PCPInt * a = *(PCPInt **)_a;
    PCPInt * b = *(PCPInt **)_b;
    if (a->get_page_number() > b->get_page_number())
        return 1;
    if (a->get_page_number() < b->get_page_number())
        return -1;
    return 0;
}

void
PageCache :: flush(void)
{
    PCPInt * p;
    int i, count;

    count = pgs->get_dirty_cnt();
    if (count == 0)
        return;

    PCPInt * pages[count];
    i = 0;
    for (p = pgs->get_dirty_head(); p; p = pgs->get_dirty_next(p))
        pages[i++] = p;

    qsort( pages, count, sizeof(PCPInt*),
           (int(*)(const void *, const void *))page_compare );

    printf("flushing %d pages\n", count);

    for (i = 0; i < count; i++)
    {
        p = pages[i];
        pgs->ref(p);
        if (!io->put_page(p))
        {
            fprintf(stderr, "error putting page %d\n", p->page_number);
            exit( 1 );
        }
        // the page is now synced with the file.
        p->dirty = false;
        pgs->deref(p);
    }
}
<commit_msg>ugh noisy printf<commit_after>
/*
    This file is part of the "pfkutils" tools written by Phil Knaack
    (pfk@pfk.org).
    Copyright (C) 2008  Phillip F Knaack

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

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

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/** \file PageCache.cc
 * \brief Implements PageCache and PageIOFileDescriptor.
 * \author Phillip F Knaack */

/** \page PageCache PageCache object

The PageIO interface is consumed by a PageCache object.  This is a
cache of PageCachePage objects up to a maximum number.  The method
PageCache::get() will retrieve a page from the cache if it is in
cache, or fetch it from the PageIO interface if it is not (and add it
to the cache).  A page returned by PageCache::get() is in the \c locked
state with a \c reference \c count greator than 0.  When the caller is
done using the page object, it must call PageCache::release() to
return the page to the cache.  This decreases the reference count on
the page.  When the PageCache::flush() method is called, all pages
currently in cache are synced up with the backend storage, by invoking
the PageIO interface to write any pages marked as dirty.

If the number of pages cached in PageCache reaches the maximum, then a
true \c Least-Recently-Used (LRU) algorithm is used to determine which
old page to remove from cache.  If the oldest page is clean (in sync
with the PageIO backend storage) then the memory is simply freed.  If
the oldest page is dirty, then PageIO::put_page() is invoked prior to
freeing the page memory.

When the \c for_write flag is set on a PageCache::get() operation, this
indicates that the user has no intention of using any data currently
stored in the page, and instead intends to write data to the whole
page.  This results in an optimization where the PageIO::get_page()
method is not called, instead an empty PageCachePage is built and
returned to the user.  (Why read a page from the file if you're just
going to throw the data away and write the whole page with new data
anyway?)

\note The maximum count only applies to unlocked pages.  A locked
page does not count against the limit.

Be sure to call PageCachePage::mark_dirty() to ensure that flushes are
written to the file properly.

Next: \ref BlockCache

*/

#include "PageCache.h"
#include "PageCache_internal.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>

PageCache :: PageCache( PageIO * _io, int _max_pages )
{
    io = _io;
    max_pages = _max_pages;
    pgs = new PageCachePageList;
    time( &last_flush );
}

PageCache :: ~PageCache(void)
{
    PCPInt * p;
    flush();
    while ((p = pgs->get_head()) != NULL)
    {
        if (p->is_locked())
        {
            fprintf(stderr, "error page is locked at delete time!\n");
            exit(1);
        }
        pgs->remove(p);
        delete p;
    }
    delete pgs;
}

PageCachePage *
PageCache :: get(int page_number, bool for_write)
{
    PCPInt * ret;
    ret = pgs->find( page_number );
    if (ret != NULL)
    {
        pgs->ref(ret);
        if (for_write)
        {
            memset(ret->ptr, 0, PC_PAGE_SIZE);
            ret->dirty = true;
        }
        return ret;
    }
    ret = new PCPInt( page_number );
    if (for_write)
    {
        memset(ret->ptr, 0, PC_PAGE_SIZE);
        ret->dirty = true;
    }
    else
    {
        if (!io->get_page(ret))
        {
            fprintf(stderr, "error getting page %d\n", page_number);
            exit( 1 );
        }
    }
    pgs->add(ret,true);
    return ret;
}

void
PageCache :: release( PageCachePage * _p, bool dirty )
{
    PCPInt * p = (PCPInt *)_p;
    if (dirty)
        p->dirty = true;
    pgs->deref(p);
    while (pgs->get_lru_cnt() > max_pages)
    {
        p = pgs->get_oldest();
        pgs->remove(p);
        if (p->dirty)
        {
            if (!io->put_page(p))
            {
                fprintf(stderr, "error putting page %d\n",
                        p->page_number);
                exit( 1 );
            }
        }
        delete p;
    }
    time_t now;
    if ( time( &now ) != last_flush )
    {
        last_flush = now;
        flush();
    }
}

void
PageCache :: truncate_pages(int num_pages)
{
    PCPInt * p, * np;
    for (p = pgs->get_head(); p; p = np)
    {
        np = pgs->get_next(p);
        if (p->page_number >= num_pages)
        {
            if (p->is_locked())
            {
                fprintf(stderr, "ERROR: PageCache :: truncate_pages: "
                        "page %d is still locked\n", p->page_number);
                return;
            }
            else
                pgs->remove(p);
        }
    }
    io->truncate_pages(num_pages);
}

/** compare page numbers of two PCPInt objects, for qsort.
 * \param _a the first PCPInt to compare
 * \param _b the second PCPInt to compare
 * \return positive if _a's page number is greator than _b's page number,
 *         negative if _a's page number is less than _b's page number,
 *         or zero if they are equal.
 * \relates PageCache
 *
 * This function compares two PCPInt objects.  Its purpose is to be a
 * utility function to the standard C library function qsort, to assist
 * qsort in sorting an array of PCPInt objects.  */

static int
page_compare( const void * _a, const void * _b )
{
    PCPInt * a = *(PCPInt **)_a;
    PCPInt * b = *(PCPInt **)_b;
    if (a->get_page_number() > b->get_page_number())
        return 1;
    if (a->get_page_number() < b->get_page_number())
        return -1;
    return 0;
}

void
PageCache :: flush(void)
{
    PCPInt * p;
    int i, count;

    count = pgs->get_dirty_cnt();
    if (count == 0)
        return;

    PCPInt * pages[count];
    i = 0;
    for (p = pgs->get_dirty_head(); p; p = pgs->get_dirty_next(p))
        pages[i++] = p;

    qsort( pages, count, sizeof(PCPInt*),
           (int(*)(const void *, const void *))page_compare );

    //printf("flushing %d pages\n", count);

    for (i = 0; i < count; i++)
    {
        p = pages[i];
        pgs->ref(p);
        if (!io->put_page(p))
        {
            fprintf(stderr, "error putting page %d\n", p->page_number);
            exit( 1 );
        }
        // the page is now synced with the file.
        p->dirty = false;
        pgs->deref(p);
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: svxbox.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 16:29:56 $
 *
 *  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 _SVX_BOX_HXX
#define _SVX_BOX_HXX

// include ---------------------------------------------------------------

#ifndef _SVARRAY_HXX //autogen
#include <svtools/svarray.hxx>
#endif

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _COMBOBOX_HXX //autogen
#include <vcl/combobox.hxx>
#endif

// forward ---------------------------------------------------------------

class SvxBoxEntry;
class SvxListBase;

//#if 0 // _SOLAR__PRIVATE
SV_DECL_PTRARR( SvxEntryLst, SvxBoxEntry*, 10, 10 )
//#else
//typedef SvPtrarr SvxEntryLst;
//#endif

// class SvxBoxEntry -----------------------------------------------------

class SvxBoxEntry
{
    friend class SvxListBox;
    friend class SvxComboBox;

public:
    SvxBoxEntry( const String& aName, USHORT nId=0 );
    SvxBoxEntry( const SvxBoxEntry& rOrg );
    SvxBoxEntry();

    String              aName;
    USHORT              nId;

private:
    BOOL                bModified;
    BOOL                bNew;
};

// class SvxListBox ------------------------------------------------------

class SvxListBox : public ListBox
{
    using ListBox::InsertEntry;
    using ListBox::RemoveEntry;
    using ListBox::GetEntryPos;
    using ListBox::IsEntrySelected;
    using ListBox::SelectEntry;

public:
    SvxListBox( Window* pParent, WinBits nBits = WB_BORDER );
    SvxListBox( Window* pParent, const ResId& rId );
    ~SvxListBox();

    void                InsertNewEntry( const SvxBoxEntry& rEntry );
    void                InsertEntry( const SvxBoxEntry& rEntry,
                                     USHORT nId = LISTBOX_ENTRY_NOTFOUND );

    void                RemoveEntry( USHORT nPos );
    void                RemoveEntry( const SvxBoxEntry& rEntry );

    void                Clear();

    USHORT              GetEntryPos( const SvxBoxEntry& rEntry ) const;
    const SvxBoxEntry&  GetSvxBoxEntry( USHORT nIdx ) const;

    inline BOOL         IsEntrySelected( const SvxBoxEntry& rEntry ) const;
    const SvxBoxEntry&  GetSelectSvxBoxEntry( USHORT nIdx = 0 ) const;
    inline void         SelectEntry( const SvxBoxEntry& rEntry,
                                     BOOL bSelect = TRUE );

    void                ModifyEntry( USHORT nPos, const String& aName );
    USHORT              GetModifiedCount() const;
    const SvxBoxEntry&  GetModifiedEntry( USHORT nPos ) const;

    USHORT              GetRemovedCount() const;
    const SvxBoxEntry&  GetRemovedEntry( USHORT nPos ) const;

    USHORT              GetNewCount() const;
    const SvxBoxEntry&  GetNewEntry( USHORT nPos ) const;

private:
    SvxEntryLst         aEntryLst;
    SvxEntryLst         aDelEntryLst;
    SvxBoxEntry         aDefault;

    void                InitListBox();
    void                InsertSorted( SvxBoxEntry* pEntry );
};

// inlines ---------------------------------------------------------------

inline BOOL SvxListBox::IsEntrySelected( const SvxBoxEntry& aEntry ) const
    { return ListBox::IsEntrySelected( aEntry.aName ); }

inline void SvxListBox::SelectEntry( const SvxBoxEntry& aEntry, BOOL bSelect )
    { ListBox::SelectEntry( aEntry.aName, bSelect ); }

// enum SvxComboBoxStyle -------------------------------------------------

enum SvxComboBoxStyle
{
    SVX_CBS_UPPER       = 0x01,
    SVX_CBS_LOWER       = 0x02,
    SVX_CBS_ALL         = 0x04,
    SVX_CBS_FILENAME    = 0x08,
#ifdef WIN
    SVX_CBS_SW_FILENAME = SVX_CBS_FILENAME | SVX_CBS_LOWER
#else
    SVX_CBS_SW_FILENAME = SVX_CBS_FILENAME
#endif
};

// class SvxComboBox -----------------------------------------------------

class SvxComboBox : public ComboBox
{
    using ComboBox::InsertEntry;
    using ComboBox::RemoveEntry;
    using ComboBox::GetEntryPos;
    using Window::SetStyle;

public:
    SvxComboBox( Window* pParent,
                 WinBits nBits = WB_BORDER, USHORT nStyleBits = SVX_CBS_ALL );
    SvxComboBox( Window* pParent, const ResId& rId, USHORT nStyleBits = SVX_CBS_ALL );
    ~SvxComboBox();

    void                InsertNewEntry( const SvxBoxEntry& );
    void                InsertEntry( const SvxBoxEntry& );

    void                RemoveEntry( USHORT nPos );
    void                RemoveEntry( const SvxBoxEntry& rEntry );

    void                Clear();

    USHORT              GetEntryPos( const SvxBoxEntry& rEntry ) const;
    const SvxBoxEntry&  GetEntry( USHORT nIdx ) const;

    void                ModifyEntry( USHORT nPos, const String& aName );
    USHORT              GetModifiedCount() const;
    const SvxBoxEntry&  GetModifiedEntry( USHORT nPos ) const;

    USHORT              GetRemovedCount() const;
    const SvxBoxEntry&  GetRemovedEntry( USHORT nPos ) const;

    USHORT              GetNewCount() const;
    const SvxBoxEntry&  GetNewEntry( USHORT nPos ) const;

    USHORT              GetStyle() const             { return nStyle; }
    void                SetStyle( const USHORT nSt ) { nStyle = nSt; }

    String              GetText() const;

private:
    SvxEntryLst         aEntryLst;
    SvxEntryLst         aDelEntryLst;
    SvxBoxEntry         aDefault;
    USHORT              nStyle;

    virtual void        KeyInput( const KeyEvent& rKEvt );

    void                InitComboBox();
    void                InsertSorted( SvxBoxEntry* pEntry );
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.2.466); FILE MERGED 2008/04/01 15:49:39 thb 1.2.466.2: #i85898# Stripping all external header guards 2008/03/31 14:18:19 rt 1.2.466.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: svxbox.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 _SVX_BOX_HXX
#define _SVX_BOX_HXX

// include ---------------------------------------------------------------

#include <svtools/svarray.hxx>
#include <tools/string.hxx>

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _COMBOBOX_HXX //autogen
#include <vcl/combobox.hxx>
#endif

// forward ---------------------------------------------------------------

class SvxBoxEntry;
class SvxListBase;

//#if 0 // _SOLAR__PRIVATE
SV_DECL_PTRARR( SvxEntryLst, SvxBoxEntry*, 10, 10 )
//#else
//typedef SvPtrarr SvxEntryLst;
//#endif

// class SvxBoxEntry -----------------------------------------------------

class SvxBoxEntry
{
    friend class SvxListBox;
    friend class SvxComboBox;

public:
    SvxBoxEntry( const String& aName, USHORT nId=0 );
    SvxBoxEntry( const SvxBoxEntry& rOrg );
    SvxBoxEntry();

    String              aName;
    USHORT              nId;

private:
    BOOL                bModified;
    BOOL                bNew;
};

// class SvxListBox ------------------------------------------------------

class SvxListBox : public ListBox
{
    using ListBox::InsertEntry;
    using ListBox::RemoveEntry;
    using ListBox::GetEntryPos;
    using ListBox::IsEntrySelected;
    using ListBox::SelectEntry;

public:
    SvxListBox( Window* pParent, WinBits nBits = WB_BORDER );
    SvxListBox( Window* pParent, const ResId& rId );
    ~SvxListBox();

    void                InsertNewEntry( const SvxBoxEntry& rEntry );
    void                InsertEntry( const SvxBoxEntry& rEntry,
                                     USHORT nId = LISTBOX_ENTRY_NOTFOUND );

    void                RemoveEntry( USHORT nPos );
    void                RemoveEntry( const SvxBoxEntry& rEntry );

    void                Clear();

    USHORT              GetEntryPos( const SvxBoxEntry& rEntry ) const;
    const SvxBoxEntry&  GetSvxBoxEntry( USHORT nIdx ) const;

    inline BOOL         IsEntrySelected( const SvxBoxEntry& rEntry ) const;
    const SvxBoxEntry&  GetSelectSvxBoxEntry( USHORT nIdx = 0 ) const;
    inline void         SelectEntry( const SvxBoxEntry& rEntry,
                                     BOOL bSelect = TRUE );

    void                ModifyEntry( USHORT nPos, const String& aName );
    USHORT              GetModifiedCount() const;
    const SvxBoxEntry&  GetModifiedEntry( USHORT nPos ) const;

    USHORT              GetRemovedCount() const;
    const SvxBoxEntry&  GetRemovedEntry( USHORT nPos ) const;

    USHORT              GetNewCount() const;
    const SvxBoxEntry&  GetNewEntry( USHORT nPos ) const;

private:
    SvxEntryLst         aEntryLst;
    SvxEntryLst         aDelEntryLst;
    SvxBoxEntry         aDefault;

    void                InitListBox();
    void                InsertSorted( SvxBoxEntry* pEntry );
};

// inlines ---------------------------------------------------------------

inline BOOL SvxListBox::IsEntrySelected( const SvxBoxEntry& aEntry ) const
    { return ListBox::IsEntrySelected( aEntry.aName ); }

inline void SvxListBox::SelectEntry( const SvxBoxEntry& aEntry, BOOL bSelect )
    { ListBox::SelectEntry( aEntry.aName, bSelect ); }

// enum SvxComboBoxStyle -------------------------------------------------

enum SvxComboBoxStyle
{
    SVX_CBS_UPPER       = 0x01,
    SVX_CBS_LOWER       = 0x02,
    SVX_CBS_ALL         = 0x04,
    SVX_CBS_FILENAME    = 0x08,
#ifdef WIN
    SVX_CBS_SW_FILENAME = SVX_CBS_FILENAME | SVX_CBS_LOWER
#else
    SVX_CBS_SW_FILENAME = SVX_CBS_FILENAME
#endif
};

// class SvxComboBox -----------------------------------------------------

class SvxComboBox : public ComboBox
{
    using ComboBox::InsertEntry;
    using ComboBox::RemoveEntry;
    using ComboBox::GetEntryPos;
    using Window::SetStyle;

public:
    SvxComboBox( Window* pParent,
                 WinBits nBits = WB_BORDER, USHORT nStyleBits = SVX_CBS_ALL );
    SvxComboBox( Window* pParent, const ResId& rId, USHORT nStyleBits = SVX_CBS_ALL );
    ~SvxComboBox();

    void                InsertNewEntry( const SvxBoxEntry& );
    void                InsertEntry( const SvxBoxEntry& );

    void                RemoveEntry( USHORT nPos );
    void                RemoveEntry( const SvxBoxEntry& rEntry );

    void                Clear();

    USHORT              GetEntryPos( const SvxBoxEntry& rEntry ) const;
    const SvxBoxEntry&  GetEntry( USHORT nIdx ) const;

    void                ModifyEntry( USHORT nPos, const String& aName );
    USHORT              GetModifiedCount() const;
    const SvxBoxEntry&  GetModifiedEntry( USHORT nPos ) const;

    USHORT              GetRemovedCount() const;
    const SvxBoxEntry&  GetRemovedEntry( USHORT nPos ) const;

    USHORT              GetNewCount() const;
    const SvxBoxEntry&  GetNewEntry( USHORT nPos ) const;

    USHORT              GetStyle() const             { return nStyle; }
    void                SetStyle( const USHORT nSt ) { nStyle = nSt; }

    String              GetText() const;

private:
    SvxEntryLst         aEntryLst;
    SvxEntryLst         aDelEntryLst;
    SvxBoxEntry         aDefault;
    USHORT              nStyle;

    virtual void        KeyInput( const KeyEvent& rKEvt );

    void                InitComboBox();
    void                InsertSorted( SvxBoxEntry* pEntry );
};

#endif

<|endoftext|>


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

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

namespace com { namespace sun { namespace star {
    namespace uno {
        class Any;
    }
}}};

class String;
class SvStrings;

namespace SWUnoHelper {

// calls over the compherl the getEnumAsInt32 function and handle the
// exceptions.
sal_Int32 GetEnumAsInt32( const com::sun::star::uno::Any& rVal );

// methods for UCB actions:
    // delete the file under this URL
BOOL UCB_DeleteFile( const String& rURL );

    // copy/move the file to a new location
BOOL UCB_CopyFile( const String& rURL, const String& rNewURL,
                    BOOL bCopyIsMove = FALSE );

    // is the URL on the current system case sentive?
BOOL UCB_IsCaseSensitiveFileName( const String& rURL );

    // is the URL readonly?
BOOL UCB_IsReadOnlyFileName( const String& rURL );

    // get a list of files from the folder of the URL
    // options: pExtension = 0 -> all, else this specific extension
    //          pDateTime != 0 -> returns also the modified date/time of
    //                       the files in a SvPtrarr -->
    //                       !! objects must be deleted from the caller!!
BOOL UCB_GetFileListOfFolder( const String& rURL, SvStrings& rList,
                                const String* pExtension = 0,
                                SvPtrarr* pDateTimeList = 0 );

    // is the URL an existing file?
BOOL UCB_IsFile( const String& rURL );

    // is the URL a existing directory?
BOOL UCB_IsDirectory( const String& rURL );
}

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

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

namespace com { namespace sun { namespace star {
    namespace uno {
        class Any;
    }
}}};

class String;
class SvStrings;

namespace SWUnoHelper {

// calls over the compherl the getEnumAsInt32 function and handle the
// exceptions.
sal_Int32 GetEnumAsInt32( const com::sun::star::uno::Any& rVal );

// methods for UCB actions:
    // delete the file under this URL
BOOL UCB_DeleteFile( const String& rURL );

    // copy/move the file to a new location
BOOL UCB_CopyFile( const String& rURL, const String& rNewURL,
                    BOOL bCopyIsMove = FALSE );

    // is the URL on the current system case sentive?
BOOL UCB_IsCaseSensitiveFileName( const String& rURL );

    // is the URL readonly?
BOOL UCB_IsReadOnlyFileName( const String& rURL );

    // get a list of files from the folder of the URL
    // options: pExtension = 0 -> all, else this specific extension
    //          pDateTime != 0 -> returns also the modified date/time of
    //                       the files in a SvPtrarr -->
    //                       !! objects must be deleted from the caller!!
BOOL UCB_GetFileListOfFolder( const String& rURL, SvStrings& rList,
                                const String* pExtension = 0,
                                SvPtrarr* pDateTimeList = 0 );

    // is the URL a existing directory?
BOOL UCB_IsDirectory( const String& rURL );
}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: swunohelper.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 02:18:11 $
 *
 *  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 _SWUNOHELPER_HXX
#define _SWUNOHELPER_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif

namespace com { namespace sun { namespace star {
    namespace uno {
        class Any;
    }
}}};

class String;
class SvStrings;
class SvPtrarr;

namespace SWUnoHelper {

// calls over the compherl the getEnumAsInt32 function and handle the
// exceptions.
sal_Int32 GetEnumAsInt32( const com::sun::star::uno::Any& rVal );

// methods for UCB actions:
    // delete the file under this URL
SW_DLLPUBLIC BOOL UCB_DeleteFile( const String& rURL );

    // copy/move the file to a new location
BOOL UCB_CopyFile( const String& rURL, const String& rNewURL,
                    BOOL bCopyIsMove = FALSE );

    // is the URL on the current system case sentive?
SW_DLLPUBLIC BOOL UCB_IsCaseSensitiveFileName( const String& rURL );

    // is the URL readonly?
SW_DLLPUBLIC BOOL UCB_IsReadOnlyFileName( const String& rURL );

    // get a list of files from the folder of the URL
    // options: pExtension = 0 -> all, else this specific extension
    //          pDateTime != 0 -> returns also the modified date/time of
    //                       the files in a SvPtrarr -->
    //                       !! objects must be deleted from the caller!!
BOOL UCB_GetFileListOfFolder( const String& rURL, SvStrings& rList,
                                const String* pExtension = 0,
                                SvPtrarr* pDateTimeList = 0 );

    // is the URL an existing file?
BOOL UCB_IsFile( const String& rURL );

    // is the URL a existing directory?
BOOL UCB_IsDirectory( const String& rURL );
}

#endif
<commit_msg>INTEGRATION: CWS swwarnings (1.8.710); FILE MERGED 2007/03/05 12:43:18 tl 1.8.710.2: #i69287# warning-free code 2007/02/27 13:06:37 tl 1.8.710.1: #i69287# warning-free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: swunohelper.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 08:12:51 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SWUNOHELPER_HXX
#define _SWUNOHELPER_HXX

#include <tools/solar.h>
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif

namespace com { namespace sun { namespace star {
    namespace uno {
        class Any;
    }
}}}

class String;
class SvStrings;
class SvPtrarr;

namespace SWUnoHelper {

// calls over the compherl the getEnumAsInt32 function and handle the
// exceptions.
sal_Int32 GetEnumAsInt32( const com::sun::star::uno::Any& rVal );

// methods for UCB actions:
    // delete the file under this URL
SW_DLLPUBLIC BOOL UCB_DeleteFile( const String& rURL );

    // copy/move the file to a new location
BOOL UCB_CopyFile( const String& rURL, const String& rNewURL,
                    BOOL bCopyIsMove = FALSE );

    // is the URL on the current system case sentive?
SW_DLLPUBLIC BOOL UCB_IsCaseSensitiveFileName( const String& rURL );

    // is the URL readonly?
SW_DLLPUBLIC BOOL UCB_IsReadOnlyFileName( const String& rURL );

    // get a list of files from the folder of the URL
    // options: pExtension = 0 -> all, else this specific extension
    //          pDateTime != 0 -> returns also the modified date/time of
    //                       the files in a SvPtrarr -->
    //                       !! objects must be deleted from the caller!!
BOOL UCB_GetFileListOfFolder( const String& rURL, SvStrings& rList,
                                const String* pExtension = 0,
                                SvPtrarr* pDateTimeList = 0 );

    // is the URL an existing file?
BOOL UCB_IsFile( const String& rURL );

    // is the URL a existing directory?
BOOL UCB_IsDirectory( const String& rURL );
}

#endif
<|endoftext|>


<commit_before>/* Copyright 2012-2013 Hallowyn and others.
See the NOTICE file distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file to you under
the Apache License, Version 2.0 (the "License"); you may not use this
file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
License for the specific language governing permissions and limitations
under the License.
*/

#include "pfhandler.h"
#include <QtDebug>

PfHandler::PfHandler() : _errorLine(0), _errorColumn(0), _errorOccured(false) {
}

PfHandler::~PfHandler() {
}

bool PfHandler::startDocument(PfOptions options) {
  _options = options;
  return true;
}

bool PfHandler::startNode(QList<QString> names) {
  Q_UNUSED(names);
  return true;
}

bool PfHandler::text(QString text) {
  Q_UNUSED(text);
  return true;
}

bool PfHandler::binary(QIODevice *device, qint64 length, qint64 offset,
                       QString surface) {
  if (device->isSequential()) {
    setErrorString("PfHandler: binary fragment lazy loading cannot handle"
                   "sequential (= not seekable) data input");
    _errorOccured = true;
    return false;
  }
  qint64 pos = device->pos();
  if (!device->seek(offset)) {
    setErrorString(QString("PfHandler: cannot seek at %1 within data input")
                   .arg(offset));
    _errorOccured = true;
    return false;
  }
  // waiting for bytes being available seems useless since there are no
  // devices that are not sequential and on which bytes may not be immediately
  // available
  QByteArray data = device->read(length);
  if (data.size() != length) {
    setErrorString(QString("PfHandler: cannot read %1 bytes at %2 within data "
                           "input").arg(length).arg(offset));
    device->seek(pos);
    _errorOccured = true;
    return false;

  }
  device->seek(pos);
  return binary(data, surface);
}

bool PfHandler::binary(QByteArray data, QString surface) {
  Q_UNUSED(data);
  Q_UNUSED(surface);
  return true;
}

bool PfHandler::array(PfArray array) {
  Q_UNUSED(array);
  return true;
}

bool PfHandler::endNode(QList<QString> names) {
  Q_UNUSED(names);
  return true;
}

bool PfHandler::comment(QString content) {
  Q_UNUSED(content);
  return true;
}

bool PfHandler::endDocument() {
  return true;
}

void PfHandler::error(int line, int column) {
  _errorLine = line;
  _errorColumn = column;
  _errorOccured = true;
  qWarning() << "PfHandler::error line" << line << "column" << column << ":"
      << errorString();
}
<commit_msg>less qWarning()s<commit_after>/* Copyright 2012-2013 Hallowyn and others.
See the NOTICE file distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file to you under
the Apache License, Version 2.0 (the "License"); you may not use this
file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
License for the specific language governing permissions and limitations
under the License.
*/

#include "pfhandler.h"
#include <QtDebug>

PfHandler::PfHandler() : _errorLine(0), _errorColumn(0), _errorOccured(false) {
}

PfHandler::~PfHandler() {
}

bool PfHandler::startDocument(PfOptions options) {
  _options = options;
  return true;
}

bool PfHandler::startNode(QList<QString> names) {
  Q_UNUSED(names);
  return true;
}

bool PfHandler::text(QString text) {
  Q_UNUSED(text);
  return true;
}

bool PfHandler::binary(QIODevice *device, qint64 length, qint64 offset,
                       QString surface) {
  if (device->isSequential()) {
    setErrorString("PfHandler: binary fragment lazy loading cannot handle"
                   "sequential (= not seekable) data input");
    _errorOccured = true;
    return false;
  }
  qint64 pos = device->pos();
  if (!device->seek(offset)) {
    setErrorString(QString("PfHandler: cannot seek at %1 within data input")
                   .arg(offset));
    _errorOccured = true;
    return false;
  }
  // waiting for bytes being available seems useless since there are no
  // devices that are not sequential and on which bytes may not be immediately
  // available
  QByteArray data = device->read(length);
  if (data.size() != length) {
    setErrorString(QString("PfHandler: cannot read %1 bytes at %2 within data "
                           "input").arg(length).arg(offset));
    device->seek(pos);
    _errorOccured = true;
    return false;

  }
  device->seek(pos);
  return binary(data, surface);
}

bool PfHandler::binary(QByteArray data, QString surface) {
  Q_UNUSED(data);
  Q_UNUSED(surface);
  return true;
}

bool PfHandler::array(PfArray array) {
  Q_UNUSED(array);
  return true;
}

bool PfHandler::endNode(QList<QString> names) {
  Q_UNUSED(names);
  return true;
}

bool PfHandler::comment(QString content) {
  Q_UNUSED(content);
  return true;
}

bool PfHandler::endDocument() {
  return true;
}

void PfHandler::error(int line, int column) {
  _errorLine = line;
  _errorColumn = column;
  _errorOccured = true;
  //qWarning() << "PfHandler::error line" << line << "column" << column << ":"
  //    << errorString();
}
<|endoftext|>