<commit_before><commit_msg>さっきのうそ<commit_after>#include <cstdio>
#include <vector>
#include <deque>
#include <string>
#include <algorithm>
#include <sstream>

/* definitions */
const int stone_size = 8;
const int field_size = 32;
const int empty_val = 257; // 障害物やzkの無いことを表す
const int filled_val = 256; // 障害物を表す
FILE* dumpout = stdout; // dump系関数の出力先

struct Position {
  /*座標を表現するクラス*/
  int y, x;
  bool operator==(const Position&obj) const {
    return y == obj.y && x == obj.x;
  }
  bool operator<(const Position&obj) const {
    if (y == obj.y) {
      return x < obj.x;
    }
    return y < obj.y;
  }
};

struct Stone {
  /* 石 */
  int raw[stone_size][stone_size]; // empty_val -> 空き, otherwise -> うまり
  std::deque<Position> fills; // 埋まってる座標を持っておく
};

struct Field {
  /* フィールド */
  int raw[field_size][field_size];
  std::deque<std::string> answer; // 答えとなる石の置き方を持っておく
};

int number_of_stones; // 与えられる石の数
Stone stones[256 * 8]; // 石を持っておくインスタンス（回転反転を考慮して8倍とってある）
Field initial_field; // 初期フィールド状態
std::deque<Position> initial_empties; // 初期フィールドで空いている場所を探す

int rotated(int deg) {
  /* 石をdeg度まわした石の番号のバイアスを返す */
  return number_of_stones * (deg/90);
}
int fliped() {
  /* 石を反転した時の石の番号のバイアスを返す */
  return number_of_stones * 4;
}
int operated(bool flip, int deg) {
  /* 石を操作した時の石の番号のバイアスを返す */
  if (flip) {
    if (deg == 0) {
      return fliped();
    }
    return fliped() + rotated(deg);
  }
  return rotated(deg);
}
int rotated(int n, int deg) {
  /* 石をdeg度まわした石の番号を返す */
  return n + rotated(deg);
}
int fliped(int n) {
  /* 石を反転した時の石の番号を返す */
  return n + fliped();
}
int operated(int n, bool flip, int deg) {
  /* 石を操作した時の石の番号のバイアスを返す */
  return n + operated(flip, deg);
}
int all_stones_num() {
  /* 全部で石が何個になるか */
  return 8*number_of_stones;
}

/* util */
std::string to_s(int n) {
  /* std::to_stringとかぶるけど、本番環境では必要になりそう*/
	std::stringstream ss;
	ss << n;
	return ss.str();
}
int get() {
  return getc(stdin) - '0';
}
void read_br() {
  /* CRLFを読み飛ばす */
  get();
  get();
};

/* dump */
void dump_stone(int n) {
  for (int i = 0; i < 8; ++i) {
    for (int j = 0; j < 8; ++j) {
      if (stones[n].raw[i][j] == empty_val) {
        /* 空き */
        putc('.', dumpout);
      } else {
        /* うまり */
        putc('@', dumpout);
      }
    }
    putc('\n', dumpout);
  }
}

void dump_field(Field& f, std::deque<Position>& ps) {
  for (int i = 0; i < field_size; ++i) {
    for (int j = 0; j < field_size; ++j) {
      if (std::find(ps.begin(), ps.end(), Position{i, j}) != ps.end()) {
        /* 次の候補 */
        putc('_', dumpout);
      } else if (f.raw[i][j] == empty_val) {
        /* あき */
        putc('.', dumpout);
      } else if (f.raw[i][j] == filled_val) {
        /* 障害物 */
        putc('#', dumpout);
      } else {
        /* 石 */
        putc('@', dumpout);
      }
    }
    putc('\n', dumpout);
  }
}
void dump_field(Field& f) {
  for (int i = 0; i < field_size; ++i) {
    for (int j = 0; j < field_size; ++j) {
      if (f.raw[i][j] == empty_val) {
        /* あき */
        putc('.', dumpout);
      } else if (f.raw[i][j] == filled_val) {
        /* 障害物 */
        putc('#', dumpout);
      } else {
        /* 石 */
        putc('@', dumpout);
      }
    }
    putc('\n', dumpout);
  }
}

/* stone manipurates */
void init_stone(int n) {
  /* 石を初期化しておく */
  for (int i = 0; i < 8; ++i) {
    for (int j = 0; j < 8; ++j) {
      stones[n].raw[i][j] = empty_val;
    }
  }
}
void rotate_stone(int n, int deg) {
  /* 石を回す。deg = 90でよばれて、内部で180, 270をよぶ */
  init_stone(rotated(n, deg));
  for (int i = 0; i < stones[n].fills.size(); ++i) {
    int newy = stones[n].fills[i].x;
    int newx = 7 - stones[n].fills[i].y;
    stones[rotated(n, deg)].fills.push_back(Position{newy, newx});
    stones[rotated(n, deg)].raw[newy][newx] = stones[n].raw[stones[n].fills[i].y][stones[n].fills[i].x];
  }

  if (deg != 270) {
    rotate_stone(n, deg+90);
  }
}

void flip_stone(int n) {
  /* 石を反転させる */
  init_stone(fliped(n));
  for (int i = 0; i < stones[n].fills.size(); ++i) {
    int newy = stones[n].fills[i].y;
    int newx = 7 - stones[n].fills[i].x;
    stones[fliped(n)].fills.push_back(Position{newy, newx});
    stones[fliped(n)].raw[newy][newx] = stones[n].raw[stones[n].fills[i].y][stones[n].fills[i].x];
  }
}

/* parsing */
void get_field() {
  /* 初期フィールドを得る */
  for (int i = 0; i < field_size; ++i) {
    for (int j = 0; j < field_size; ++j) {
      if (get() == 0) {
        initial_field.raw[i][j] = empty_val;
        initial_empties.push_back(Position{i, j});
      } else {
        initial_field.raw[i][j] = filled_val;
      }
    }
    read_br();
  }
}

void get_stone(int index) {
  /* 石をひとつ読む */
  for (int i = 0; i < stone_size; ++i) {
    for (int j = 0; j < stone_size; ++j) {
      if (get() == 0) {
        stones[index].raw[i][j] = empty_val;
      } else {
        stones[index].raw[i][j] = index;
        stones[index].fills.push_back(Position{i, j});
      }
    }
    read_br();
  }
}
void get_stones() {
  /* 石をnumber_of_stones個よむ */
  for (int i = 0; i < number_of_stones; ++i) {
    get_stone(i);
    read_br();

    flip_stone(i);
    rotate_stone(i, 90);
    rotate_stone(fliped(i), 90);
  }
}
void get_input() {
  /* 入力を読む */
  get_field(); read_br();
  scanf("%d\n", &number_of_stones);
  get_stones();
}

/* helper */
void create_candidates(std::deque<Position>& next_candidates, int n, std::deque<Position>& empties) {
  /* 石の埋まっている場所とフィールド上の候補から、次に石を置く可能性のある場所に置く*/
  // next_candidates.resize(empties.size() * stones[n].fills.size());
  for (auto p1 : empties) {
    for (auto p2 : stones[n].fills) {
      next_candidates.push_back(Position{ p1.y - p2.y, p1.x - p2.x });
    }
  }
}

bool pos_check(int y, int x) {
  /* 与えられた座標が、fieldからはみ出ていたらfalseを返す */
  return (0 <= y && y < field_size) && (0 <= x < field_size);
}

std::string create_answer_format(int n, bool flip, int deg, Position p) {
  /* 石を置いた様子から回答フォーマットに沿った文字列を返す */
  return to_s(p.x) + " " + to_s(p.y) + " " + (flip ? "T" : "H") + " " + to_s(deg);
}

void print_anser(Field& f) {
  for (auto l : f.answer) {
    printf("%s\r\n", l.c_str());
  }
}

/* solver */
int put_stone(int m, bool flip, int deg, Position base, Field& f, std::deque<Position>& next_candidates) {
  /* 石を置く処理。ついでに次に石を置けそうな場所を探す */
  int score = 0;
  int n = operated(m, flip, deg);
  bool flag = false; // となりに石があるかフラグ。本来不要
  Field backup = f;
  for (auto p : stones[n].fills) { // zkごとにおけるかどうかを判定する
    int y = base.y + p.y;
    int x = base.x + p.x;
    if (!pos_check(y, x) || f.raw[y][x] != empty_val) { // 置きたい場所が空いてないと置けない
      next_candidates.clear();
      f = backup;
      return 0;
    }

    score += 1;
    f.raw[y][x] = m;

    /* 置いたところは候補から外す */
    auto exists = std::find(next_candidates.begin(), next_candidates.end(), Position{y, x});
    if (exists != next_candidates.end()) {
      next_candidates.erase(exists);
    }

    /* 隣接している空きマスを次の候補に */
    int dy[] = {-1, 0, 0, 1};
    int dx[] = {0, -1, 1, 0};
    for (int i = 0; i < 4; ++i) {
      if (!flag &&
          pos_check(y + dy[i], x + dx[i]) &&
          f.raw[y + dy[i]][x + dx[i]] > n) {
        flag = true;
      }
      if (pos_check(y + dy[i], x + dx[i]) &&
          f.raw[y + dy[i]][x + dx[i]] == empty_val) {
        Position newpos{y+dy[i], x+dx[i]};
        if (std::find(next_candidates.begin(), next_candidates.end(), newpos) == next_candidates.end()) {
          next_candidates.push_back(newpos);
        }
      }
    }
  }

  if (!flag) {
      next_candidates.clear();
      f = backup;
      return 0;
  }

  return score;
}
void dfs(int nowscore, int n, bool fliped, int deg, Position p, Field f, std::deque<Position> next_empties) {
  /* n番の石をfliped + degの状態で、f上のpに置くところから深く */
  if (n >= number_of_stones) {
    return;
  }

  int score;

  if ((score = put_stone(n, fliped, deg, p, f, next_empties)) > 0) {
    score += nowscore;
    fprintf(stderr, "score - %d\n", score);
    /* 石を置いた時の処理 */
    f.answer[n] = create_answer_format(n, fliped, deg, p);

    printf("score: %d\n", score);
    dump_field(f, next_empties);
    print_anser(f);
    fflush(dumpout);
  }

  /* 次の石を置く処理 */
  std::deque<Position> next_candidates;

  for (int j = 0; j <= 270; j += 90) { // 回転
    for (bool k = false; !k; k = true) { // 反転
      for (int i = n + 1; i < number_of_stones; ++i) {
        create_candidates(next_candidates, operated(i, k, j), next_empties); // 石を置く場所の候補を生成
        for (auto p : next_candidates) {
         dfs(score, i, k, j, p, f, next_empties);
        }
      }
    }
  }
}
void solve() {
  /* とりあえずこれを呼んでsolveする */
  std::deque<Position> first_candidates; // 最初の石を置く場所
  std::deque<Position> empty_positions;
  empty_positions.empty();

  for (int j = 0; j <= 270; j += 90) { // 回転
    for (bool k = false; !k; k = true) { // 反転
      for (int i = 0; i < number_of_stones; ++i) {
        create_candidates(first_candidates, operated(i, k, j), initial_empties); // 一個目の石を置く場所の候補を生成
        for (auto p : first_candidates) {
          dfs(0, i, k, j, p, initial_field, empty_positions);
        }
      }
    }
  }
}

/* main */
int main() {
  get_input();
  initial_field.answer.resize(number_of_stones);
  solve();
}
<|endoftext|>


<commit_before>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2008, Willow Garage, Inc.
*  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 Willow Garage 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.
*********************************************************************/

/* Author: Ryan Luna, Ioan Sucan */

#include "console_bridge/console.h"

#include <cstdio>
#include <cstdarg>

#include <iostream>
#include <mutex>

/// @cond IGNORE

struct DefaultOutputHandler
{
    DefaultOutputHandler(void)
    {
        output_handler_ = static_cast<console_bridge::OutputHandler*>(&std_output_handler_);
        previous_output_handler_ = output_handler_;
        logLevel_ = console_bridge::CONSOLE_BRIDGE_LOG_WARN;
    }

    console_bridge::OutputHandlerSTD std_output_handler_;
    console_bridge::OutputHandler   *output_handler_;
    console_bridge::OutputHandler   *previous_output_handler_;
    console_bridge::LogLevel         logLevel_;
    std::mutex                       lock_; // it is likely the outputhandler does some I/O, so we serialize it
};

// we use this function because we want to handle static initialization correctly
// however, the first run of this function is not thread safe, due to the use of a static
// variable inside the function. For this reason, we ensure the first call happens during
// static initialization using a proxy class
static DefaultOutputHandler* getDOH(void)
{
    static DefaultOutputHandler DOH;
    return &DOH;
}

#define USE_DOH                                                                \
    DefaultOutputHandler *doh = getDOH();                                      \
    std::lock_guard<std::mutex> lock_guard(doh->lock_)

#define MAX_BUFFER_SIZE 1024

/// @endcond

void console_bridge::noOutputHandler(void)
{
    USE_DOH;
    doh->previous_output_handler_ = doh->output_handler_;
    doh->output_handler_ = NULL;
}

void console_bridge::restorePreviousOutputHandler(void)
{
    USE_DOH;
    std::swap(doh->previous_output_handler_, doh->output_handler_);
}

void console_bridge::useOutputHandler(OutputHandler *oh)
{
    USE_DOH;
    doh->previous_output_handler_ = doh->output_handler_;
    doh->output_handler_ = oh;
}

console_bridge::OutputHandler* console_bridge::getOutputHandler(void)
{
    return getDOH()->output_handler_;
}

void console_bridge::log(const char *file, int line, LogLevel level, const char* m, ...)
{
    USE_DOH;
    if (doh->output_handler_ && level >= doh->logLevel_)
    {
        va_list __ap;
        va_start(__ap, m);
        char buf[MAX_BUFFER_SIZE];
        vsnprintf(buf, sizeof(buf), m, __ap);
        va_end(__ap);
        buf[MAX_BUFFER_SIZE - 1] = '\0';

        doh->output_handler_->log(buf, level, file, line);
    }
}

void console_bridge::setLogLevel(LogLevel level)
{
    USE_DOH;
    doh->logLevel_ = level;
}

console_bridge::LogLevel console_bridge::getLogLevel(void)
{
    USE_DOH;
    return doh->logLevel_;
}

static const char* LogLevelString[4] = {"Debug:   ", "Info:    ", "Warning: ", "Error:   "};

void console_bridge::OutputHandlerSTD::log(const std::string &text, LogLevel level, const char *filename, int line)
{
    if (level >= CONSOLE_BRIDGE_LOG_WARN)
    {
        std::cerr << LogLevelString[level] << text << std::endl;
        std::cerr << "         at line " << line << " in " << filename << std::endl;
        std::cerr.flush();
    }
    else
    {
        std::cout << LogLevelString[level] << text << std::endl;
        std::cout.flush();
    }
}

console_bridge::OutputHandlerFile::OutputHandlerFile(const char *filename) : OutputHandler()
{
    file_ = fopen(filename, "a");
    if (!file_)
        std::cerr << "Unable to open log file: '" << filename << "'" << std::endl;
}

console_bridge::OutputHandlerFile::~OutputHandlerFile(void)
{
    if (file_)
        if (fclose(file_) != 0)
            std::cerr << "Error closing logfile" << std::endl;
}

void console_bridge::OutputHandlerFile::log(const std::string &text, LogLevel level, const char *filename, int line)
{
    if (file_)
    {
        fprintf(file_, "%s%s\n", LogLevelString[level], text.c_str());
        if(level >= CONSOLE_BRIDGE_LOG_WARN)
            fprintf(file_, "         at line %d in %s\n", line, filename);
        fflush(file_);
    }
}
<commit_msg>Fix windows compiler warning<commit_after>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2008, Willow Garage, Inc.
*  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 Willow Garage 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.
*********************************************************************/

/* Author: Ryan Luna, Ioan Sucan */

#include "console_bridge/console.h"

#include <cstdio>
#include <cstdarg>

#include <iostream>
#include <mutex>

/// @cond IGNORE

struct DefaultOutputHandler
{
    DefaultOutputHandler(void)
    {
        output_handler_ = static_cast<console_bridge::OutputHandler*>(&std_output_handler_);
        previous_output_handler_ = output_handler_;
        logLevel_ = console_bridge::CONSOLE_BRIDGE_LOG_WARN;
    }

    console_bridge::OutputHandlerSTD std_output_handler_;
    console_bridge::OutputHandler   *output_handler_;
    console_bridge::OutputHandler   *previous_output_handler_;
    console_bridge::LogLevel         logLevel_;
    std::mutex                       lock_; // it is likely the outputhandler does some I/O, so we serialize it
};

// we use this function because we want to handle static initialization correctly
// however, the first run of this function is not thread safe, due to the use of a static
// variable inside the function. For this reason, we ensure the first call happens during
// static initialization using a proxy class
static DefaultOutputHandler* getDOH(void)
{
    static DefaultOutputHandler DOH;
    return &DOH;
}

#define USE_DOH                                                                \
    DefaultOutputHandler *doh = getDOH();                                      \
    std::lock_guard<std::mutex> lock_guard(doh->lock_)

#define MAX_BUFFER_SIZE 1024

/// @endcond

void console_bridge::noOutputHandler(void)
{
    USE_DOH;
    doh->previous_output_handler_ = doh->output_handler_;
    doh->output_handler_ = NULL;
}

void console_bridge::restorePreviousOutputHandler(void)
{
    USE_DOH;
    std::swap(doh->previous_output_handler_, doh->output_handler_);
}

void console_bridge::useOutputHandler(OutputHandler *oh)
{
    USE_DOH;
    doh->previous_output_handler_ = doh->output_handler_;
    doh->output_handler_ = oh;
}

console_bridge::OutputHandler* console_bridge::getOutputHandler(void)
{
    return getDOH()->output_handler_;
}

void console_bridge::log(const char *file, int line, LogLevel level, const char* m, ...)
{
    USE_DOH;
    if (doh->output_handler_ && level >= doh->logLevel_)
    {
        va_list __ap;
        va_start(__ap, m);
        char buf[MAX_BUFFER_SIZE];
        vsnprintf(buf, sizeof(buf), m, __ap);
        va_end(__ap);
        buf[MAX_BUFFER_SIZE - 1] = '\0';

        doh->output_handler_->log(buf, level, file, line);
    }
}

void console_bridge::setLogLevel(LogLevel level)
{
    USE_DOH;
    doh->logLevel_ = level;
}

console_bridge::LogLevel console_bridge::getLogLevel(void)
{
    USE_DOH;
    return doh->logLevel_;
}

static const char* LogLevelString[4] = {"Debug:   ", "Info:    ", "Warning: ", "Error:   "};

void console_bridge::OutputHandlerSTD::log(const std::string &text, LogLevel level, const char *filename, int line)
{
    if (level >= CONSOLE_BRIDGE_LOG_WARN)
    {
        std::cerr << LogLevelString[level] << text << std::endl;
        std::cerr << "         at line " << line << " in " << filename << std::endl;
        std::cerr.flush();
    }
    else
    {
        std::cout << LogLevelString[level] << text << std::endl;
        std::cout.flush();
    }
}

console_bridge::OutputHandlerFile::OutputHandlerFile(const char *filename) : OutputHandler()
{
#ifdef _MSC_VER
    errno_t err = fopen_s(&file_, filename, "a");
    if (err != 0 || !file_)
#else
    file_ = fopen(filename, "a");
    if (!file_)
#endif
        std::cerr << "Unable to open log file: '" << filename << "'" << std::endl;
}

console_bridge::OutputHandlerFile::~OutputHandlerFile(void)
{
    if (file_)
        if (fclose(file_) != 0)
            std::cerr << "Error closing logfile" << std::endl;
}

void console_bridge::OutputHandlerFile::log(const std::string &text, LogLevel level, const char *filename, int line)
{
    if (file_)
    {
        fprintf(file_, "%s%s\n", LogLevelString[level], text.c_str());
        if(level >= CONSOLE_BRIDGE_LOG_WARN)
            fprintf(file_, "         at line %d in %s\n", line, filename);
        fflush(file_);
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <mpd/client.h>
#include "consumer.hh"
#include "globals.hh"

using namespace boost::filesystem;
using namespace std;

#include <fstream>
Consumer::Consumer(string throwaway)
    : _playlist_file_(std::move(throwaway))
    , _write_to_file_(true) {

    std::ifstream file(_playlist_file_);

    if (file) {
        string temp;
        while (getline(file, temp)) {
            _playlist_lines_.insert(temp);
        }
    }
}

void Consumer::_sorted_insert_song_(const std::string& str) {
    bool inserted = _playlist_lines_.insert(str).second;
    if (NONO && inserted) {
        printf("Insert `%s` into playlist `%s`.\n", str.c_str(),
               _playlist_file_.c_str());
    }
}

Consumer::~Consumer() {
    if (_write_to_file_) {
        if (!NONO) {
            std::ofstream file(_playlist_file_);
            if (!file)
                throw std::runtime_error("Problem opening file " +
                                            _playlist_file_);
            for (const auto& s : _playlist_lines_) {
                file << s << '\n';
            }
            if (USE_MPD) {
                _run_mpd_();
            }
        } else if (USE_MPD) {
            printf("Will clear the mpd playlist, update the mpd "
                   "database, and load %s.\n",
                   path(_playlist_file_)
                       .filename()
                       .replace_extension()
                       .c_str());
        }
    }
}

#include <taglib/fileref.h>
void Consumer::_apply_tags_(const path& path, const string& artist,
                            const string& title) {
    using namespace TagLib;
    bool changed = false;

    FileRef file(path.c_str());
    Tag* tags = file.tag();

    if (!tags) {
        fprintf(stderr, "Music file `%s` has no tags!\n", path.c_str());
        return;
    }

    if (tags->artist() != artist) {
        if (NONO) {
            printf("  Artist: `%s` -> `%s`\n",
                   tags->artist().toCString(), artist.c_str());
        } else {
            changed = true;
            tags->setArtist(artist);
        }
    }

    if (tags->title() != title) {
        if (NONO) {
            printf("  Title: `%s` -> `%s`\n",
                   tags->title().toCString(), title.c_str());
        } else {
            changed = true;
            tags->setTitle(title);
        }
    }

    if (changed) {
        file.save();
    }
}
<commit_msg>In consumer.cc, remove double negative condition to test file validity.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <mpd/client.h>
#include "consumer.hh"
#include "globals.hh"

using namespace boost::filesystem;
using namespace std;

#include <fstream>
Consumer::Consumer(string throwaway)
    : _playlist_file_(std::move(throwaway))
    , _write_to_file_(true) {

    std::ifstream file(_playlist_file_);

    if (file) {
        string temp;
        while (getline(file, temp)) {
            _playlist_lines_.insert(temp);
        }
    }
}

void Consumer::_sorted_insert_song_(const std::string& str) {
    bool inserted = _playlist_lines_.insert(str).second;
    if (NONO && inserted) {
        printf("Insert `%s` into playlist `%s`.\n", str.c_str(),
               _playlist_file_.c_str());
    }
}

Consumer::~Consumer() {
    if (_write_to_file_) {
        if (!NONO) {
            std::ofstream file(_playlist_file_);
            if (file) {
                for (const auto& s : _playlist_lines_) {
                    file << s << '\n';
                }
                if (USE_MPD) {
                    _run_mpd_();
                }
            } else {
                throw std::runtime_error("Problem opening file " +
                                            _playlist_file_);
            }
        } else if (USE_MPD) {
            printf("Will clear the mpd playlist, update the mpd "
                   "database, and load %s.\n",
                   path(_playlist_file_)
                       .filename()
                       .replace_extension()
                       .c_str());
        }
    }
}

#include <taglib/fileref.h>
void Consumer::_apply_tags_(const path& path, const string& artist,
                            const string& title) {
    using namespace TagLib;
    bool changed = false;

    FileRef file(path.c_str());
    Tag* tags = file.tag();

    if (!tags) {
        fprintf(stderr, "Music file `%s` has no tags!\n", path.c_str());
        return;
    }

    if (tags->artist() != artist) {
        if (NONO) {
            printf("  Artist: `%s` -> `%s`\n",
                   tags->artist().toCString(), artist.c_str());
        } else {
            changed = true;
            tags->setArtist(artist);
        }
    }

    if (tags->title() != title) {
        if (NONO) {
            printf("  Title: `%s` -> `%s`\n",
                   tags->title().toCString(), title.c_str());
        } else {
            changed = true;
            tags->setTitle(title);
        }
    }

    if (changed) {
        file.save();
    }
}
<|endoftext|>


<commit_before>//===------- X86ExpandPseudo.cpp - Expand pseudo instructions -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a pass that expands pseudo instructions into target
// instructions to allow proper scheduling, if-conversion, other late
// optimizations, or simply the encoding of the instructions.
//
//===----------------------------------------------------------------------===//

#include "X86.h"
#include "X86FrameLowering.h"
#include "X86InstrBuilder.h"
#include "X86InstrInfo.h"
#include "X86MachineFunctionInfo.h"
#include "X86Subtarget.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved.
#include "llvm/IR/GlobalValue.h"
using namespace llvm;

#define DEBUG_TYPE "x86-pseudo"

namespace {
class X86ExpandPseudo : public MachineFunctionPass {
public:
  static char ID;
  X86ExpandPseudo() : MachineFunctionPass(ID) {}

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
    AU.addPreservedID(MachineLoopInfoID);
    AU.addPreservedID(MachineDominatorsID);
    MachineFunctionPass::getAnalysisUsage(AU);
  }

  const X86Subtarget *STI;
  const X86InstrInfo *TII;
  const X86RegisterInfo *TRI;
  const X86FrameLowering *X86FL;

  bool runOnMachineFunction(MachineFunction &Fn) override;

  const char *getPassName() const override {
    return "X86 pseudo instruction expansion pass";
  }

private:
  bool ExpandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
  bool ExpandMBB(MachineBasicBlock &MBB);
};
char X86ExpandPseudo::ID = 0;
} // End anonymous namespace.

/// If \p MBBI is a pseudo instruction, this method expands
/// it to the corresponding (sequence of) actual instruction(s).
/// \returns true if \p MBBI has been expanded.
bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator MBBI) {
  MachineInstr &MI = *MBBI;
  unsigned Opcode = MI.getOpcode();
  DebugLoc DL = MBBI->getDebugLoc();
  switch (Opcode) {
  default:
    return false;
  case X86::TCRETURNdi:
  case X86::TCRETURNri:
  case X86::TCRETURNmi:
  case X86::TCRETURNdi64:
  case X86::TCRETURNri64:
  case X86::TCRETURNmi64: {
    bool isMem = Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64;
    MachineOperand &JumpTarget = MBBI->getOperand(0);
    MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1);
    assert(StackAdjust.isImm() && "Expecting immediate value.");

    // Adjust stack pointer.
    int StackAdj = StackAdjust.getImm();

    if (StackAdj) {
      // Check for possible merge with preceding ADD instruction.
      StackAdj += X86FL->mergeSPUpdates(MBB, MBBI, true);
      X86FL->emitSPUpdate(MBB, MBBI, StackAdj, /*InEpilogue=*/true);
    }

    // Jump to label or value in register.
    bool IsWin64 = STI->isTargetWin64();
    if (Opcode == X86::TCRETURNdi || Opcode == X86::TCRETURNdi64) {
      unsigned Op = (Opcode == X86::TCRETURNdi)
                        ? X86::TAILJMPd
                        : (IsWin64 ? X86::TAILJMPd64_REX : X86::TAILJMPd64);
      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op));
      if (JumpTarget.isGlobal())
        MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
                             JumpTarget.getTargetFlags());
      else {
        assert(JumpTarget.isSymbol());
        MIB.addExternalSymbol(JumpTarget.getSymbolName(),
                              JumpTarget.getTargetFlags());
      }
    } else if (Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64) {
      unsigned Op = (Opcode == X86::TCRETURNmi)
                        ? X86::TAILJMPm
                        : (IsWin64 ? X86::TAILJMPm64_REX : X86::TAILJMPm64);
      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op));
      for (unsigned i = 0; i != 5; ++i)
        MIB.addOperand(MBBI->getOperand(i));
    } else if (Opcode == X86::TCRETURNri64) {
      BuildMI(MBB, MBBI, DL,
              TII->get(IsWin64 ? X86::TAILJMPr64_REX : X86::TAILJMPr64))
          .addReg(JumpTarget.getReg(), RegState::Kill);
    } else {
      BuildMI(MBB, MBBI, DL, TII->get(X86::TAILJMPr))
          .addReg(JumpTarget.getReg(), RegState::Kill);
    }

    MachineInstr *NewMI = std::prev(MBBI);
    NewMI->copyImplicitOps(*MBBI->getParent()->getParent(), MBBI);

    // Delete the pseudo instruction TCRETURN.
    MBB.erase(MBBI);

    return true;
  }
  case X86::EH_RETURN:
  case X86::EH_RETURN64: {
    MachineOperand &DestAddr = MBBI->getOperand(0);
    assert(DestAddr.isReg() && "Offset should be in register!");
    const bool Uses64BitFramePtr =
        STI->isTarget64BitLP64() || STI->isTargetNaCl64();
    unsigned StackPtr = TRI->getStackRegister();
    BuildMI(MBB, MBBI, DL,
            TII->get(Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr), StackPtr)
        .addReg(DestAddr.getReg());
    // The EH_RETURN pseudo is really removed during the MC Lowering.
    return true;
  }
  case X86::IRET: {
    // Adjust stack to erase error code
    int64_t StackAdj = MBBI->getOperand(0).getImm();
    X86FL->emitSPUpdate(MBB, MBBI, StackAdj, true);
    // Replace pseudo with machine iret
    BuildMI(MBB, MBBI, DL,
            TII->get(STI->is64Bit() ? X86::IRET64 : X86::IRET32));
    MBB.erase(MBBI);
    return true;
  }
  case X86::EH_RESTORE: {
    // Restore ESP and EBP, and optionally ESI if required.
    bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality(
        MBB.getParent()->getFunction()->getPersonalityFn()));
    X86FL->restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/IsSEH);
    MBBI->eraseFromParent();
    return true;
  }
  }
  llvm_unreachable("Previous switch has a fallthrough?");
}

/// Expand all pseudo instructions contained in \p MBB.
/// \returns true if any expansion occurred for \p MBB.
bool X86ExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
  bool Modified = false;

  // MBBI may be invalidated by the expansion.
  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
  while (MBBI != E) {
    MachineBasicBlock::iterator NMBBI = std::next(MBBI);
    Modified |= ExpandMI(MBB, MBBI);
    MBBI = NMBBI;
  }

  return Modified;
}

bool X86ExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
  STI = &static_cast<const X86Subtarget &>(MF.getSubtarget());
  TII = STI->getInstrInfo();
  TRI = STI->getRegisterInfo();
  X86FL = STI->getFrameLowering();

  bool Modified = false;
  for (MachineBasicBlock &MBB : MF)
    Modified |= ExpandMBB(MBB);
  return Modified;
}

/// Returns an instance of the pseudo instruction expansion pass.
FunctionPass *llvm::createX86ExpandPseudoPass() {
  return new X86ExpandPseudo();
}
<commit_msg>Fix line endings after r256155. NFC.<commit_after>//===------- X86ExpandPseudo.cpp - Expand pseudo instructions -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a pass that expands pseudo instructions into target
// instructions to allow proper scheduling, if-conversion, other late
// optimizations, or simply the encoding of the instructions.
//
//===----------------------------------------------------------------------===//

#include "X86.h"
#include "X86FrameLowering.h"
#include "X86InstrBuilder.h"
#include "X86InstrInfo.h"
#include "X86MachineFunctionInfo.h"
#include "X86Subtarget.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved.
#include "llvm/IR/GlobalValue.h"
using namespace llvm;

#define DEBUG_TYPE "x86-pseudo"

namespace {
class X86ExpandPseudo : public MachineFunctionPass {
public:
  static char ID;
  X86ExpandPseudo() : MachineFunctionPass(ID) {}

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
    AU.addPreservedID(MachineLoopInfoID);
    AU.addPreservedID(MachineDominatorsID);
    MachineFunctionPass::getAnalysisUsage(AU);
  }

  const X86Subtarget *STI;
  const X86InstrInfo *TII;
  const X86RegisterInfo *TRI;
  const X86FrameLowering *X86FL;

  bool runOnMachineFunction(MachineFunction &Fn) override;

  const char *getPassName() const override {
    return "X86 pseudo instruction expansion pass";
  }

private:
  bool ExpandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
  bool ExpandMBB(MachineBasicBlock &MBB);
};
char X86ExpandPseudo::ID = 0;
} // End anonymous namespace.

/// If \p MBBI is a pseudo instruction, this method expands
/// it to the corresponding (sequence of) actual instruction(s).
/// \returns true if \p MBBI has been expanded.
bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator MBBI) {
  MachineInstr &MI = *MBBI;
  unsigned Opcode = MI.getOpcode();
  DebugLoc DL = MBBI->getDebugLoc();
  switch (Opcode) {
  default:
    return false;
  case X86::TCRETURNdi:
  case X86::TCRETURNri:
  case X86::TCRETURNmi:
  case X86::TCRETURNdi64:
  case X86::TCRETURNri64:
  case X86::TCRETURNmi64: {
    bool isMem = Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64;
    MachineOperand &JumpTarget = MBBI->getOperand(0);
    MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1);
    assert(StackAdjust.isImm() && "Expecting immediate value.");

    // Adjust stack pointer.
    int StackAdj = StackAdjust.getImm();

    if (StackAdj) {
      // Check for possible merge with preceding ADD instruction.
      StackAdj += X86FL->mergeSPUpdates(MBB, MBBI, true);
      X86FL->emitSPUpdate(MBB, MBBI, StackAdj, /*InEpilogue=*/true);
    }

    // Jump to label or value in register.
    bool IsWin64 = STI->isTargetWin64();
    if (Opcode == X86::TCRETURNdi || Opcode == X86::TCRETURNdi64) {
      unsigned Op = (Opcode == X86::TCRETURNdi)
                        ? X86::TAILJMPd
                        : (IsWin64 ? X86::TAILJMPd64_REX : X86::TAILJMPd64);
      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op));
      if (JumpTarget.isGlobal())
        MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
                             JumpTarget.getTargetFlags());
      else {
        assert(JumpTarget.isSymbol());
        MIB.addExternalSymbol(JumpTarget.getSymbolName(),
                              JumpTarget.getTargetFlags());
      }
    } else if (Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64) {
      unsigned Op = (Opcode == X86::TCRETURNmi)
                        ? X86::TAILJMPm
                        : (IsWin64 ? X86::TAILJMPm64_REX : X86::TAILJMPm64);
      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op));
      for (unsigned i = 0; i != 5; ++i)
        MIB.addOperand(MBBI->getOperand(i));
    } else if (Opcode == X86::TCRETURNri64) {
      BuildMI(MBB, MBBI, DL,
              TII->get(IsWin64 ? X86::TAILJMPr64_REX : X86::TAILJMPr64))
          .addReg(JumpTarget.getReg(), RegState::Kill);
    } else {
      BuildMI(MBB, MBBI, DL, TII->get(X86::TAILJMPr))
          .addReg(JumpTarget.getReg(), RegState::Kill);
    }

    MachineInstr *NewMI = std::prev(MBBI);
    NewMI->copyImplicitOps(*MBBI->getParent()->getParent(), MBBI);

    // Delete the pseudo instruction TCRETURN.
    MBB.erase(MBBI);

    return true;
  }
  case X86::EH_RETURN:
  case X86::EH_RETURN64: {
    MachineOperand &DestAddr = MBBI->getOperand(0);
    assert(DestAddr.isReg() && "Offset should be in register!");
    const bool Uses64BitFramePtr =
        STI->isTarget64BitLP64() || STI->isTargetNaCl64();
    unsigned StackPtr = TRI->getStackRegister();
    BuildMI(MBB, MBBI, DL,
            TII->get(Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr), StackPtr)
        .addReg(DestAddr.getReg());
    // The EH_RETURN pseudo is really removed during the MC Lowering.
    return true;
  }
  case X86::IRET: {
    // Adjust stack to erase error code
    int64_t StackAdj = MBBI->getOperand(0).getImm();
    X86FL->emitSPUpdate(MBB, MBBI, StackAdj, true);
    // Replace pseudo with machine iret
    BuildMI(MBB, MBBI, DL,
            TII->get(STI->is64Bit() ? X86::IRET64 : X86::IRET32));
    MBB.erase(MBBI);
    return true;
  }
  case X86::EH_RESTORE: {
    // Restore ESP and EBP, and optionally ESI if required.
    bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality(
        MBB.getParent()->getFunction()->getPersonalityFn()));
    X86FL->restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/IsSEH);
    MBBI->eraseFromParent();
    return true;
  }
  }
  llvm_unreachable("Previous switch has a fallthrough?");
}

/// Expand all pseudo instructions contained in \p MBB.
/// \returns true if any expansion occurred for \p MBB.
bool X86ExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
  bool Modified = false;

  // MBBI may be invalidated by the expansion.
  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
  while (MBBI != E) {
    MachineBasicBlock::iterator NMBBI = std::next(MBBI);
    Modified |= ExpandMI(MBB, MBBI);
    MBBI = NMBBI;
  }

  return Modified;
}

bool X86ExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
  STI = &static_cast<const X86Subtarget &>(MF.getSubtarget());
  TII = STI->getInstrInfo();
  TRI = STI->getRegisterInfo();
  X86FL = STI->getFrameLowering();

  bool Modified = false;
  for (MachineBasicBlock &MBB : MF)
    Modified |= ExpandMBB(MBB);
  return Modified;
}

/// Returns an instance of the pseudo instruction expansion pass.
FunctionPass *llvm::createX86ExpandPseudoPass() {
  return new X86ExpandPseudo();
}
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  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
//
//  Current versions can be found at www.libavg.de
//

#include "VertexArray.h"

#include "../base/Exception.h"
#include "../base/WideLine.h"
#include "../base/ObjectCounter.h"

#include <iostream>
#include <stddef.h>
#include <string.h>

using namespace std;
using namespace boost;

namespace avg {

thread_specific_ptr<vector<unsigned int> > VertexArray::s_pGLVertexBufferIDs;
thread_specific_ptr<vector<unsigned int> > VertexArray::s_pGLIndexBufferIDs;

VertexArray::VertexArray(int reserveVerts, int reserveIndexes)
    : m_NumVerts(0),
      m_NumIndexes(0),
      m_ReserveVerts(reserveVerts),
      m_ReserveIndexes(reserveIndexes),
      m_bDataChanged(true)
{
    ObjectCounter::get()->incRef(&typeid(*this));
    if (m_ReserveVerts < 10) {
        m_ReserveVerts = 10;
    }
    if (m_ReserveIndexes < 20) {
        m_ReserveIndexes = 20;
    }
    m_pVertexData = new T2V3C4Vertex[m_ReserveVerts];
    m_pIndexData = new unsigned int[m_ReserveIndexes];

    initBufferCache();
    if (s_pGLVertexBufferIDs->empty() || m_ReserveVerts != 10 ||
            m_ReserveIndexes != 20)
    {
        glproc::GenBuffers(1, &m_GLVertexBufferID);
        glproc::GenBuffers(1, &m_GLIndexBufferID);
    } else {
        m_GLVertexBufferID = s_pGLVertexBufferIDs->back();
        s_pGLVertexBufferIDs->pop_back();
        m_GLIndexBufferID = s_pGLIndexBufferIDs->back();
        s_pGLIndexBufferIDs->pop_back();
    }
}

VertexArray::~VertexArray()
{
    if (m_ReserveVerts == 10) {
        s_pGLVertexBufferIDs->push_back(m_GLVertexBufferID);
    } else {
        glproc::DeleteBuffers(1, &m_GLVertexBufferID);
    }
    if (m_ReserveIndexes == 20) {
        s_pGLIndexBufferIDs->push_back(m_GLIndexBufferID);
    } else {
        glproc::DeleteBuffers(1, &m_GLIndexBufferID);
    }
    delete[] m_pVertexData;
    delete[] m_pIndexData;
    ObjectCounter::get()->decRef(&typeid(*this));
}

void VertexArray::appendPos(const DPoint& pos, const DPoint& texPos, const Pixel32& color)
{
    if (m_NumVerts >= m_ReserveVerts-1) {
        grow();
    }
    T2V3C4Vertex* pVertex = &(m_pVertexData[m_NumVerts]);
    pVertex->m_Pos[0] = (GLfloat)pos.x;
    pVertex->m_Pos[1] = (GLfloat)pos.y;
    pVertex->m_Pos[2] = 0.0;
    pVertex->m_Tex[0] = (GLfloat)texPos.x;
    pVertex->m_Tex[1] = (GLfloat)texPos.y;
    pVertex->m_Color = color;
    m_bDataChanged = true;
    m_NumVerts++;
}

void VertexArray::appendTriIndexes(int v0, int v1, int v2)
{
    if (m_NumIndexes >= m_ReserveIndexes-3) {
        grow();
    }
    m_pIndexData[m_NumIndexes] = v0;
    m_pIndexData[m_NumIndexes+1] = v1;
    m_pIndexData[m_NumIndexes+2] = v2;
    m_NumIndexes += 3;
}

void VertexArray::appendQuadIndexes(int v0, int v1, int v2, int v3)
{
    if (m_NumIndexes >= m_ReserveIndexes-6) {
        grow();
    }
    m_pIndexData[m_NumIndexes] = v0;
    m_pIndexData[m_NumIndexes+1] = v1;
    m_pIndexData[m_NumIndexes+2] = v2;
    m_pIndexData[m_NumIndexes+3] = v1;
    m_pIndexData[m_NumIndexes+4] = v2;
    m_pIndexData[m_NumIndexes+5] = v3;
    m_NumIndexes += 6;
}

void VertexArray::addLineData(Pixel32 color, const DPoint& p1, const DPoint& p2,
        double width, double tc1, double tc2)
{
    WideLine wl(p1, p2, width);
    int curVertex = getCurVert();
    appendPos(wl.pl0, DPoint(tc1, 1), color);
    appendPos(wl.pr0, DPoint(tc1, 0), color);
    appendPos(wl.pl1, DPoint(tc2, 1), color);
    appendPos(wl.pr1, DPoint(tc2, 0), color);
    appendQuadIndexes(curVertex+1, curVertex, curVertex+3, curVertex+2);
}

void VertexArray::reset()
{
    m_NumVerts = 0;
    m_NumIndexes = 0;
}

void VertexArray::update()
{
    if (m_bDataChanged) {
        glproc::BindBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID);
        glproc::BufferData(GL_ARRAY_BUFFER, m_ReserveVerts*sizeof(T2V3C4Vertex), 0,
                GL_DYNAMIC_DRAW);
        void * pBuffer = glproc::MapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
        memcpy(pBuffer, m_pVertexData, m_NumVerts*sizeof(T2V3C4Vertex));
        glproc::UnmapBuffer(GL_ARRAY_BUFFER);

        glproc::BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID);
        glproc::BufferData(GL_ELEMENT_ARRAY_BUFFER,
            m_ReserveIndexes*sizeof(unsigned int), 0, GL_DYNAMIC_DRAW);
        pBuffer = glproc::MapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
        memcpy(pBuffer, m_pIndexData, m_NumIndexes*sizeof(unsigned int));
        glproc::UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);

        OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "VertexArray::update");
    }
    m_bDataChanged = false;
}

void VertexArray::draw()
{
    update();
    glproc::BindBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID);
    glTexCoordPointer(2, GL_FLOAT, sizeof(T2V3C4Vertex), 0);
    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(T2V3C4Vertex),
            (void *)(offsetof(T2V3C4Vertex, m_Color)));
    glVertexPointer(3, GL_FLOAT, sizeof(T2V3C4Vertex),
            (void *)(offsetof(T2V3C4Vertex, m_Pos)));
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "VertexArray::draw:1");

    glproc::BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID);
    glDrawElements(GL_TRIANGLES, m_NumIndexes, GL_UNSIGNED_INT, 0);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "VertexArray::draw():2");
}

int VertexArray::getCurVert() const
{
    return m_NumVerts;
}

int VertexArray::getCurIndex() const
{
    return m_NumIndexes;
}

void VertexArray::grow()
{
    bool bChanged = false;
    if (m_NumVerts >= m_ReserveVerts-1) {
        bChanged = true;
        int oldReserveVerts = m_ReserveVerts;
        m_ReserveVerts = int(m_ReserveVerts*1.5);
        if (m_ReserveVerts < m_NumVerts) {
            m_ReserveVerts = m_NumVerts;
        }
        T2V3C4Vertex* pVertexData = m_pVertexData;
        m_pVertexData = new T2V3C4Vertex[m_ReserveVerts];
        memcpy(m_pVertexData, pVertexData, sizeof(T2V3C4Vertex)*oldReserveVerts);
        delete[] pVertexData;
    }
    if (m_NumIndexes >= m_ReserveIndexes-6) {
        bChanged = true;
        int oldReserveIndexes = m_ReserveIndexes;
        m_ReserveIndexes = int(m_ReserveIndexes*1.5);
        if (m_ReserveIndexes < m_NumIndexes) {
            m_ReserveIndexes = m_NumIndexes;
        }
        unsigned int * pIndexData = m_pIndexData;
        m_pIndexData = new unsigned int[m_ReserveIndexes];
        memcpy(m_pIndexData, pIndexData, sizeof(unsigned int)*oldReserveIndexes);
        delete[] pIndexData;
    }
    if (bChanged) {
        m_bDataChanged = true;
    }
}

void VertexArray::initBufferCache()
{
    if (s_pGLVertexBufferIDs.get() == 0) {
        s_pGLVertexBufferIDs.reset(new vector<unsigned int>);
    }
    if (s_pGLIndexBufferIDs.get() == 0) {
        s_pGLIndexBufferIDs.reset(new vector<unsigned int>);
    }
}

void VertexArray::deleteBufferCache()
{
    if (s_pGLVertexBufferIDs.get() != 0) {
        for (unsigned i=0; i<s_pGLVertexBufferIDs->size(); ++i) {
            glproc::DeleteBuffers(1, &((*s_pGLVertexBufferIDs)[i]));
        }
        s_pGLVertexBufferIDs->clear();
    }
    if (s_pGLIndexBufferIDs.get() != 0) {
        for (unsigned i=0; i<s_pGLIndexBufferIDs->size(); ++i) {
            glproc::DeleteBuffers(1, &((*s_pGLIndexBufferIDs)[i]));
        }
        s_pGLIndexBufferIDs->clear();
    }
}

}

<commit_msg>Fixed bug in vertex buffer caching across multiple Player.play() calls.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  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
//
//  Current versions can be found at www.libavg.de
//

#include "VertexArray.h"

#include "../base/Exception.h"
#include "../base/WideLine.h"
#include "../base/ObjectCounter.h"

#include <iostream>
#include <stddef.h>
#include <string.h>

using namespace std;
using namespace boost;

namespace avg {

thread_specific_ptr<vector<unsigned int> > VertexArray::s_pGLVertexBufferIDs;
thread_specific_ptr<vector<unsigned int> > VertexArray::s_pGLIndexBufferIDs;

VertexArray::VertexArray(int reserveVerts, int reserveIndexes)
    : m_NumVerts(0),
      m_NumIndexes(0),
      m_ReserveVerts(reserveVerts),
      m_ReserveIndexes(reserveIndexes),
      m_bDataChanged(true)
{
    ObjectCounter::get()->incRef(&typeid(*this));
    if (m_ReserveVerts < 10) {
        m_ReserveVerts = 10;
    }
    if (m_ReserveIndexes < 20) {
        m_ReserveIndexes = 20;
    }
    m_pVertexData = new T2V3C4Vertex[m_ReserveVerts];
    m_pIndexData = new unsigned int[m_ReserveIndexes];

    initBufferCache();
    if (s_pGLVertexBufferIDs->empty() || m_ReserveVerts != 10 ||
            m_ReserveIndexes != 20)
    {
        glproc::GenBuffers(1, &m_GLVertexBufferID);
        glproc::GenBuffers(1, &m_GLIndexBufferID);
    } else {
        m_GLVertexBufferID = s_pGLVertexBufferIDs->back();
        s_pGLVertexBufferIDs->pop_back();
        m_GLIndexBufferID = s_pGLIndexBufferIDs->back();
        s_pGLIndexBufferIDs->pop_back();
    }
}

VertexArray::~VertexArray()
{
    if (m_ReserveVerts == 10 && s_pGLVertexBufferIDs.get() != 0) {
        s_pGLVertexBufferIDs->push_back(m_GLVertexBufferID);
    } else {
        glproc::DeleteBuffers(1, &m_GLVertexBufferID);
    }
    if (m_ReserveIndexes == 20 && s_pGLIndexBufferIDs.get() != 0) {
        s_pGLIndexBufferIDs->push_back(m_GLIndexBufferID);
    } else {
        glproc::DeleteBuffers(1, &m_GLIndexBufferID);
    }
    delete[] m_pVertexData;
    delete[] m_pIndexData;
    ObjectCounter::get()->decRef(&typeid(*this));
}

void VertexArray::appendPos(const DPoint& pos, const DPoint& texPos, const Pixel32& color)
{
    if (m_NumVerts >= m_ReserveVerts-1) {
        grow();
    }
    T2V3C4Vertex* pVertex = &(m_pVertexData[m_NumVerts]);
    pVertex->m_Pos[0] = (GLfloat)pos.x;
    pVertex->m_Pos[1] = (GLfloat)pos.y;
    pVertex->m_Pos[2] = 0.0;
    pVertex->m_Tex[0] = (GLfloat)texPos.x;
    pVertex->m_Tex[1] = (GLfloat)texPos.y;
    pVertex->m_Color = color;
    m_bDataChanged = true;
    m_NumVerts++;
}

void VertexArray::appendTriIndexes(int v0, int v1, int v2)
{
    if (m_NumIndexes >= m_ReserveIndexes-3) {
        grow();
    }
    m_pIndexData[m_NumIndexes] = v0;
    m_pIndexData[m_NumIndexes+1] = v1;
    m_pIndexData[m_NumIndexes+2] = v2;
    m_NumIndexes += 3;
}

void VertexArray::appendQuadIndexes(int v0, int v1, int v2, int v3)
{
    if (m_NumIndexes >= m_ReserveIndexes-6) {
        grow();
    }
    m_pIndexData[m_NumIndexes] = v0;
    m_pIndexData[m_NumIndexes+1] = v1;
    m_pIndexData[m_NumIndexes+2] = v2;
    m_pIndexData[m_NumIndexes+3] = v1;
    m_pIndexData[m_NumIndexes+4] = v2;
    m_pIndexData[m_NumIndexes+5] = v3;
    m_NumIndexes += 6;
}

void VertexArray::addLineData(Pixel32 color, const DPoint& p1, const DPoint& p2,
        double width, double tc1, double tc2)
{
    WideLine wl(p1, p2, width);
    int curVertex = getCurVert();
    appendPos(wl.pl0, DPoint(tc1, 1), color);
    appendPos(wl.pr0, DPoint(tc1, 0), color);
    appendPos(wl.pl1, DPoint(tc2, 1), color);
    appendPos(wl.pr1, DPoint(tc2, 0), color);
    appendQuadIndexes(curVertex+1, curVertex, curVertex+3, curVertex+2);
}

void VertexArray::reset()
{
    m_NumVerts = 0;
    m_NumIndexes = 0;
}

void VertexArray::update()
{
    if (m_bDataChanged) {
        glproc::BindBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID);
        glproc::BufferData(GL_ARRAY_BUFFER, m_ReserveVerts*sizeof(T2V3C4Vertex), 0,
                GL_DYNAMIC_DRAW);
        void * pBuffer = glproc::MapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
        memcpy(pBuffer, m_pVertexData, m_NumVerts*sizeof(T2V3C4Vertex));
        glproc::UnmapBuffer(GL_ARRAY_BUFFER);

        glproc::BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID);
        glproc::BufferData(GL_ELEMENT_ARRAY_BUFFER,
            m_ReserveIndexes*sizeof(unsigned int), 0, GL_DYNAMIC_DRAW);
        pBuffer = glproc::MapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
        memcpy(pBuffer, m_pIndexData, m_NumIndexes*sizeof(unsigned int));
        glproc::UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);

        OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "VertexArray::update");
    }
    m_bDataChanged = false;
}

void VertexArray::draw()
{
    update();
    glproc::BindBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID);
    glTexCoordPointer(2, GL_FLOAT, sizeof(T2V3C4Vertex), 0);
    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(T2V3C4Vertex),
            (void *)(offsetof(T2V3C4Vertex, m_Color)));
    glVertexPointer(3, GL_FLOAT, sizeof(T2V3C4Vertex),
            (void *)(offsetof(T2V3C4Vertex, m_Pos)));
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "VertexArray::draw:1");

    glproc::BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID);
    glDrawElements(GL_TRIANGLES, m_NumIndexes, GL_UNSIGNED_INT, 0);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "VertexArray::draw():2");
}

int VertexArray::getCurVert() const
{
    return m_NumVerts;
}

int VertexArray::getCurIndex() const
{
    return m_NumIndexes;
}

void VertexArray::grow()
{
    bool bChanged = false;
    if (m_NumVerts >= m_ReserveVerts-1) {
        bChanged = true;
        int oldReserveVerts = m_ReserveVerts;
        m_ReserveVerts = int(m_ReserveVerts*1.5);
        if (m_ReserveVerts < m_NumVerts) {
            m_ReserveVerts = m_NumVerts;
        }
        T2V3C4Vertex* pVertexData = m_pVertexData;
        m_pVertexData = new T2V3C4Vertex[m_ReserveVerts];
        memcpy(m_pVertexData, pVertexData, sizeof(T2V3C4Vertex)*oldReserveVerts);
        delete[] pVertexData;
    }
    if (m_NumIndexes >= m_ReserveIndexes-6) {
        bChanged = true;
        int oldReserveIndexes = m_ReserveIndexes;
        m_ReserveIndexes = int(m_ReserveIndexes*1.5);
        if (m_ReserveIndexes < m_NumIndexes) {
            m_ReserveIndexes = m_NumIndexes;
        }
        unsigned int * pIndexData = m_pIndexData;
        m_pIndexData = new unsigned int[m_ReserveIndexes];
        memcpy(m_pIndexData, pIndexData, sizeof(unsigned int)*oldReserveIndexes);
        delete[] pIndexData;
    }
    if (bChanged) {
        m_bDataChanged = true;
    }
}

void VertexArray::initBufferCache()
{
    if (s_pGLVertexBufferIDs.get() == 0) {
        s_pGLVertexBufferIDs.reset(new vector<unsigned int>);
    }
    if (s_pGLIndexBufferIDs.get() == 0) {
        s_pGLIndexBufferIDs.reset(new vector<unsigned int>);
    }
}

void VertexArray::deleteBufferCache()
{
    if (s_pGLVertexBufferIDs.get() != 0) {
        for (unsigned i=0; i<s_pGLVertexBufferIDs->size(); ++i) {
            glproc::DeleteBuffers(1, &((*s_pGLVertexBufferIDs)[i]));
        }
        s_pGLVertexBufferIDs->clear();
        s_pGLVertexBufferIDs.reset();
    }
    if (s_pGLIndexBufferIDs.get() != 0) {
        for (unsigned i=0; i<s_pGLIndexBufferIDs->size(); ++i) {
            glproc::DeleteBuffers(1, &((*s_pGLIndexBufferIDs)[i]));
        }
        s_pGLIndexBufferIDs->clear();
        s_pGLIndexBufferIDs.reset();
    }
}

}

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkShepardMethod.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkShepardMethod.h"

#include "vtkFloatArray.h"
#include "vtkImageData.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPointData.h"

vtkStandardNewMacro(vtkShepardMethod);

// Construct with sample dimensions=(50,50,50) and so that model bounds are
// automatically computed from input. Null value for each unvisited output
// point is 0.0. Maximum distance is 0.25.
vtkShepardMethod::vtkShepardMethod()
{
  this->MaximumDistance = 0.25;

  this->ModelBounds[0] = 0.0;
  this->ModelBounds[1] = 0.0;
  this->ModelBounds[2] = 0.0;
  this->ModelBounds[3] = 0.0;
  this->ModelBounds[4] = 0.0;
  this->ModelBounds[5] = 0.0;

  this->SampleDimensions[0] = 50;
  this->SampleDimensions[1] = 50;
  this->SampleDimensions[2] = 50;

  this->NullValue = 0.0;
}

// Compute ModelBounds from input geometry.
double vtkShepardMethod::ComputeModelBounds(double origin[3],
                                            double spacing[3])
{
  double *bounds, maxDist;
  int i, adjustBounds=0;

  // compute model bounds if not set previously
  if ( this->ModelBounds[0] >= this->ModelBounds[1] ||
       this->ModelBounds[2] >= this->ModelBounds[3] ||
       this->ModelBounds[4] >= this->ModelBounds[5] )
    {
    adjustBounds = 1;
    vtkDataSet *ds = vtkDataSet::SafeDownCast(this->GetInput());
    // ds better be non null otherwise something is very wrong here
    bounds = ds->GetBounds();
    }
  else
    {
    bounds = this->ModelBounds;
    }

  for (maxDist=0.0, i=0; i<3; i++)
    {
    if ( (bounds[2*i+1] - bounds[2*i]) > maxDist )
      {
      maxDist = bounds[2*i+1] - bounds[2*i];
      }
    }
  maxDist *= this->MaximumDistance;

  // adjust bounds so model fits strictly inside (only if not set previously)
  if ( adjustBounds )
    {
    for (i=0; i<3; i++)
      {
      this->ModelBounds[2*i] = bounds[2*i] - maxDist;
      this->ModelBounds[2*i+1] = bounds[2*i+1] + maxDist;
      }
    }

  // Set volume origin and data spacing
  for (i=0; i<3; i++)
    {
    origin[i] = this->ModelBounds[2*i];
    spacing[i] = (this->ModelBounds[2*i+1] - this->ModelBounds[2*i])
            / (this->SampleDimensions[i] - 1);
    }

  return maxDist;
}

int vtkShepardMethod::RequestInformation (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector ** vtkNotUsed( inputVector ),
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation* outInfo = outputVector->GetInformationObject(0);

  int i;
  double ar[3], origin[3];

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               0, this->SampleDimensions[0]-1,
               0, this->SampleDimensions[1]-1,
               0, this->SampleDimensions[2]-1);

  for (i=0; i < 3; i++)
    {
    origin[i] = this->ModelBounds[2*i];
    if ( this->SampleDimensions[i] <= 1 )
      {
      ar[i] = 1;
      }
    else
      {
      ar[i] = (this->ModelBounds[2*i+1] - this->ModelBounds[2*i])
              / (this->SampleDimensions[i] - 1);
      }
    }
  outInfo->Set(vtkDataObject::ORIGIN(),origin,3);
  outInfo->Set(vtkDataObject::SPACING(),ar,3);

  vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_FLOAT, 1);
  return 1;
}

int vtkShepardMethod::RequestData(
  vtkInformation* vtkNotUsed( request ),
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  // get the input
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));

  // get the output
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  vtkImageData *output = vtkImageData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // We need to allocate our own scalars since we are overriding
  // the superclasses "Execute()" method.
  output->SetExtent(
    outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));
  output->AllocateScalars(outInfo);

  vtkIdType ptId, i;
  int j, k;
  double *px, x[3], s, *sum, spacing[3], origin[3];

  double maxDistance, distance2, inScalar;
  vtkDataArray *inScalars;
  vtkIdType numPts, numNewPts, idx;
  int min[3], max[3];
  int jkFactor;
  vtkFloatArray *newScalars =
    vtkFloatArray::SafeDownCast(output->GetPointData()->GetScalars());

  vtkDebugMacro(<< "Executing Shepard method");

  // Check input
  //
  if ( (numPts=input->GetNumberOfPoints()) < 1 )
    {
    vtkErrorMacro(<<"Points must be defined!");
    return 1;
    }

  if ( (inScalars = input->GetPointData()->GetScalars()) == NULL )
    {
    vtkErrorMacro(<<"Scalars must be defined!");
    return 1;
    }

  newScalars->SetName(inScalars->GetName());

  // Allocate
  //
  numNewPts = this->SampleDimensions[0] * this->SampleDimensions[1]
              * this->SampleDimensions[2];

  sum = new double[numNewPts];
  for (i=0; i<numNewPts; i++)
    {
    newScalars->SetComponent(i,0,0.0);
    sum[i] = 0.0;
    }

  maxDistance = this->ComputeModelBounds(origin,spacing);
  outInfo->Set(vtkDataObject::ORIGIN(),origin,3);
  outInfo->Set(vtkDataObject::SPACING(),spacing,3);

  // Traverse all input points.
  // Each input point affects voxels within maxDistance.
  //
  int abortExecute=0;
  for (ptId=0; ptId < numPts && !abortExecute; ptId++)
    {
    if ( ! (ptId % 1000) )
      {
      vtkDebugMacro(<<"Inserting point #" << ptId);
      this->UpdateProgress (ptId/numPts);
      if (this->GetAbortExecute())
        {
        abortExecute = 1;
        break;
        }
      }

    px = input->GetPoint(ptId);
    inScalar = inScalars->GetComponent(ptId,0);

    for (i=0; i<3; i++) //compute dimensional bounds in data set
      {
      double amin = static_cast<double>(
        (px[i] - maxDistance) - origin[i]) / spacing[i];
      double amax = static_cast<double>(
        (px[i] + maxDistance) - origin[i]) / spacing[i];
      min[i] = static_cast<int>(amin);
      max[i] = static_cast<int>(amax);

      if (min[i] < amin)
        {
        min[i]++; // round upward to nearest integer to get min[i]
        }
      if (max[i] > amax)
        {
        max[i]--; // round downward to nearest integer to get max[i]
        }

      if (min[i] < 0)
        {
        min[i] = 0; // valid range check
        }
      if (max[i] >= this->SampleDimensions[i])
        {
        max[i] = this->SampleDimensions[i] - 1;
        }
      }

    for (i=0; i<3; i++) //compute dimensional bounds in data set
      {
      min[i] = static_cast<int>(
        static_cast<double>((px[i] - maxDistance) - origin[i]) / spacing[i]);
      max[i] = static_cast<int>(
        static_cast<double>((px[i] + maxDistance) - origin[i]) / spacing[i]);
      if (min[i] < 0)
        {
        min[i] = 0;
        }
      if (max[i] >= this->SampleDimensions[i])
        {
        max[i] = this->SampleDimensions[i] - 1;
        }
      }

    jkFactor = this->SampleDimensions[0]*this->SampleDimensions[1];
    for (k = min[2]; k <= max[2]; k++)
      {
      x[2] = spacing[2] * k + origin[2];
      for (j = min[1]; j <= max[1]; j++)
        {
        x[1] = spacing[1] * j + origin[1];
        for (i = min[0]; i <= max[0]; i++)
          {
          x[0] = spacing[0] * i + origin[0];
          idx = jkFactor*k + this->SampleDimensions[0]*j + i;

          distance2 = vtkMath::Distance2BetweenPoints(x,px);

          if ( distance2 == 0.0 )
            {
            sum[idx] = VTK_DOUBLE_MAX;
            newScalars->SetComponent(idx,0,VTK_FLOAT_MAX);
            }
          else
            {
            s = newScalars->GetComponent(idx,0);
            sum[idx] += 1.0 / distance2;
            newScalars->SetComponent(idx,0,s+(inScalar/distance2));
            }
          }
        }
      }
    }

  // Run through scalars and compute final values
  //
  for (ptId=0; ptId<numNewPts; ptId++)
    {
    s = newScalars->GetComponent(ptId,0);
    if ( sum[ptId] != 0.0 )
      {
      newScalars->SetComponent(ptId,0,s/sum[ptId]);
      }
    else
      {
      newScalars->SetComponent(ptId,0,this->NullValue);
      }
    }

  // Update self
  //
  delete [] sum;

  return 1;
}

// Set the i-j-k dimensions on which to sample the distance function.
void vtkShepardMethod::SetSampleDimensions(int i, int j, int k)
{
  int dim[3];

  dim[0] = i;
  dim[1] = j;
  dim[2] = k;

  this->SetSampleDimensions(dim);
}

// Set the i-j-k dimensions on which to sample the distance function.
void vtkShepardMethod::SetSampleDimensions(int dim[3])
{
  int dataDim, i;

  vtkDebugMacro(<< " setting SampleDimensions to (" << dim[0] << ","
                << dim[1] << "," << dim[2] << ")");

  if ( dim[0] != this->SampleDimensions[0] ||
       dim[1] != this->SampleDimensions[1] ||
       dim[2] != this->SampleDimensions[2] )
    {
    if ( dim[0]<1 || dim[1]<1 || dim[2]<1 )
      {
      vtkErrorMacro (<< "Bad Sample Dimensions, retaining previous values");
      return;
      }

    for (dataDim=0, i=0; i<3 ; i++)
      {
      if (dim[i] > 1)
        {
        dataDim++;
        }
      }

    if ( dataDim  < 3 )
      {
      vtkErrorMacro(<<"Sample dimensions must define a volume!");
      return;
      }

    for ( i=0; i<3; i++)
      {
      this->SampleDimensions[i] = dim[i];
      }

    this->Modified();
    }
}

int vtkShepardMethod::FillInputPortInformation(
  int vtkNotUsed(port), vtkInformation* info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
  return 1;
}

void vtkShepardMethod::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Maximum Distance: " << this->MaximumDistance << "\n";

  os << indent << "Sample Dimensions: (" << this->SampleDimensions[0] << ", "
               << this->SampleDimensions[1] << ", "
               << this->SampleDimensions[2] << ")\n";

  os << indent << "ModelBounds: \n";
  os << indent << "  Xmin,Xmax: (" << this->ModelBounds[0] << ", " << this->ModelBounds[1] << ")\n";
  os << indent << "  Ymin,Ymax: (" << this->ModelBounds[2] << ", " << this->ModelBounds[3] << ")\n";
  os << indent << "  Zmin,Zmax: (" << this->ModelBounds[4] << ", " << this->ModelBounds[5] << ")\n";

  os << indent << "Null Value: " << this->NullValue << "\n";

}
<commit_msg>fix warning by eliminating redundant loop termination variable<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkShepardMethod.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkShepardMethod.h"

#include "vtkFloatArray.h"
#include "vtkImageData.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPointData.h"

vtkStandardNewMacro(vtkShepardMethod);

// Construct with sample dimensions=(50,50,50) and so that model bounds are
// automatically computed from input. Null value for each unvisited output
// point is 0.0. Maximum distance is 0.25.
vtkShepardMethod::vtkShepardMethod()
{
  this->MaximumDistance = 0.25;

  this->ModelBounds[0] = 0.0;
  this->ModelBounds[1] = 0.0;
  this->ModelBounds[2] = 0.0;
  this->ModelBounds[3] = 0.0;
  this->ModelBounds[4] = 0.0;
  this->ModelBounds[5] = 0.0;

  this->SampleDimensions[0] = 50;
  this->SampleDimensions[1] = 50;
  this->SampleDimensions[2] = 50;

  this->NullValue = 0.0;
}

// Compute ModelBounds from input geometry.
double vtkShepardMethod::ComputeModelBounds(double origin[3],
                                            double spacing[3])
{
  double *bounds, maxDist;
  int i, adjustBounds=0;

  // compute model bounds if not set previously
  if ( this->ModelBounds[0] >= this->ModelBounds[1] ||
       this->ModelBounds[2] >= this->ModelBounds[3] ||
       this->ModelBounds[4] >= this->ModelBounds[5] )
    {
    adjustBounds = 1;
    vtkDataSet *ds = vtkDataSet::SafeDownCast(this->GetInput());
    // ds better be non null otherwise something is very wrong here
    bounds = ds->GetBounds();
    }
  else
    {
    bounds = this->ModelBounds;
    }

  for (maxDist=0.0, i=0; i<3; i++)
    {
    if ( (bounds[2*i+1] - bounds[2*i]) > maxDist )
      {
      maxDist = bounds[2*i+1] - bounds[2*i];
      }
    }
  maxDist *= this->MaximumDistance;

  // adjust bounds so model fits strictly inside (only if not set previously)
  if ( adjustBounds )
    {
    for (i=0; i<3; i++)
      {
      this->ModelBounds[2*i] = bounds[2*i] - maxDist;
      this->ModelBounds[2*i+1] = bounds[2*i+1] + maxDist;
      }
    }

  // Set volume origin and data spacing
  for (i=0; i<3; i++)
    {
    origin[i] = this->ModelBounds[2*i];
    spacing[i] = (this->ModelBounds[2*i+1] - this->ModelBounds[2*i])
            / (this->SampleDimensions[i] - 1);
    }

  return maxDist;
}

int vtkShepardMethod::RequestInformation (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector ** vtkNotUsed( inputVector ),
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation* outInfo = outputVector->GetInformationObject(0);

  int i;
  double ar[3], origin[3];

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               0, this->SampleDimensions[0]-1,
               0, this->SampleDimensions[1]-1,
               0, this->SampleDimensions[2]-1);

  for (i=0; i < 3; i++)
    {
    origin[i] = this->ModelBounds[2*i];
    if ( this->SampleDimensions[i] <= 1 )
      {
      ar[i] = 1;
      }
    else
      {
      ar[i] = (this->ModelBounds[2*i+1] - this->ModelBounds[2*i])
              / (this->SampleDimensions[i] - 1);
      }
    }
  outInfo->Set(vtkDataObject::ORIGIN(),origin,3);
  outInfo->Set(vtkDataObject::SPACING(),ar,3);

  vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_FLOAT, 1);
  return 1;
}

int vtkShepardMethod::RequestData(
  vtkInformation* vtkNotUsed( request ),
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  // get the input
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));

  // get the output
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  vtkImageData *output = vtkImageData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // We need to allocate our own scalars since we are overriding
  // the superclasses "Execute()" method.
  output->SetExtent(
    outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));
  output->AllocateScalars(outInfo);

  vtkIdType ptId, i;
  int j, k;
  double *px, x[3], s, *sum, spacing[3], origin[3];

  double maxDistance, distance2, inScalar;
  vtkDataArray *inScalars;
  vtkIdType numPts, numNewPts, idx;
  int min[3], max[3];
  int jkFactor;
  vtkFloatArray *newScalars =
    vtkFloatArray::SafeDownCast(output->GetPointData()->GetScalars());

  vtkDebugMacro(<< "Executing Shepard method");

  // Check input
  //
  if ( (numPts=input->GetNumberOfPoints()) < 1 )
    {
    vtkErrorMacro(<<"Points must be defined!");
    return 1;
    }

  if ( (inScalars = input->GetPointData()->GetScalars()) == NULL )
    {
    vtkErrorMacro(<<"Scalars must be defined!");
    return 1;
    }

  newScalars->SetName(inScalars->GetName());

  // Allocate
  //
  numNewPts = this->SampleDimensions[0] * this->SampleDimensions[1]
              * this->SampleDimensions[2];

  sum = new double[numNewPts];
  for (i=0; i<numNewPts; i++)
    {
    newScalars->SetComponent(i,0,0.0);
    sum[i] = 0.0;
    }

  maxDistance = this->ComputeModelBounds(origin,spacing);
  outInfo->Set(vtkDataObject::ORIGIN(),origin,3);
  outInfo->Set(vtkDataObject::SPACING(),spacing,3);

  // Traverse all input points.
  // Each input point affects voxels within maxDistance.
  //
  for (ptId=0; ptId < numPts; ptId++)
    {
    if ( ! (ptId % 1000) )
      {
      vtkDebugMacro(<<"Inserting point #" << ptId);
      this->UpdateProgress (ptId/numPts);
      if (this->GetAbortExecute())
        {
        break;
        }
      }

    px = input->GetPoint(ptId);
    inScalar = inScalars->GetComponent(ptId,0);

    for (i=0; i<3; i++) //compute dimensional bounds in data set
      {
      double amin = static_cast<double>(
        (px[i] - maxDistance) - origin[i]) / spacing[i];
      double amax = static_cast<double>(
        (px[i] + maxDistance) - origin[i]) / spacing[i];
      min[i] = static_cast<int>(amin);
      max[i] = static_cast<int>(amax);

      if (min[i] < amin)
        {
        min[i]++; // round upward to nearest integer to get min[i]
        }
      if (max[i] > amax)
        {
        max[i]--; // round downward to nearest integer to get max[i]
        }

      if (min[i] < 0)
        {
        min[i] = 0; // valid range check
        }
      if (max[i] >= this->SampleDimensions[i])
        {
        max[i] = this->SampleDimensions[i] - 1;
        }
      }

    for (i=0; i<3; i++) //compute dimensional bounds in data set
      {
      min[i] = static_cast<int>(
        static_cast<double>((px[i] - maxDistance) - origin[i]) / spacing[i]);
      max[i] = static_cast<int>(
        static_cast<double>((px[i] + maxDistance) - origin[i]) / spacing[i]);
      if (min[i] < 0)
        {
        min[i] = 0;
        }
      if (max[i] >= this->SampleDimensions[i])
        {
        max[i] = this->SampleDimensions[i] - 1;
        }
      }

    jkFactor = this->SampleDimensions[0]*this->SampleDimensions[1];
    for (k = min[2]; k <= max[2]; k++)
      {
      x[2] = spacing[2] * k + origin[2];
      for (j = min[1]; j <= max[1]; j++)
        {
        x[1] = spacing[1] * j + origin[1];
        for (i = min[0]; i <= max[0]; i++)
          {
          x[0] = spacing[0] * i + origin[0];
          idx = jkFactor*k + this->SampleDimensions[0]*j + i;

          distance2 = vtkMath::Distance2BetweenPoints(x,px);

          if ( distance2 == 0.0 )
            {
            sum[idx] = VTK_DOUBLE_MAX;
            newScalars->SetComponent(idx,0,VTK_FLOAT_MAX);
            }
          else
            {
            s = newScalars->GetComponent(idx,0);
            sum[idx] += 1.0 / distance2;
            newScalars->SetComponent(idx,0,s+(inScalar/distance2));
            }
          }
        }
      }
    }

  // Run through scalars and compute final values
  //
  for (ptId=0; ptId<numNewPts; ptId++)
    {
    s = newScalars->GetComponent(ptId,0);
    if ( sum[ptId] != 0.0 )
      {
      newScalars->SetComponent(ptId,0,s/sum[ptId]);
      }
    else
      {
      newScalars->SetComponent(ptId,0,this->NullValue);
      }
    }

  // Update self
  //
  delete [] sum;

  return 1;
}

// Set the i-j-k dimensions on which to sample the distance function.
void vtkShepardMethod::SetSampleDimensions(int i, int j, int k)
{
  int dim[3];

  dim[0] = i;
  dim[1] = j;
  dim[2] = k;

  this->SetSampleDimensions(dim);
}

// Set the i-j-k dimensions on which to sample the distance function.
void vtkShepardMethod::SetSampleDimensions(int dim[3])
{
  int dataDim, i;

  vtkDebugMacro(<< " setting SampleDimensions to (" << dim[0] << ","
                << dim[1] << "," << dim[2] << ")");

  if ( dim[0] != this->SampleDimensions[0] ||
       dim[1] != this->SampleDimensions[1] ||
       dim[2] != this->SampleDimensions[2] )
    {
    if ( dim[0]<1 || dim[1]<1 || dim[2]<1 )
      {
      vtkErrorMacro (<< "Bad Sample Dimensions, retaining previous values");
      return;
      }

    for (dataDim=0, i=0; i<3 ; i++)
      {
      if (dim[i] > 1)
        {
        dataDim++;
        }
      }

    if ( dataDim  < 3 )
      {
      vtkErrorMacro(<<"Sample dimensions must define a volume!");
      return;
      }

    for ( i=0; i<3; i++)
      {
      this->SampleDimensions[i] = dim[i];
      }

    this->Modified();
    }
}

int vtkShepardMethod::FillInputPortInformation(
  int vtkNotUsed(port), vtkInformation* info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
  return 1;
}

void vtkShepardMethod::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Maximum Distance: " << this->MaximumDistance << "\n";

  os << indent << "Sample Dimensions: (" << this->SampleDimensions[0] << ", "
               << this->SampleDimensions[1] << ", "
               << this->SampleDimensions[2] << ")\n";

  os << indent << "ModelBounds: \n";
  os << indent << "  Xmin,Xmax: (" << this->ModelBounds[0] << ", " << this->ModelBounds[1] << ")\n";
  os << indent << "  Ymin,Ymax: (" << this->ModelBounds[2] << ", " << this->ModelBounds[3] << ")\n";
  os << indent << "  Zmin,Zmax: (" << this->ModelBounds[4] << ", " << this->ModelBounds[5] << ")\n";

  os << indent << "Null Value: " << this->NullValue << "\n";

}
<|endoftext|>


<commit_before>/**
 * echo.cpp - echo serial characters back
 *
 * connect using putty/hyperterm/minicom .. 9600-8-N-1
 * what ever you type is echoed back
 */

#include <fabooh.h>
#include <main.h>
#include <serial.h>

namespace {
  const uint32_t BAUD_RATE = 9600;
  serial_default_t<BAUD_RATE, CPU::frequency, TX_PIN, RX_PIN> Serial; // TX=varies, RX=varies
  const char *prompt = "\r\ntype here: ";
}

void setup() {
  Serial.begin(BAUD_RATE);                 // configure serial device for Timer or SW only serial
}

void loop() {
  Serial.print(prompt);

  for (;;) {
    int c;
    // use a blocking read to get a character
    switch ((c = Serial.read())) {

    case '\r':
      return;

    default:
      Serial.write(c);
      break;
    }
  }
}
<commit_msg>make demo compatible with g2231 and g2452<commit_after>/**
 * echo.cpp - echo serial characters back
 *
 * connect using putty/hyperterm/minicom .. 9600-8-N-1
 * what ever you type is echoed back
 */

#include <fabooh.h>
#include <main.h>
#include <serial.h>

namespace {
  const uint32_t BAUD_RATE = 9600;
#if defined(__MSP430G2231__) || defined(__MSP430G2452__)
  timer_serial_t<BAUD_RATE, CPU::frequency, TX_PIN, RX_PIN> Serial; // TX=varies, RX=varies
#else
  serial_default_t<BAUD_RATE, CPU::frequency, TX_PIN, RX_PIN> Serial; // TX=varies, RX=varies
#endif
  const char *prompt = "\r\ntype here:\r";
}

void setup() {
  Serial.begin(BAUD_RATE);                 // configure serial device for Timer or SW only serial
}

void loop() {
  Serial.print(prompt);

  for (;;) {
    int c;
    // use a blocking read to get a character
    switch ((c = Serial.read())) {

    case '\r':
      return;

    default:
      Serial.write(c);
      break;
    }
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: urp_bridgeimpl.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: svesik $ $Date: 2004-04-21 13:44:31 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/
#include <osl/thread.h>
#include <bridges/remote/helper.hxx>

#include <algorithm>

#include "urp_bridgeimpl.hxx"

using namespace ::rtl;
using namespace ::osl;
using namespace ::com::sun::star::uno;
namespace bridges_urp
{

template < class t >
inline t mymin( const t & val1, const t & val2 )
{
    return val1 < val2 ? val1 : val2;
}

/***********
 * urp_BridgeImpl
 ***********/
urp_BridgeImpl::urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize ) :
    m_blockMarshaler( this , nInitialMarshalerSize , ::bridges_remote::remote_retrieveOidFromProxy),
    m_nMarshaledMessages( 0 ),
    m_oidCacheOut( (sal_uInt16)nCacheSize ),
    m_tidCacheOut( (sal_uInt16)nCacheSize ),
    m_typeCacheOut( (sal_uInt16)nCacheSize )
{
    m_pOidIn = new OUString[ nCacheSize ];
    m_pTidIn = new ByteSequence[ nCacheSize ];
    m_pTypeIn = new Type[ nCacheSize ];
    m_nRemoteThreads = 0;
}

urp_BridgeImpl::~urp_BridgeImpl()
{
    delete [] m_pOidIn;
    delete [] m_pTidIn;
    delete [] m_pTypeIn;
}

void urp_BridgeImpl::applyProtocolChanges( const Properties &props )
{
    if( m_properties.nTypeCacheSize != props.nTypeCacheSize )
    {
        if( props.nTypeCacheSize == 0 )
        {
            delete [] m_pTypeIn;
            m_pTypeIn = 0;
        }
        else
        {
            Type *pNew = new Type[props.nTypeCacheSize];
            sal_Int32 i;
            sal_Int32 iMin = mymin( m_properties.nTypeCacheSize , props.nTypeCacheSize );
            for( i = 0; i < iMin ; i ++ )
            {
                pNew[i] = m_pTypeIn[i];
            }
            delete [] m_pTypeIn;
            m_pTypeIn = pNew;
        }
        OSL_ASSERT( props.nTypeCacheSize <= 0xffff );
        m_properties.nTypeCacheSize = props.nTypeCacheSize;
        m_typeCacheOut.resize( (sal_uInt16)props.nTypeCacheSize );
    }

     if( m_properties.nOidCacheSize != props.nOidCacheSize )
     {
         if( 0 == props.nOidCacheSize )
         {
             delete [] m_pOidIn;
             m_pOidIn = 0;
         }
         else
         {
             OUString *pNew = new OUString[props.nOidCacheSize];
             sal_Int32 i;
             sal_Int32 iMin = mymin( m_properties.nOidCacheSize , props.nOidCacheSize );
             for( i = 0; i < iMin ; i ++ )
             {
                 pNew[i] = m_pOidIn[i];
             }
             delete [] m_pOidIn;
             m_pOidIn = pNew;
         }
        OSL_ASSERT( props.nOidCacheSize <= 0xffff );
         m_oidCacheOut.resize( (sal_uInt16)props.nOidCacheSize );
         m_properties.nOidCacheSize = props.nOidCacheSize;
     }

     if( m_properties.nTidCacheSize != props.nTidCacheSize )
     {
         if( 0 == props.nTidCacheSize )
         {
             delete [] m_pTidIn;
            m_pTidIn = 0;
         }
         else
         {
             ByteSequence *pNew = new ByteSequence[props.nTidCacheSize];
             sal_Int32 i;
             sal_Int32 iMin = mymin( m_properties.nTidCacheSize , props.nTidCacheSize );
             for( i = 0; i < iMin ; i ++ )
             {
                 pNew[i] = m_pTidIn[i];
             }
             delete [] m_pTidIn;
             m_pTidIn = pNew;
         }
        OSL_ASSERT( props.nTidCacheSize <= 0xffff );
         m_tidCacheOut.resize( (sal_uInt16)props.nTidCacheSize );
         m_properties.nTidCacheSize = props.nTidCacheSize;
     }

     if( m_properties.sVersion != props.sVersion )
     {
        m_properties.sVersion = props.sVersion;
     }

    if( m_properties.nFlushBlockSize != props.nFlushBlockSize )
    {
        m_properties.nFlushBlockSize = props.nFlushBlockSize;
    }

    if( m_properties.nOnewayTimeoutMUSEC != props.nOnewayTimeoutMUSEC )
    {
        m_properties.nOnewayTimeoutMUSEC = props.nOnewayTimeoutMUSEC;
    }

    if( props.bClearCache )
    {
        if( m_properties.nTypeCacheSize )
        {
            delete [] m_pTypeIn;
            m_pTypeIn = new Type[m_properties.nTypeCacheSize];
            m_typeCacheOut.clear();
        }
        m_lastInType = Type();
        m_lastOutType = Type();

        if( m_properties.nOidCacheSize )
        {
            delete [] m_pOidIn;
            m_pOidIn = new OUString[ m_properties.nOidCacheSize];
            m_oidCacheOut.clear();
        }
        m_lastOutOid = OUString();
        m_lastInOid = OUString();

        if( m_properties.nTidCacheSize )
        {
            delete [] m_pTidIn;
            m_pTidIn = new ByteSequence[m_properties.nTidCacheSize];
            m_tidCacheOut.clear();
        }
        m_lastInTid = ByteSequence();
        m_lastOutTid = ByteSequence();
    }

    if( m_properties.bNegotiate != props.bNegotiate )
    {
        m_properties.bNegotiate = props.bNegotiate;
    }

    if( m_properties.bForceSynchronous != props.bForceSynchronous )
    {
        m_properties.bForceSynchronous = props.bForceSynchronous;
    }

}

void urp_BridgeImpl::addError( char *pError )
{
    OUString message = OUString( RTL_CONSTASCII_USTRINGPARAM( "(tid=" ) );
    message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
    message += OUString::createFromAscii( ") " );
    message += OUString::createFromAscii( pError );
    MutexGuard guard( m_errorListMutex );
    m_lstErrors.push_back( message );
}

void urp_BridgeImpl::addError( const OUString & error )
{
    OUString message = OUString( RTL_CONSTASCII_USTRINGPARAM( "(tid=" ) );
    message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
    message += OUString::createFromAscii( ") " );
    message += error;
    MutexGuard guard( m_errorListMutex );
    m_lstErrors.push_back( message );
}

void urp_BridgeImpl::dumpErrors( FILE * f)
{
    MutexGuard guard( m_errorListMutex );
    for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
         ii != m_lstErrors.end() ;
         ++ii )
    {
        OString o = OUStringToOString( *ii , RTL_TEXTENCODING_UTF8 );
        fprintf( f,  "%s\n" , o.getStr() );
    }
}

OUString urp_BridgeImpl::getErrorsAsString( )
{
    MutexGuard guard( m_errorListMutex );
    OUString ret;
    for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
         ii != m_lstErrors.end() ;
         ++ii )
    {
        ret += *ii;
    }
    return ret;
}

}
<commit_msg>INTEGRATION: CWS ooo19126 (1.8.86); FILE MERGED 2005/09/05 17:07:53 rt 1.8.86.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: urp_bridgeimpl.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 22:44:41 $
 *
 *  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
 *
 ************************************************************************/
#include <osl/thread.h>
#include <bridges/remote/helper.hxx>

#include <algorithm>

#include "urp_bridgeimpl.hxx"

using namespace ::rtl;
using namespace ::osl;
using namespace ::com::sun::star::uno;
namespace bridges_urp
{

template < class t >
inline t mymin( const t & val1, const t & val2 )
{
    return val1 < val2 ? val1 : val2;
}

/***********
 * urp_BridgeImpl
 ***********/
urp_BridgeImpl::urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize ) :
    m_blockMarshaler( this , nInitialMarshalerSize , ::bridges_remote::remote_retrieveOidFromProxy),
    m_nMarshaledMessages( 0 ),
    m_oidCacheOut( (sal_uInt16)nCacheSize ),
    m_tidCacheOut( (sal_uInt16)nCacheSize ),
    m_typeCacheOut( (sal_uInt16)nCacheSize )
{
    m_pOidIn = new OUString[ nCacheSize ];
    m_pTidIn = new ByteSequence[ nCacheSize ];
    m_pTypeIn = new Type[ nCacheSize ];
    m_nRemoteThreads = 0;
}

urp_BridgeImpl::~urp_BridgeImpl()
{
    delete [] m_pOidIn;
    delete [] m_pTidIn;
    delete [] m_pTypeIn;
}

void urp_BridgeImpl::applyProtocolChanges( const Properties &props )
{
    if( m_properties.nTypeCacheSize != props.nTypeCacheSize )
    {
        if( props.nTypeCacheSize == 0 )
        {
            delete [] m_pTypeIn;
            m_pTypeIn = 0;
        }
        else
        {
            Type *pNew = new Type[props.nTypeCacheSize];
            sal_Int32 i;
            sal_Int32 iMin = mymin( m_properties.nTypeCacheSize , props.nTypeCacheSize );
            for( i = 0; i < iMin ; i ++ )
            {
                pNew[i] = m_pTypeIn[i];
            }
            delete [] m_pTypeIn;
            m_pTypeIn = pNew;
        }
        OSL_ASSERT( props.nTypeCacheSize <= 0xffff );
        m_properties.nTypeCacheSize = props.nTypeCacheSize;
        m_typeCacheOut.resize( (sal_uInt16)props.nTypeCacheSize );
    }

     if( m_properties.nOidCacheSize != props.nOidCacheSize )
     {
         if( 0 == props.nOidCacheSize )
         {
             delete [] m_pOidIn;
             m_pOidIn = 0;
         }
         else
         {
             OUString *pNew = new OUString[props.nOidCacheSize];
             sal_Int32 i;
             sal_Int32 iMin = mymin( m_properties.nOidCacheSize , props.nOidCacheSize );
             for( i = 0; i < iMin ; i ++ )
             {
                 pNew[i] = m_pOidIn[i];
             }
             delete [] m_pOidIn;
             m_pOidIn = pNew;
         }
        OSL_ASSERT( props.nOidCacheSize <= 0xffff );
         m_oidCacheOut.resize( (sal_uInt16)props.nOidCacheSize );
         m_properties.nOidCacheSize = props.nOidCacheSize;
     }

     if( m_properties.nTidCacheSize != props.nTidCacheSize )
     {
         if( 0 == props.nTidCacheSize )
         {
             delete [] m_pTidIn;
            m_pTidIn = 0;
         }
         else
         {
             ByteSequence *pNew = new ByteSequence[props.nTidCacheSize];
             sal_Int32 i;
             sal_Int32 iMin = mymin( m_properties.nTidCacheSize , props.nTidCacheSize );
             for( i = 0; i < iMin ; i ++ )
             {
                 pNew[i] = m_pTidIn[i];
             }
             delete [] m_pTidIn;
             m_pTidIn = pNew;
         }
        OSL_ASSERT( props.nTidCacheSize <= 0xffff );
         m_tidCacheOut.resize( (sal_uInt16)props.nTidCacheSize );
         m_properties.nTidCacheSize = props.nTidCacheSize;
     }

     if( m_properties.sVersion != props.sVersion )
     {
        m_properties.sVersion = props.sVersion;
     }

    if( m_properties.nFlushBlockSize != props.nFlushBlockSize )
    {
        m_properties.nFlushBlockSize = props.nFlushBlockSize;
    }

    if( m_properties.nOnewayTimeoutMUSEC != props.nOnewayTimeoutMUSEC )
    {
        m_properties.nOnewayTimeoutMUSEC = props.nOnewayTimeoutMUSEC;
    }

    if( props.bClearCache )
    {
        if( m_properties.nTypeCacheSize )
        {
            delete [] m_pTypeIn;
            m_pTypeIn = new Type[m_properties.nTypeCacheSize];
            m_typeCacheOut.clear();
        }
        m_lastInType = Type();
        m_lastOutType = Type();

        if( m_properties.nOidCacheSize )
        {
            delete [] m_pOidIn;
            m_pOidIn = new OUString[ m_properties.nOidCacheSize];
            m_oidCacheOut.clear();
        }
        m_lastOutOid = OUString();
        m_lastInOid = OUString();

        if( m_properties.nTidCacheSize )
        {
            delete [] m_pTidIn;
            m_pTidIn = new ByteSequence[m_properties.nTidCacheSize];
            m_tidCacheOut.clear();
        }
        m_lastInTid = ByteSequence();
        m_lastOutTid = ByteSequence();
    }

    if( m_properties.bNegotiate != props.bNegotiate )
    {
        m_properties.bNegotiate = props.bNegotiate;
    }

    if( m_properties.bForceSynchronous != props.bForceSynchronous )
    {
        m_properties.bForceSynchronous = props.bForceSynchronous;
    }

}

void urp_BridgeImpl::addError( char *pError )
{
    OUString message = OUString( RTL_CONSTASCII_USTRINGPARAM( "(tid=" ) );
    message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
    message += OUString::createFromAscii( ") " );
    message += OUString::createFromAscii( pError );
    MutexGuard guard( m_errorListMutex );
    m_lstErrors.push_back( message );
}

void urp_BridgeImpl::addError( const OUString & error )
{
    OUString message = OUString( RTL_CONSTASCII_USTRINGPARAM( "(tid=" ) );
    message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
    message += OUString::createFromAscii( ") " );
    message += error;
    MutexGuard guard( m_errorListMutex );
    m_lstErrors.push_back( message );
}

void urp_BridgeImpl::dumpErrors( FILE * f)
{
    MutexGuard guard( m_errorListMutex );
    for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
         ii != m_lstErrors.end() ;
         ++ii )
    {
        OString o = OUStringToOString( *ii , RTL_TEXTENCODING_UTF8 );
        fprintf( f,  "%s\n" , o.getStr() );
    }
}

OUString urp_BridgeImpl::getErrorsAsString( )
{
    MutexGuard guard( m_errorListMutex );
    OUString ret;
    for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
         ii != m_lstErrors.end() ;
         ++ii )
    {
        ret += *ii;
    }
    return ret;
}

}
<|endoftext|>