<commit_before>#ifndef IMQUE_ALLOCATOR_HH
#define IMQUE_ALLOCATOR_HH

#include <inttypes.h>
#include <cassert>

namespace imque {
  /**
   * 複数プロセス・複数スレッドで共有されているメモリ領域の割り当てに使えるアロケータ
   */
  class Allocator {
    /**
     * 補助構造体・クラス群
     */
    // 空き領域を管理するリンクリストのノード
    struct Node {
      uint32_t next;     // 次のノードのインデックス
      uint32_t count:30; // このノードが管理する空きチャンク数: sizeof(Chunk)*count = 割り当て可能なバイト数
      uint32_t status:2; // ノードのステータス

      enum STATUS {
        FREE      = 0, // 割り当て可能
        JOIN_HEAD = 1, // 後ろのノードとの結合待ち
        JOIN_TAIL = 2  // 前のノードとの結合待ち
      };

      uint64_t* uint64_ptr() { return reinterpret_cast<uint64_t*>(this); }
      uint64_t uint64() const { return *reinterpret_cast<const uint64_t*>(this); }
    } __attribute__((__packed__));

    // 実際に割り当てられるチャンク領域
    // インデックスが1のノードは、インデックスが1のチャンクを管理している
    struct Chunk {
      char padding[32];
    };

    // ノードの特定時点でのスナップショットを保持するクラス
    class Snapshot {
    public:
      Snapshot() : ptr_(NULL) {}
      Snapshot(Node* ptr) { update(ptr); }

      void update(Node* ptr) {
        ptr_ = ptr;

        uint64_t val = __sync_add_and_fetch(ptr->uint64_ptr(), 0); // atomicなロード関数がないので、その代替
        val_ = *reinterpret_cast<Node*>(&val);
      }

      const Node& node() const { return val_; }
      bool isModified() const { return ptr_->uint64() != val_.uint64(); }
      bool isJoinable(Node* head) const { return val_.next == index(head) + val_.count; }

      bool compare_and_swap(const Node& new_val) {
        if(isModified() == false &&
           __sync_bool_compare_and_swap(ptr_->uint64_ptr(), val_.uint64(), new_val.uint64())) {
          val_ = new_val;
          return true;
        }
        return false;
      }

      uint32_t index(Node* head) const { return ptr_ - head; }

    private:
      Node* ptr_;
      Node  val_;
    };

  private:
    static const uint32_t MAX_RETRY_COUNT = 512;

  public:
    // コンストラクタ
    //
    // region: 割り当て可能なメモリ領域
    // size: 割り当て可能なメモリ領域のバイト数
    //
    // [スペースに関する注意事項]
    // - 渡されたメモリ領域の内の 1/5 は空き領域の管理用に使用される。
    // - また、一つの割り当てごとに平均して 16byte のオーバーヘッドがある。
    Allocator(void* region, uint32_t size)
      : node_count_(size/(sizeof(Node)+sizeof(Chunk))),
        nodes_(reinterpret_cast<Node*>(region)),
        chunks_(reinterpret_cast<Chunk*>(nodes_+node_count_)) {
    }

    operator bool() const { return node_count_ > 2; }

    void init() {
      nodes_[0].next   = 1;
      nodes_[0].count  = 0;
      nodes_[0].status = Node::FREE;

      nodes_[1].next   = node_count_;
      nodes_[1].count  = node_count_-1;
      nodes_[1].status = Node::FREE;
    }

    // メモリ割り当てを行う。
    // 失敗した場合は 0 を、成功した場合は割り当てたメモリ領域参照用のID値を返す。
    // ※ ID値を ptr() メソッドに渡すことで、実際に利用可能なメモリ領域を取得できる
    uint32_t allocate(uint32_t size) {
      if(size == 0) {
        return 0; // invalid argument
      }

      uint32_t required_chunk_count = (size+sizeof(Chunk)-1) / sizeof(Chunk);

      Snapshot cand;
      if(find_candidate(IsEnoughChunk(required_chunk_count), cand) == false) {
        return 0; // out of memory
      }

      Node new_node = {cand.node().next,
                       cand.node().count - required_chunk_count,
                       Node::FREE};

      if(cand.compare_and_swap(new_node) == false) {
        return allocate(size);
      }

      uint32_t alloced_node_index = cand.index(nodes_) + new_node.count;
      nodes_[alloced_node_index].count = required_chunk_count;

      return alloced_node_index;
    }

    bool release(uint32_t index) {
      if(index == 0 || index >= node_count_) {
        assert(index < node_count_);
        return true;
      }

      uint32_t node_index = index;
      Snapshot pred;
      if(find_candidate(IsPredecessor(node_index), pred) == false) {
        return false;
      }

      assert(node_index >= pred.index(nodes_)+pred.node().count);
      assert(pred.node().status == Node::FREE);

      Node* node = &nodes_[node_index];
      Node new_pred_node = {0, 0, Node::FREE};
      if(node_index == pred.index(nodes_) + pred.node().count) {
        new_pred_node.next  = pred.node().next;
        new_pred_node.count = pred.node().count + node->count;
      } else {
        node->next   = pred.node().next;
        node->status = Node::FREE;

        new_pred_node.next  = node_index;
        new_pred_node.count = pred.node().count;
      }

      if(pred.compare_and_swap(new_pred_node) == false) {
        return release(index);
      }

      return true;
    }

    template<typename T>
    T* ptr(uint32_t index) const { return reinterpret_cast<T*>(chunks_ + index); }

    template<typename T>
    T* ptr(uint32_t index, uint32_t offset) const { return reinterpret_cast<T*>(ptr<char>(index)+offset); }

    // sizeバイトを利用(割当)可能にするためには、何バイト分の領域をコンストラクタに渡せば良いかを返す
    // ※ あくまでも目安である程度の誤差はある
    static size_t calc_need_byte_size(size_t size) {
      return (sizeof(Node)+sizeof(Chunk))*size / sizeof(Chunk);
    }

    // テスト用メソッド: 他と競合が発生するような状況で実行したら、結果が不正になることがあるので注意
    uint32_t allocatedNodeCount() const {
      uint32_t allocated_count = 0;

      Snapshot pred(&nodes_[0]);
      Snapshot curr;
      while(get_next_snapshot(pred, curr)) {
        allocated_count += (curr.node().next - curr.index(nodes_)) - curr.node().count;
        pred = curr;
      }
      allocated_count += (node_count_ - curr.node().next);

      return allocated_count;
    }

  private:
    // 現在のノードが、十分な(要求以上の)空き領域を管理しているかどうかを判定するためのコールバック
    class IsEnoughChunk {
    public:
      IsEnoughChunk(uint32_t required_chunk_count) : count_(required_chunk_count) {}

      bool operator()(const Snapshot& curr) const {
        // NOTE: '>='ではなく'>'で比較していることに注意
        //       ※ ノードの先頭部分も割り当ててしまうとリンクリストが壊れるので、そこは除外している
        return curr.node().status == Node::FREE && curr.node().count > count_;
      }

    private:
      const uint32_t count_;
    };

    // 現在のノードが、指定されたインデックス(のノード)の直前となるものかを判定するためのコールバック
    class IsPredecessor {
    public:
      IsPredecessor(uint32_t node_index) : node_index_(node_index) {}

      bool operator()(const Snapshot& curr) const {
        return node_index_ < curr.node().next;
      }

    private:
      uint32_t node_index_;
    };

    template<class Callback>
    bool find_candidate(const Callback& fn, Snapshot& node, uint32_t retry=0) {
      Snapshot head(&nodes_[0]);
      return find_candidate(fn, head, node, retry);
    }

    template<class Callback>
    bool find_candidate(const Callback& fn, Snapshot& pred, Snapshot& curr, uint32_t retry) {
      if(retry > MAX_RETRY_COUNT) {
        assert(retry <= MAX_RETRY_COUNT);
        return false;
      }

      if(pred.node().next == node_count_) { // 終端ノードに達した
        return false;
      }

      if(get_next_snapshot(pred, curr) == false ||
         update_node_status(pred, curr) == false ||
         join_nodes_if_need(pred, curr) == false) {
        usleep(retry+1);
        return find_candidate(fn, curr, retry+1);
      }

      if(fn(curr)) {
        return true;
      }

      pred = curr;
      return find_candidate(fn, pred, curr, retry);
    }

    // predの次のノード(のスナップショット)を取得して curr に設定する
    bool get_next_snapshot(Snapshot& pred, Snapshot& curr) const {
      if(pred.node().next == node_count_) {
        return false;
      }

      curr.update(&nodes_[pred.node().next]);

      if(pred.isModified()) {
        return false;
      }

      assert(! (curr.node().status & Node::JOIN_HEAD && curr.isJoinable(nodes_)==false));

      if((! pred.node().status & Node::JOIN_HEAD) && curr.node().status & Node::JOIN_TAIL) {
        // 前半のノードが結合可能状態になっていないのに、後半のノードだけ結合可能にマークされている
        // => pred がその一つ前のノードと結合されてしまった場合は、ここに来る可能性あり
        //    1) predを取得 => predにはNode::JOIN_TAILマークのみが付いている
        //    2) predとその前のノード(predpred)が結合 => この時点でpredの内容は実質無効になる (ただし値は変わらない)
        //    3) predpredとcurrは結合可能 => currにNode::JOIN_TAILマークが付く
        //    4) predからcurrを取得 => predは無効になっているけど、値は以前から変わっていないのでそれを検出できない
        //       => この時点で、上のif文を満たす条件が成立する
        return false;
      }

      return true;
    }

    bool update_node_status(Snapshot& pred, Snapshot& curr) {
      if(pred.isJoinable(nodes_) == false) {
        return true;
      }

      Node new_pred_node = {pred.node().next,
                            pred.node().count,
                            pred.node().status | Node::JOIN_HEAD};
      if(pred.compare_and_swap(new_pred_node) == false) {
        return false;
      }

      Node new_curr_node = {curr.node().next,
                            curr.node().count,
                            curr.node().status | Node::JOIN_TAIL};
      if(curr.compare_and_swap(new_curr_node) == false) {
        return false;
      }

      return true;
    }

    bool join_nodes_if_need(Snapshot& pred, Snapshot& curr) {
      if(! (pred.node().status & Node::JOIN_HEAD &&
            curr.node().status & Node::JOIN_TAIL)) {
        assert(!(curr.node().status & Node::JOIN_TAIL));
        return true;
      }
      assert(pred.node().next == curr.index(nodes_));
      assert(pred.isJoinable(nodes_));
     uint32_t curr_status = curr.node().status;
      Node new_pred_node = {curr.node().next,
                            pred.node().count + curr.node().count,
                            (pred.node().status & ~Node::JOIN_HEAD) |
                            (curr.node().status & ~Node::JOIN_TAIL)};
      if(pred.compare_and_swap(new_pred_node) == false) {
        return false;
      }
      if(! (curr_status & Node::JOIN_HEAD)) {
        assert(! (pred.node().status & Node::JOIN_HEAD));
      }
      curr = pred;
      return true;
    }

  private:
    const uint32_t node_count_;
    Node*          nodes_;
    Chunk*         chunks_;
  };
}

#endif
<commit_msg>TODOコメント追加<commit_after>#ifndef IMQUE_ALLOCATOR_HH
#define IMQUE_ALLOCATOR_HH

#include <inttypes.h>
#include <cassert>

namespace imque {
  /**
   * 複数プロセス・複数スレッドで共有されているメモリ領域の割り当てに使えるアロケータ
   */
  // TODO: Chunkのサイズはtemplateで指定可能にしても良いかもしれない
  class Allocator {
    /**
     * 補助構造体・クラス群
     */
    // 空き領域を管理するリンクリストのノード
    struct Node {
      uint32_t next;     // 次のノードのインデックス
      uint32_t count:30; // このノードが管理する空きチャンク数: sizeof(Chunk)*count = 割り当て可能なバイト数
      uint32_t status:2; // ノードのステータス

      enum STATUS {
        FREE      = 0, // 割り当て可能
        JOIN_HEAD = 1, // 後ろのノードとの結合待ち
        JOIN_TAIL = 2  // 前のノードとの結合待ち
      };

      uint64_t* uint64_ptr() { return reinterpret_cast<uint64_t*>(this); }
      uint64_t uint64() const { return *reinterpret_cast<const uint64_t*>(this); }
    } __attribute__((__packed__));

    // 実際に割り当てられるチャンク領域
    // インデックスが1のノードは、インデックスが1のチャンクを管理している
    struct Chunk {
      char padding[32];
    };

    // ノードの特定時点でのスナップショットを保持するクラス
    class Snapshot {
    public:
      Snapshot() : ptr_(NULL) {}
      Snapshot(Node* ptr) { update(ptr); }

      void update(Node* ptr) {
        ptr_ = ptr;

        uint64_t val = __sync_add_and_fetch(ptr->uint64_ptr(), 0); // atomicなロード関数がないので、その代替
        val_ = *reinterpret_cast<Node*>(&val);
      }

      const Node& node() const { return val_; }
      bool isModified() const { return ptr_->uint64() != val_.uint64(); }
      bool isJoinable(Node* head) const { return val_.next == index(head) + val_.count; }

      bool compare_and_swap(const Node& new_val) {
        if(isModified() == false &&
           __sync_bool_compare_and_swap(ptr_->uint64_ptr(), val_.uint64(), new_val.uint64())) {
          val_ = new_val;
          return true;
        }
        return false;
      }

      uint32_t index(Node* head) const { return ptr_ - head; }

    private:
      Node* ptr_;
      Node  val_;
    };

  private:
    static const uint32_t MAX_RETRY_COUNT = 512;

  public:
    // コンストラクタ
    //
    // region: 割り当て可能なメモリ領域
    // size: 割り当て可能なメモリ領域のバイト数
    //
    // [スペースに関する注意事項]
    // - 渡されたメモリ領域の内の 1/5 は空き領域の管理用に使用される。
    // - また、一つの割り当てごとに平均して 16byte のオーバーヘッドがある。
    Allocator(void* region, uint32_t size)
      : node_count_(size/(sizeof(Node)+sizeof(Chunk))),
        nodes_(reinterpret_cast<Node*>(region)),
        chunks_(reinterpret_cast<Chunk*>(nodes_+node_count_)) {
    }

    operator bool() const { return node_count_ > 2; }

    void init() {
      nodes_[0].next   = 1;
      nodes_[0].count  = 0;
      nodes_[0].status = Node::FREE;

      nodes_[1].next   = node_count_;
      nodes_[1].count  = node_count_-1;
      nodes_[1].status = Node::FREE;
    }

    // メモリ割り当てを行う。
    // 失敗した場合は 0 を、成功した場合は割り当てたメモリ領域参照用のID値を返す。
    // ※ ID値を ptr() メソッドに渡すことで、実際に利用可能なメモリ領域を取得できる
    uint32_t allocate(uint32_t size) {
      if(size == 0) {
        return 0; // invalid argument
      }

      uint32_t required_chunk_count = (size+sizeof(Chunk)-1) / sizeof(Chunk);

      Snapshot cand;
      if(find_candidate(IsEnoughChunk(required_chunk_count), cand) == false) {
        return 0; // out of memory
      }

      Node new_node = {cand.node().next,
                       cand.node().count - required_chunk_count,
                       Node::FREE};

      if(cand.compare_and_swap(new_node) == false) {
        return allocate(size);
      }

      uint32_t alloced_node_index = cand.index(nodes_) + new_node.count;
      nodes_[alloced_node_index].count = required_chunk_count;

      return alloced_node_index;
    }

    bool release(uint32_t index) {
      if(index == 0 || index >= node_count_) {
        assert(index < node_count_);
        return true;
      }

      uint32_t node_index = index;
      Snapshot pred;
      if(find_candidate(IsPredecessor(node_index), pred) == false) {
        return false;
      }

      assert(node_index >= pred.index(nodes_)+pred.node().count);
      assert(pred.node().status == Node::FREE);

      Node* node = &nodes_[node_index];
      Node new_pred_node = {0, 0, Node::FREE};
      if(node_index == pred.index(nodes_) + pred.node().count) {
        new_pred_node.next  = pred.node().next;
        new_pred_node.count = pred.node().count + node->count;
      } else {
        node->next   = pred.node().next;
        node->status = Node::FREE;

        new_pred_node.next  = node_index;
        new_pred_node.count = pred.node().count;
      }

      if(pred.compare_and_swap(new_pred_node) == false) {
        return release(index);
      }

      return true;
    }

    template<typename T>
    T* ptr(uint32_t index) const { return reinterpret_cast<T*>(chunks_ + index); }

    template<typename T>
    T* ptr(uint32_t index, uint32_t offset) const { return reinterpret_cast<T*>(ptr<char>(index)+offset); }

    // sizeバイトを利用(割当)可能にするためには、何バイト分の領域をコンストラクタに渡せば良いかを返す
    // ※ あくまでも目安である程度の誤差はある
    static size_t calc_need_byte_size(size_t size) {
      return (sizeof(Node)+sizeof(Chunk))*size / sizeof(Chunk);
    }

    // テスト用メソッド: 他と競合が発生するような状況で実行したら、結果が不正になることがあるので注意
    uint32_t allocatedNodeCount() const {
      uint32_t allocated_count = 0;

      Snapshot pred(&nodes_[0]);
      Snapshot curr;
      while(get_next_snapshot(pred, curr)) {
        allocated_count += (curr.node().next - curr.index(nodes_)) - curr.node().count;
        pred = curr;
      }
      allocated_count += (node_count_ - curr.node().next);

      return allocated_count;
    }

  private:
    // 現在のノードが、十分な(要求以上の)空き領域を管理しているかどうかを判定するためのコールバック
    class IsEnoughChunk {
    public:
      IsEnoughChunk(uint32_t required_chunk_count) : count_(required_chunk_count) {}

      bool operator()(const Snapshot& curr) const {
        // NOTE: '>='ではなく'>'で比較していることに注意
        //       ※ ノードの先頭部分も割り当ててしまうとリンクリストが壊れるので、そこは除外している
        return curr.node().status == Node::FREE && curr.node().count > count_;
      }

    private:
      const uint32_t count_;
    };

    // 現在のノードが、指定されたインデックス(のノード)の直前となるものかを判定するためのコールバック
    class IsPredecessor {
    public:
      IsPredecessor(uint32_t node_index) : node_index_(node_index) {}

      bool operator()(const Snapshot& curr) const {
        return node_index_ < curr.node().next;
      }

    private:
      uint32_t node_index_;
    };

    template<class Callback>
    bool find_candidate(const Callback& fn, Snapshot& node, uint32_t retry=0) {
      Snapshot head(&nodes_[0]);
      return find_candidate(fn, head, node, retry);
    }

    template<class Callback>
    bool find_candidate(const Callback& fn, Snapshot& pred, Snapshot& curr, uint32_t retry) {
      if(retry > MAX_RETRY_COUNT) {
        assert(retry <= MAX_RETRY_COUNT);
        return false;
      }

      if(pred.node().next == node_count_) { // 終端ノードに達した
        return false;
      }

      if(get_next_snapshot(pred, curr) == false ||
         update_node_status(pred, curr) == false ||
         join_nodes_if_need(pred, curr) == false) {
        usleep(retry+1);
        return find_candidate(fn, curr, retry+1);
      }

      if(fn(curr)) {
        return true;
      }

      pred = curr;
      return find_candidate(fn, pred, curr, retry);
    }

    // predの次のノード(のスナップショット)を取得して curr に設定する
    bool get_next_snapshot(Snapshot& pred, Snapshot& curr) const {
      if(pred.node().next == node_count_) {
        return false;
      }

      curr.update(&nodes_[pred.node().next]);

      if(pred.isModified()) {
        return false;
      }

      assert(! (curr.node().status & Node::JOIN_HEAD && curr.isJoinable(nodes_)==false));

      if((! pred.node().status & Node::JOIN_HEAD) && curr.node().status & Node::JOIN_TAIL) {
        // 前半のノードが結合可能状態になっていないのに、後半のノードだけ結合可能にマークされている
        // => pred がその一つ前のノードと結合されてしまった場合は、ここに来る可能性あり
        //    1) predを取得 => predにはNode::JOIN_TAILマークのみが付いている
        //    2) predとその前のノード(predpred)が結合 => この時点でpredの内容は実質無効になる (ただし値は変わらない)
        //    3) predpredとcurrは結合可能 => currにNode::JOIN_TAILマークが付く
        //    4) predからcurrを取得 => predは無効になっているけど、値は以前から変わっていないのでそれを検出できない
        //       => この時点で、上のif文を満たす条件が成立する
        return false;
      }

      return true;
    }

    bool update_node_status(Snapshot& pred, Snapshot& curr) {
      if(pred.isJoinable(nodes_) == false) {
        return true;
      }

      Node new_pred_node = {pred.node().next,
                            pred.node().count,
                            pred.node().status | Node::JOIN_HEAD};
      if(pred.compare_and_swap(new_pred_node) == false) {
        return false;
      }

      Node new_curr_node = {curr.node().next,
                            curr.node().count,
                            curr.node().status | Node::JOIN_TAIL};
      if(curr.compare_and_swap(new_curr_node) == false) {
        return false;
      }

      return true;
    }

    bool join_nodes_if_need(Snapshot& pred, Snapshot& curr) {
      if(! (pred.node().status & Node::JOIN_HEAD &&
            curr.node().status & Node::JOIN_TAIL)) {
        assert(!(curr.node().status & Node::JOIN_TAIL));
        return true;
      }
      assert(pred.node().next == curr.index(nodes_));
      assert(pred.isJoinable(nodes_));

      uint32_t curr_status = curr.node().status;
      Node new_pred_node = {curr.node().next,
                            pred.node().count + curr.node().count,
                            (pred.node().status & ~Node::JOIN_HEAD) |
                            (curr.node().status & ~Node::JOIN_TAIL)};
      if(pred.compare_and_swap(new_pred_node) == false) {
        return false;
      }
      if(! (curr_status & Node::JOIN_HEAD)) {
        assert(! (pred.node().status & Node::JOIN_HEAD));
      }
      curr = pred;
      return true;
    }

  private:
    const uint32_t node_count_;
    Node*          nodes_;
    Chunk*         chunks_;
  };
}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: pe_tydef.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: np $ $Date: 2002-03-08 14:45: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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef ADC_CPP_PE_TYDEF_HXX
#define ADC_CPP_PE_TYDEF_HXX

// USED SERVICES
    // BASE CLASSES
#include "cpp_pe.hxx"
    // COMPONENTS
#include <semantic/callf.hxx>
#include <semantic/sub_peu.hxx>
    // PARAMETERS

namespace cpp {

class PE_Type;

class PE_Typedef : public cpp::Cpp_PE
{
  public:
    enum E_State
    {
        start,
        expectName,
        afterName,
        size_of_states
    };
                        PE_Typedef(
                            Cpp_PE *        i_pParent );
                        ~PE_Typedef();

    virtual void        Call_Handler(
                            const cpp::Token &  i_rTok );
  private:
    typedef SubPe< PE_Typedef, PE_Type >        SP_Type;
    typedef SubPeUse< PE_Typedef, PE_Type>  SPU_Type;

    void                Setup_StatusFunctions();
    virtual void        InitData();
    virtual void        TransferData();
    void                Hdl_SyntaxError( const char *);

    void                SpReturn_Type();

    void                On_start_typedef( const char * );
    void                On_expectName_Identifier( const char * );
    void                On_afterName_Semicolon( const char * );

    // DATA
    Dyn< PeStatusArray<PE_Typedef> >
                        pStati;
    Dyn<SP_Type>        pSpType;
    Dyn<SPU_Type>       pSpuType;

    udmstri             sName;
    ary::Tid            nType;
};

// IMPLEMENTATION

}   // namespace cpp

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.1.1.1.146); FILE MERGED 2005/09/05 13:11:50 rt 1.1.1.1.146.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pe_tydef.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 18:29:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef ADC_CPP_PE_TYDEF_HXX
#define ADC_CPP_PE_TYDEF_HXX

// USED SERVICES
    // BASE CLASSES
#include "cpp_pe.hxx"
    // COMPONENTS
#include <semantic/callf.hxx>
#include <semantic/sub_peu.hxx>
    // PARAMETERS

namespace cpp {

class PE_Type;

class PE_Typedef : public cpp::Cpp_PE
{
  public:
    enum E_State
    {
        start,
        expectName,
        afterName,
        size_of_states
    };
                        PE_Typedef(
                            Cpp_PE *        i_pParent );
                        ~PE_Typedef();

    virtual void        Call_Handler(
                            const cpp::Token &  i_rTok );
  private:
    typedef SubPe< PE_Typedef, PE_Type >        SP_Type;
    typedef SubPeUse< PE_Typedef, PE_Type>  SPU_Type;

    void                Setup_StatusFunctions();
    virtual void        InitData();
    virtual void        TransferData();
    void                Hdl_SyntaxError( const char *);

    void                SpReturn_Type();

    void                On_start_typedef( const char * );
    void                On_expectName_Identifier( const char * );
    void                On_afterName_Semicolon( const char * );

    // DATA
    Dyn< PeStatusArray<PE_Typedef> >
                        pStati;
    Dyn<SP_Type>        pSpType;
    Dyn<SPU_Type>       pSpuType;

    udmstri             sName;
    ary::Tid            nType;
};

// IMPLEMENTATION

}   // namespace cpp

#endif

<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html 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 notices for more information.

=========================================================================*/

#include <mitkGL.h>
#include "mitkGeometry2DDataMapper2D.h"

#include "mitkBaseRenderer.h"

#include "mitkPlaneGeometry.h"

#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkSmartPointerProperty.h"

#include "mitkGeometry2DDataToSurfaceFilter.h"
#include "mitkSurfaceMapper2D.h"

//##ModelId=3E639E100243
mitk::Geometry2DDataMapper2D::Geometry2DDataMapper2D() : m_SurfaceMapper(NULL)
{
}

//##ModelId=3E639E100257
mitk::Geometry2DDataMapper2D::~Geometry2DDataMapper2D()
{
}

//##ModelId=3E6423D20341
const mitk::Geometry2DData *mitk::Geometry2DDataMapper2D::GetInput(void)
{
  return static_cast<const mitk::Geometry2DData * > ( GetData() );
}

void mitk::Geometry2DDataMapper2D::SetDataIteratorToOtherGeometry2Ds(const mitk::DataTreeIteratorBase* iterator)
{
  if(m_IteratorToOtherGeometry2Ds != iterator)
  {
    m_IteratorToOtherGeometry2Ds = iterator;
    Modified();
  }
}

void mitk::Geometry2DDataMapper2D::GenerateData()
{
  //collect all Geometry2DData's accessible by traversing m_IteratorToOtherGeometry2Ds
  m_OtherGeometry2Ds.clear();
  if(m_IteratorToOtherGeometry2Ds.IsNull()) return;

  mitk::DataTreeIteratorClone it = m_IteratorToOtherGeometry2Ds;
  while(!it->IsAtEnd())
  {
    if(it->Get().IsNotNull())
    {
      mitk::BaseData* data = it->Get()->GetData();
      if(data != NULL)
      {
        mitk::Geometry2DData* geometry2dData = dynamic_cast<mitk::Geometry2DData*>(data);
        if(geometry2dData!=NULL)
        {
          mitk::PlaneGeometry* planegeometry = dynamic_cast<mitk::PlaneGeometry*>(geometry2dData->GetGeometry2D());
          if(planegeometry!=NULL)
            m_OtherGeometry2Ds.push_back(it->Get());
        }
      }
    }
    ++it;
  }
}

//##ModelId=3E67D77A0109
void mitk::Geometry2DDataMapper2D::Paint(mitk::BaseRenderer * renderer)
{
  if(IsVisible(renderer)==false) return;

  //	@FIXME: Logik fuer update
  bool updateNeccesary=true;

  if (updateNeccesary) {
    // ok, das ist aus GenerateData kopiert

    mitk::Geometry2DData::Pointer input  = const_cast<mitk::Geometry2DData*>(this->GetInput());

    //intersecting with ourself?
    if(input->GetGeometry2D()==renderer->GetCurrentWorldGeometry2D())
      return; //do nothing!

    PlaneGeometry::ConstPointer input_planeGeometry = dynamic_cast<const PlaneGeometry *>(input->GetGeometry2D());
    PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>(renderer->GetCurrentWorldGeometry2D());

    if(worldPlaneGeometry.IsNotNull() && (input_planeGeometry.IsNotNull()))
    {
      mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry();
      assert(displayGeometry);

      //calculate intersection of the plane data with the border of the world geometry rectangle
      Point2D lineFrom, lineTo;
      bool intersecting = worldPlaneGeometry->IntersectWithPlane2D( input_planeGeometry, lineFrom, lineTo ) > 0;

      if(intersecting)
      {
        mitk::Line<ScalarType, 2> line, tmpLine;
        line.SetPoints(lineFrom, lineTo);

        displayGeometry->WorldToDisplay(lineFrom, lineFrom);
        displayGeometry->WorldToDisplay(lineTo, lineTo);
        Vector2D l;
        l=lineTo-lineFrom;
        ScalarType lengthInDisplayUnits = l.GetNorm();

        std::vector<ScalarType> lineParams;
        lineParams.reserve(m_OtherGeometry2Ds.size()+2);
        lineParams.push_back(0);
        lineParams.push_back(1);

        Vector2D d, dOrth;
        NodesVectorType::iterator otherPlanesIt = m_OtherGeometry2Ds.begin();
        NodesVectorType::iterator otherPlanesEnd = m_OtherGeometry2Ds.end();
        while(otherPlanesIt != otherPlanesEnd)
        {
          mitk::PlaneGeometry* otherPlane = static_cast<PlaneGeometry*>(static_cast<Geometry2DData*>((*otherPlanesIt)->GetData())->GetGeometry2D());
          if(otherPlane != input_planeGeometry)
          {
            bool otherIntersecting = worldPlaneGeometry->IntersectWithPlane2D( otherPlane, lineFrom, lineTo ) > 0;
            if(otherIntersecting)
            {
              tmpLine.SetPoints(lineFrom, lineTo);
              d = tmpLine.GetDirection();
              dOrth[0] = -d[1]; dOrth[1] = d[0];
              ScalarType t = (tmpLine.GetPoint1()-line.GetPoint1())*(dOrth);
              ScalarType norm = line.GetDirection()*dOrth;
              if(fabs(norm) > mitk::eps)
              {
                t /= norm;
                lineParams.push_back(t);
              }
            }
          }

          ++otherPlanesIt;
        }

        //apply color and opacity read from the PropertyList
        ApplyProperties(renderer);

        ScalarType gapSizeInPixel = 10;
        ScalarType gapSizeInParamUnits = 1.0/lengthInDisplayUnits*gapSizeInPixel;

        std::sort(lineParams.begin(), lineParams.end());

        Point2D p1, p2;
        ScalarType p1Param, p2Param;

        p1Param = lineParams[0];
        p1 = line.GetPoint(p1Param);
        displayGeometry->WorldToDisplay(p1, p1);

        unsigned int i, preLastLineParam = lineParams.size()-1;
        for(i=1; i < preLastLineParam; ++i)
        {
          p2Param = lineParams[i]-gapSizeInParamUnits*0.5;
          p2 = line.GetPoint(p2Param);
          if(p2Param > p1Param)
          {
            //convert intersection points (until now mm) to display coordinates (units )
            displayGeometry->WorldToDisplay(p2, p2);

            //draw
            glBegin (GL_LINES);
            glVertex2f(p1[0],p1[1]);
            glVertex2f(p2[0],p2[1]);
            glEnd ();
          }
          p1Param = p2Param+gapSizeInParamUnits;
          p1 = line.GetPoint(p1Param);
          displayGeometry->WorldToDisplay(p1, p1);
        }
        //draw last line segment
        p2Param = lineParams[i];
        p2 = line.GetPoint(p2Param);
        displayGeometry->WorldToDisplay(p2, p2);
        glBegin (GL_LINES);
        glVertex2f(p1[0],p1[1]);
        glVertex2f(p2[0],p2[1]);
        glEnd ();
      }
    }
    else
    {
      mitk::Geometry2DDataToSurfaceFilter::Pointer surfaceCreator;
      mitk::SmartPointerProperty::Pointer surfacecreatorprop;
      surfacecreatorprop=dynamic_cast<mitk::SmartPointerProperty*>(GetDataTreeNode()->GetProperty("surfacegeometry", renderer).GetPointer());
      if( (surfacecreatorprop.IsNull()) ||
          (surfacecreatorprop->GetSmartPointer().IsNull()) ||
          ((surfaceCreator=dynamic_cast<mitk::Geometry2DDataToSurfaceFilter*>(surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull())
        )
      {
        surfaceCreator = mitk::Geometry2DDataToSurfaceFilter::New();
        surfacecreatorprop=new mitk::SmartPointerProperty(surfaceCreator);
        surfaceCreator->PlaceByGeometryOn();
        GetDataTreeNode()->SetProperty("surfacegeometry", surfacecreatorprop);
      }

      surfaceCreator->SetInput(input);

      int res;
      bool usegeometryparametricbounds=true;
      if(GetDataTreeNode()->GetIntProperty("xresolution", res, renderer))
      {
        surfaceCreator->SetXResolution(res);
        usegeometryparametricbounds=false;
      }
      if(GetDataTreeNode()->GetIntProperty("yresolution", res, renderer))
      {
        surfaceCreator->SetYResolution(res);
        usegeometryparametricbounds=false;
      }
      surfaceCreator->SetUseGeometryParametricBounds(usegeometryparametricbounds);

      surfaceCreator->Update(); //@FIXME ohne das crash

      if(m_SurfaceMapper.IsNull())
        m_SurfaceMapper=mitk::SurfaceMapper2D::New();
      m_SurfaceMapper->SetSurface(surfaceCreator->GetOutput());
      m_SurfaceMapper->SetDataTreeNode(GetDataTreeNode());

      m_SurfaceMapper->Paint(renderer);
    }
  }
}
<commit_msg>COMP: Added missing #include<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html 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 notices for more information.

=========================================================================*/

#include <mitkGL.h>
#include "mitkGeometry2DDataMapper2D.h"
#include "mitkLine.h"
#include "mitkBaseRenderer.h"

#include "mitkPlaneGeometry.h"

#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkSmartPointerProperty.h"

#include "mitkGeometry2DDataToSurfaceFilter.h"
#include "mitkSurfaceMapper2D.h"

//##ModelId=3E639E100243
mitk::Geometry2DDataMapper2D::Geometry2DDataMapper2D() : m_SurfaceMapper(NULL)
{
}

//##ModelId=3E639E100257
mitk::Geometry2DDataMapper2D::~Geometry2DDataMapper2D()
{
}

//##ModelId=3E6423D20341
const mitk::Geometry2DData *mitk::Geometry2DDataMapper2D::GetInput(void)
{
  return static_cast<const mitk::Geometry2DData * > ( GetData() );
}

void mitk::Geometry2DDataMapper2D::SetDataIteratorToOtherGeometry2Ds(const mitk::DataTreeIteratorBase* iterator)
{
  if(m_IteratorToOtherGeometry2Ds != iterator)
  {
    m_IteratorToOtherGeometry2Ds = iterator;
    Modified();
  }
}

void mitk::Geometry2DDataMapper2D::GenerateData()
{
  //collect all Geometry2DData's accessible by traversing m_IteratorToOtherGeometry2Ds
  m_OtherGeometry2Ds.clear();
  if(m_IteratorToOtherGeometry2Ds.IsNull()) return;

  mitk::DataTreeIteratorClone it = m_IteratorToOtherGeometry2Ds;
  while(!it->IsAtEnd())
  {
    if(it->Get().IsNotNull())
    {
      mitk::BaseData* data = it->Get()->GetData();
      if(data != NULL)
      {
        mitk::Geometry2DData* geometry2dData = dynamic_cast<mitk::Geometry2DData*>(data);
        if(geometry2dData!=NULL)
        {
          mitk::PlaneGeometry* planegeometry = dynamic_cast<mitk::PlaneGeometry*>(geometry2dData->GetGeometry2D());
          if(planegeometry!=NULL)
            m_OtherGeometry2Ds.push_back(it->Get());
        }
      }
    }
    ++it;
  }
}

//##ModelId=3E67D77A0109
void mitk::Geometry2DDataMapper2D::Paint(mitk::BaseRenderer * renderer)
{
  if(IsVisible(renderer)==false) return;

  //	@FIXME: Logik fuer update
  bool updateNeccesary=true;

  if (updateNeccesary) {
    // ok, das ist aus GenerateData kopiert

    mitk::Geometry2DData::Pointer input  = const_cast<mitk::Geometry2DData*>(this->GetInput());

    //intersecting with ourself?
    if(input->GetGeometry2D()==renderer->GetCurrentWorldGeometry2D())
      return; //do nothing!

    PlaneGeometry::ConstPointer input_planeGeometry = dynamic_cast<const PlaneGeometry *>(input->GetGeometry2D());
    PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>(renderer->GetCurrentWorldGeometry2D());

    if(worldPlaneGeometry.IsNotNull() && (input_planeGeometry.IsNotNull()))
    {
      mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry();
      assert(displayGeometry);

      //calculate intersection of the plane data with the border of the world geometry rectangle
      Point2D lineFrom, lineTo;
      bool intersecting = worldPlaneGeometry->IntersectWithPlane2D( input_planeGeometry, lineFrom, lineTo ) > 0;

      if(intersecting)
      {
        mitk::Line<ScalarType, 2> line, tmpLine;
        line.SetPoints(lineFrom, lineTo);

        displayGeometry->WorldToDisplay(lineFrom, lineFrom);
        displayGeometry->WorldToDisplay(lineTo, lineTo);
        Vector2D l;
        l=lineTo-lineFrom;
        ScalarType lengthInDisplayUnits = l.GetNorm();

        std::vector<ScalarType> lineParams;
        lineParams.reserve(m_OtherGeometry2Ds.size()+2);
        lineParams.push_back(0);
        lineParams.push_back(1);

        Vector2D d, dOrth;
        NodesVectorType::iterator otherPlanesIt = m_OtherGeometry2Ds.begin();
        NodesVectorType::iterator otherPlanesEnd = m_OtherGeometry2Ds.end();
        while(otherPlanesIt != otherPlanesEnd)
        {
          mitk::PlaneGeometry* otherPlane = static_cast<PlaneGeometry*>(static_cast<Geometry2DData*>((*otherPlanesIt)->GetData())->GetGeometry2D());
          if(otherPlane != input_planeGeometry)
          {
            bool otherIntersecting = worldPlaneGeometry->IntersectWithPlane2D( otherPlane, lineFrom, lineTo ) > 0;
            if(otherIntersecting)
            {
              tmpLine.SetPoints(lineFrom, lineTo);
              d = tmpLine.GetDirection();
              dOrth[0] = -d[1]; dOrth[1] = d[0];
              ScalarType t = (tmpLine.GetPoint1()-line.GetPoint1())*(dOrth);
              ScalarType norm = line.GetDirection()*dOrth;
              if(fabs(norm) > mitk::eps)
              {
                t /= norm;
                lineParams.push_back(t);
              }
            }
          }

          ++otherPlanesIt;
        }

        //apply color and opacity read from the PropertyList
        ApplyProperties(renderer);

        ScalarType gapSizeInPixel = 10;
        ScalarType gapSizeInParamUnits = 1.0/lengthInDisplayUnits*gapSizeInPixel;

        std::sort(lineParams.begin(), lineParams.end());

        Point2D p1, p2;
        ScalarType p1Param, p2Param;

        p1Param = lineParams[0];
        p1 = line.GetPoint(p1Param);
        displayGeometry->WorldToDisplay(p1, p1);

        unsigned int i, preLastLineParam = lineParams.size()-1;
        for(i=1; i < preLastLineParam; ++i)
        {
          p2Param = lineParams[i]-gapSizeInParamUnits*0.5;
          p2 = line.GetPoint(p2Param);
          if(p2Param > p1Param)
          {
            //convert intersection points (until now mm) to display coordinates (units )
            displayGeometry->WorldToDisplay(p2, p2);

            //draw
            glBegin (GL_LINES);
            glVertex2f(p1[0],p1[1]);
            glVertex2f(p2[0],p2[1]);
            glEnd ();
          }
          p1Param = p2Param+gapSizeInParamUnits;
          p1 = line.GetPoint(p1Param);
          displayGeometry->WorldToDisplay(p1, p1);
        }
        //draw last line segment
        p2Param = lineParams[i];
        p2 = line.GetPoint(p2Param);
        displayGeometry->WorldToDisplay(p2, p2);
        glBegin (GL_LINES);
        glVertex2f(p1[0],p1[1]);
        glVertex2f(p2[0],p2[1]);
        glEnd ();
      }
    }
    else
    {
      mitk::Geometry2DDataToSurfaceFilter::Pointer surfaceCreator;
      mitk::SmartPointerProperty::Pointer surfacecreatorprop;
      surfacecreatorprop=dynamic_cast<mitk::SmartPointerProperty*>(GetDataTreeNode()->GetProperty("surfacegeometry", renderer).GetPointer());
      if( (surfacecreatorprop.IsNull()) ||
          (surfacecreatorprop->GetSmartPointer().IsNull()) ||
          ((surfaceCreator=dynamic_cast<mitk::Geometry2DDataToSurfaceFilter*>(surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull())
        )
      {
        surfaceCreator = mitk::Geometry2DDataToSurfaceFilter::New();
        surfacecreatorprop=new mitk::SmartPointerProperty(surfaceCreator);
        surfaceCreator->PlaceByGeometryOn();
        GetDataTreeNode()->SetProperty("surfacegeometry", surfacecreatorprop);
      }

      surfaceCreator->SetInput(input);

      int res;
      bool usegeometryparametricbounds=true;
      if(GetDataTreeNode()->GetIntProperty("xresolution", res, renderer))
      {
        surfaceCreator->SetXResolution(res);
        usegeometryparametricbounds=false;
      }
      if(GetDataTreeNode()->GetIntProperty("yresolution", res, renderer))
      {
        surfaceCreator->SetYResolution(res);
        usegeometryparametricbounds=false;
      }
      surfaceCreator->SetUseGeometryParametricBounds(usegeometryparametricbounds);

      surfaceCreator->Update(); //@FIXME ohne das crash

      if(m_SurfaceMapper.IsNull())
        m_SurfaceMapper=mitk::SurfaceMapper2D::New();
      m_SurfaceMapper->SetSurface(surfaceCreator->GetOutput());
      m_SurfaceMapper->SetDataTreeNode(GetDataTreeNode());

      m_SurfaceMapper->Paint(renderer);
    }
  }
}
<|endoftext|>


<commit_before>#pragma once
#include<string>
#include<cstdint>
#include<fstream>
#include<array>
#include<vector>
#include<algorithm>
namespace bmslib {

	std::vector<std::string> split_naive(const std::string &s, char delim) {
		std::vector<std::string> elems;
		std::string item;
		for (char ch : s) {
			if (ch == delim) {
				if (!item.empty())
					elems.push_back(item);
				item.clear();
			}
			else {
				item += ch;
			}
		}
		if (!item.empty())
			elems.push_back(item);
		return elems;
	}

	std::string trim(const std::string& string, const char* trimCharacterList = " \t\v\r")
	{
		std::string result;

		// g镶ȊOʒu܂B
		std::string::size_type left = string.find_first_not_of(trimCharacterList);

		if (left != std::string::npos)
		{
			// g镶ȊOꍇ́A悤ɉE܂B
			std::string::size_type right = string.find_last_not_of(trimCharacterList);

			// ߂l肵܂Bł͉E猟ĂAg镶ȊOK݂̂ŔsvłB
			result = string.substr(left, right - left + 1);
		}

		return result;
	}

	enum Player {
		None,
		Single,
		Couple,
		Double,
		Battle
	};

	enum Rank {
		Veryhard,
		Hard,
		Normal,
		Easy
	};

	struct Header
	{
		Player player;
		std::string genre, title, artist, stagefile;
		double bpm;
		unsigned int level, volume, total;
		Rank rank;
		std::array<std::string, 575> wav, bmp;
	};

	enum Channel {
		None1,
		Backwav,
		Shortening,
		Changebpm,
		Bga,
		None2,
		Pooranim,
		Bgalayer,
		exBPM,
		Stop,
		None3,
		Key1,
		Key2,
		Key3,
		Key4,
		Key5,
		Key6,
		Key7,
		Key8,
		Key9,
		None4,
		Key1_2P,
		Key2_2P,
		Key3_2P,
		Key4_2P,
		Key5_2P,
		Key6_2P,
		Key7_2P,
		Key8_2P,
		Key9_2P,
	};

	struct Bar {
		Channel channel;
		int backchorus; // Set WAV number
		int length = 1000; // Default Value = 1000
		std::vector<double> bpms;
		int bga, pooranim, layerbga;
		std::array<std::vector<bool>, 9> objects;
	};

	struct Object {
		int data;
		long time;
		Channel channel;

		bool operator<(const Object obj) {
			return time < obj.time;
		}
	};

	struct Bms {
		Header header;
		std::vector<Object> bar;
	};

	Bms load_data(std::string bmsfile) {
		std::ifstream file(bmsfile);
		std::string line;
		if (file.fail())
		{
			return Bms();
		}
		Bms bms;
		while (getline(file, line))
		{
			trim(line);
			if (line[0] == '#') {
				if (isdigit(line[1])) {
					auto str = split_naive(line,':');

					auto command = str[0];
					auto data = str[1];

					if (bms.bar.size() < std::stoi(command.substr(1, 3)) + 1){
						bms.bar.reserve(std::stoi(command.substr(1, 3)) + 1);
					}
					auto channel = static_cast<Channel>(std::stoi(command.substr(4, 2)));
					int num_bar = std::stoi(command.substr(0, 3));
					int num_note = data.size() / 2;
					for (int i = 0; i < num_note - 1; i++) {
						Object obj;
						obj.time = 9600 * num_bar + i*(9600 / num_note);
						obj.data = std::stoi(data.substr(i, 2));
						obj.channel = channel;
						bms.bar.push_back(obj);
					}
				}
			}
		}
		std::sort(bms.bar.begin(), bms.bar.end());
	}

	Bms loadheader(std::string bmsfile) {
		std::ifstream file(bmsfile);
		std::string line;
		if (file.fail())
		{
			return Bms();
		}
		Bms bms;

		while (getline(file, line))
		{

			if (line[0] == '#') {

				if (!isdigit(line[1])) {

					auto strs = split_naive(line, ' ');
					std::string command = strs[0].substr(1);
					std::string arg1;
					if (strs.size() == 1) {
						arg1 = "";
					}
					else {
						arg1 = strs[1];
					}

					if (!std::strcmp(command.c_str(), "PLAYER")) {

						bms.header.player = static_cast<Player>(std::stoi(arg1.c_str()));
					}
					if (!std::strcmp(command.c_str(), "GENRE")) {
						bms.header.genre = arg1;
					}
					if (!std::strcmp(command.c_str(), "TITLE")) {
						std::string rs;
						for (int i = 1; i < strs.size() - 1; i++) {
							rs += strs[i];
						}
						bms.header.title = rs;
					}
					if (!std::strcmp(command.c_str(), "ARTIST")) {
						bms.header.artist = arg1;
					}
					if (!std::strcmp(command.c_str(), "BPM")) {
						bms.header.bpm = std::stof(arg1);
					}
					if (!std::strcmp(command.c_str(), "PLAYLEVEL")) {
						bms.header.level = std::stoi(arg1);
					}
					if (!std::strcmp(command.c_str(), "RANK")) {
						bms.header.rank = static_cast<Rank>(std::stoi(arg1));
					}
					if (!std::strcmp(command.c_str(), "VOLWAV")) {
						bms.header.volume = std::stoi(arg1);
					}
					if (!std::strcmp(command.c_str(), "TOTAL")) {
						bms.header.total = std::stoi(arg1);
					}
					if (!std::strcmp(command.substr(0, 3).c_str(), "WAV")) {
						bms.header.wav[std::stoi(command.substr(3, 2), nullptr, 36)] = arg1;
					}
					if (!std::strcmp(command.substr(0, 3).c_str(), "BMP")) {
						bms.header.bmp[std::stoi(command.substr(3, 2), nullptr, 36)] = arg1;
					}
					if (!std::strcmp(command.c_str(), "StageFile")) {
						bms.header.stagefile = arg1;
					}
				}
			}
		}
		return bms;
	}

	void save(std::string filename, const Bms& bms) {

	}
}<commit_msg>直ってなかったてへぺろ<commit_after>#pragma once
#include<string>
#include<cstdint>
#include<fstream>
#include<array>
#include<vector>
#include<algorithm>
namespace bmslib {

	std::vector<std::string> split_naive(const std::string &s, char delim) {
		std::vector<std::string> elems;
		std::string item;
		for (char ch : s) {
			if (ch == delim) {
				if (!item.empty())
					elems.push_back(item);
				item.clear();
			}
			else {
				item += ch;
			}
		}
		if (!item.empty())
			elems.push_back(item);
		return elems;
	}

	std::string trim(const std::string& string, const char* trimCharacterList = " \t\v\r")
	{
		std::string result;

		// g镶ȊOʒu܂B
		std::string::size_type left = string.find_first_not_of(trimCharacterList);

		if (left != std::string::npos)
		{
			// g镶ȊOꍇ́A悤ɉE܂B
			std::string::size_type right = string.find_last_not_of(trimCharacterList);

			// ߂l肵܂Bł͉E猟ĂAg镶ȊOK݂̂ŔsvłB
			result = string.substr(left, right - left + 1);
		}

		return result;
	}

	enum Player {
		None,
		Single,
		Couple,
		Double,
		Battle
	};

	enum Rank {
		Veryhard,
		Hard,
		Normal,
		Easy
	};

	struct Header
	{
		Player player;
		std::string genre, title, artist, stagefile;
		double bpm;
		unsigned int level, volume, total;
		Rank rank;
		std::array<std::string, 575> wav, bmp;
	};

	enum Channel {
		None1,
		Backwav,
		Shortening,
		Changebpm,
		Bga,
		None2,
		Pooranim,
		Bgalayer,
		exBPM,
		Stop,
		None3,
		Key1,
		Key2,
		Key3,
		Key4,
		Key5,
		Key6,
		Key7,
		Key8,
		Key9,
		None4,
		Key1_2P,
		Key2_2P,
		Key3_2P,
		Key4_2P,
		Key5_2P,
		Key6_2P,
		Key7_2P,
		Key8_2P,
		Key9_2P,
	};

	struct Bar {
		Channel channel;
		int backchorus; // Set WAV number
		int length = 1000; // Default Value = 1000
		std::vector<double> bpms;
		int bga, pooranim, layerbga;
		std::array<std::vector<bool>, 9> objects;
	};

	struct Object {
		int data;
		long time;
		Channel channel;

		bool operator<(const Object obj) {
			return time < obj.time;
		}
	};

	struct Bms {
		Header header;
		std::vector<Object> bar;
	};

	Bms load_data(std::string bmsfile) {
		std::ifstream file(bmsfile);
		std::string line;
		if (file.fail())
		{
			return Bms();
		}
		Bms bms;
		while (getline(file, line))
		{
			trim(line);
			if (line[0] == '#') {
				if (isdigit(line[1])) {
					auto str = split_naive(line,':');

					auto command = str[0];
					auto data = str[1];

					if (bms.bar.size() < std::stoi(command.substr(1, 3)) + 1){
						bms.bar.reserve(std::stoi(command.substr(1, 3)) + 1);
					}
					auto channel = static_cast<Channel>(std::stoi(command.substr(4, 2)));
					int num_bar = std::stoi(command.substr(0, 3));
					int num_note = data.size() / 2;
					for (int i = 0; i < num_note - 1; i++) {
						Object obj;
						obj.time = 9600 * num_bar + i*(9600 / num_note);
						obj.data = std::stoi(data.substr(i, 2));
						obj.channel = channel;
						bms.bar.push_back(obj);
					}
				}
			}
		}
		std::sort(bms.bar.begin(), bms.bar.end());
	}

	Bms loadheader(std::string bmsfile) {
		std::ifstream file(bmsfile);
		std::string line;
		if (file.fail())
		{
			return Bms();
		}
		Bms bms;

		while (getline(file, line))
		{

			if (line[0] == '#') {

				if (!isdigit(line[1])) {

					auto strs = split_naive(line, ' ');
					std::string command = strs[0].substr(1);
					std::string arg1;
					if (strs.size() == 1) {
						arg1 = "";
					}
					else {
						arg1 = strs[1];
					}

					if (!std::strcmp(command.c_str(), "PLAYER")) {

						bms.header.player = static_cast<Player>(std::stoi(arg1.c_str()));
					}
					if (!std::strcmp(command.c_str(), "GENRE")) {
						bms.header.genre = arg1;
					}
					if (!std::strcmp(command.c_str(), "TITLE")) {
						std::string rs;
						for (int i = 1; i < strs.size() - 1; i++) {
							rs += strs[i];
							rs += "";
						}
						bms.header.title = rs;
					}
					if (!std::strcmp(command.c_str(), "ARTIST")) {
						bms.header.artist = arg1;
					}
					if (!std::strcmp(command.c_str(), "BPM")) {
						bms.header.bpm = std::stof(arg1);
					}
					if (!std::strcmp(command.c_str(), "PLAYLEVEL")) {
						bms.header.level = std::stoi(arg1);
					}
					if (!std::strcmp(command.c_str(), "RANK")) {
						bms.header.rank = static_cast<Rank>(std::stoi(arg1));
					}
					if (!std::strcmp(command.c_str(), "VOLWAV")) {
						bms.header.volume = std::stoi(arg1);
					}
					if (!std::strcmp(command.c_str(), "TOTAL")) {
						bms.header.total = std::stoi(arg1);
					}
					if (!std::strcmp(command.substr(0, 3).c_str(), "WAV")) {
						bms.header.wav[std::stoi(command.substr(3, 2), nullptr, 36)] = arg1;
					}
					if (!std::strcmp(command.substr(0, 3).c_str(), "BMP")) {
						bms.header.bmp[std::stoi(command.substr(3, 2), nullptr, 36)] = arg1;
					}
					if (!std::strcmp(command.c_str(), "StageFile")) {
						bms.header.stagefile = arg1;
					}
				}
			}
		}
		return bms;
	}

	void save(std::string filename, const Bms& bms) {

	}
}<|endoftext|>


<commit_before>/************************************************************************
*
* Flood Project  (2008-201x)
* Licensed under the simplified BSD license. All rights reserved.
*
************************************************************************/

#include "Core/API.h"

#ifdef ENABLE_ARCHIVE_DIR

#include "Core/Archive.h"
#include "Core/Stream.h"
#include "Core/Memory.h"
#include "Core/Log.h"
#include "Core/Utilities.h"

NAMESPACE_CORE_BEGIN

//-----------------------------------//

static bool    DirArchiveOpen(Archive*, const String&);
static bool    DirArchiveClose(Archive*);
static Stream* DirArchiveOpenFile(Archive*, const Path&, Allocator*);
static void    DirArchiveEnumerateFiles(Archive*, std::vector<Path>&);
static void    DirArchiveEnumerateDirectories(Archive*, std::vector<Path>&);
static bool    DirArchiveExistsFile(Archive*, const Path&);
static bool    DirArchiveExistsDir(Archive*, const Path&);
static bool    DirArchiveMonitor(Archive*);

static ArchiveFuncs gs_DirArchiveFuncs =
{
	DirArchiveOpen,
	DirArchiveClose,
	DirArchiveOpenFile,
	DirArchiveExistsFile,
	DirArchiveExistsDir,
	DirArchiveEnumerateFiles,
	DirArchiveEnumerateDirectories,
	DirArchiveMonitor,
};

//-----------------------------------//

Archive* ArchiveCreateFromDirectory(Allocator* alloc, const Path& path)
{
	Archive* archive = Allocate(alloc, Archive);

	archive->path = path;
	archive->handle = nullptr;
	archive->scheme = "fs";
	archive->fn = &gs_DirArchiveFuncs;

	if( !ArchiveOpen(archive, path) )
	{
		LogDebug("Error opening archive: %s", path.c_str());
		Deallocate(archive);
		return nullptr;
	}

	return archive;
}

//-----------------------------------//

static bool DirArchiveOpen(Archive* archive, const String& path)
{
	if( !archive ) return false;
	return true;
}

//-----------------------------------//

static bool DirArchiveClose(Archive* archive)
{
	if( !archive ) return false;

	if(archive->watchId != 0)
	{
		// Remove the archive from the watch list.
		GetFileWatcher()->removeWatch(archive->watchId);
	}

	return true;
}

//-----------------------------------//

static Stream* DirArchiveOpenFile(Archive* archive, const Path& file, Allocator* alloc)
{
	if( !archive ) return nullptr;

	Path fullPath = ArchiveCombinePath(archive, file);
	Stream* stream = AllocateHeap(FileStream, fullPath, StreamOpenMode::Read);

	return stream;
}

//-----------------------------------//

static void DirArchiveEnumerate(std::vector<String>&, Path, Path, bool);

static void DirArchiveEnumerateFiles(Archive* archive, std::vector<Path>& paths)
{
	if( !archive ) return;
	FileEnumerateFiles(archive->path, paths);
}

//-----------------------------------//

static void DirArchiveEnumerateDirectories(Archive* archive, std::vector<Path>& paths)
{
	if( !archive ) return;
	FileEnumerateDirectories(archive->path, paths);
}

//-----------------------------------//

static bool DirArchiveExistsFile(Archive* archive, const Path& file)
{
	if( !archive ) return false;

	const Path& fullPath = ArchiveCombinePath(archive, file);
	return FileExists(fullPath);
}

//-----------------------------------//

static bool DirArchiveExistsDir(Archive* archive, const Path& path)
{
	std::vector<Path> dirs;
	ArchiveEnumerateDirectories(archive, dirs);

	for(size_t i = 0; i < dirs.size(); i++)
	{
		Path normalized = PathNormalize(dirs[i]);
		Path dir = StringTrim(normalized, "/");
		if(dir == path) return true;
	}

	return false;
}

//-----------------------------------//

static void HandleFileWatch(const FileWatchEvent& event)
{
	Archive* archive = (Archive*) event.userdata;
	assert( archive != nullptr );

	archive->watch(archive, event);
}

//-----------------------------------//

static bool DirArchiveMonitor(Archive* archive)
{
	if( !archive ) return false;

	GetFileWatcher()->onFileWatchEvent.Connect(&HandleFileWatch);

	if(archive->watchId == 0)
	{
		// Add the archive to the watch list.
		archive->watchId = GetFileWatcher()->addWatch(archive->path, archive);
	}

	GetFileWatcher()->update();

	return true;
}

#endif

//-----------------------------------//

NAMESPACE_CORE_END<commit_msg>Check if the file exists when opening a new file from a directory.<commit_after>/************************************************************************
*
* Flood Project  (2008-201x)
* Licensed under the simplified BSD license. All rights reserved.
*
************************************************************************/

#include "Core/API.h"

#ifdef ENABLE_ARCHIVE_DIR

#include "Core/Archive.h"
#include "Core/Stream.h"
#include "Core/Memory.h"
#include "Core/Log.h"
#include "Core/Utilities.h"

NAMESPACE_CORE_BEGIN

//-----------------------------------//

static bool    DirArchiveOpen(Archive*, const String&);
static bool    DirArchiveClose(Archive*);
static Stream* DirArchiveOpenFile(Archive*, const Path&, Allocator*);
static void    DirArchiveEnumerateFiles(Archive*, std::vector<Path>&);
static void    DirArchiveEnumerateDirectories(Archive*, std::vector<Path>&);
static bool    DirArchiveExistsFile(Archive*, const Path&);
static bool    DirArchiveExistsDir(Archive*, const Path&);
static bool    DirArchiveMonitor(Archive*);

static ArchiveFuncs gs_DirArchiveFuncs =
{
	DirArchiveOpen,
	DirArchiveClose,
	DirArchiveOpenFile,
	DirArchiveExistsFile,
	DirArchiveExistsDir,
	DirArchiveEnumerateFiles,
	DirArchiveEnumerateDirectories,
	DirArchiveMonitor,
};

//-----------------------------------//

Archive* ArchiveCreateFromDirectory(Allocator* alloc, const Path& path)
{
	Archive* archive = Allocate(alloc, Archive);

	archive->path = path;
	archive->handle = nullptr;
	archive->scheme = "fs";
	archive->fn = &gs_DirArchiveFuncs;

	if( !ArchiveOpen(archive, path) )
	{
		LogDebug("Error opening archive: %s", path.c_str());
		Deallocate(archive);
		return nullptr;
	}

	return archive;
}

//-----------------------------------//

static bool DirArchiveOpen(Archive* archive, const String& path)
{
	if( !archive ) return false;
	return true;
}

//-----------------------------------//

static bool DirArchiveClose(Archive* archive)
{
	if( !archive ) return false;

	if(archive->watchId != 0)
	{
		// Remove the archive from the watch list.
		GetFileWatcher()->removeWatch(archive->watchId);
	}

	return true;
}

//-----------------------------------//

static Stream* DirArchiveOpenFile(Archive* archive, const Path& file, Allocator* alloc)
{
	if( !archive ) return nullptr;

	Path fullPath = ArchiveCombinePath(archive, file);

	if (!FileExists(fullPath))
		return nullptr;

	Stream* stream = AllocateHeap(FileStream, fullPath, StreamOpenMode::Read);

	return stream;
}

//-----------------------------------//

static void DirArchiveEnumerate(std::vector<String>&, Path, Path, bool);

static void DirArchiveEnumerateFiles(Archive* archive, std::vector<Path>& paths)
{
	if( !archive ) return;
	FileEnumerateFiles(archive->path, paths);
}

//-----------------------------------//

static void DirArchiveEnumerateDirectories(Archive* archive, std::vector<Path>& paths)
{
	if( !archive ) return;
	FileEnumerateDirectories(archive->path, paths);
}

//-----------------------------------//

static bool DirArchiveExistsFile(Archive* archive, const Path& file)
{
	if( !archive ) return false;

	const Path& fullPath = ArchiveCombinePath(archive, file);
	return FileExists(fullPath);
}

//-----------------------------------//

static bool DirArchiveExistsDir(Archive* archive, const Path& path)
{
	std::vector<Path> dirs;
	ArchiveEnumerateDirectories(archive, dirs);

	for(size_t i = 0; i < dirs.size(); i++)
	{
		Path normalized = PathNormalize(dirs[i]);
		Path dir = StringTrim(normalized, "/");
		if(dir == path) return true;
	}

	return false;
}

//-----------------------------------//

static void HandleFileWatch(const FileWatchEvent& event)
{
	Archive* archive = (Archive*) event.userdata;
	assert( archive != nullptr );

	archive->watch(archive, event);
}

//-----------------------------------//

static bool DirArchiveMonitor(Archive* archive)
{
	if( !archive ) return false;

	GetFileWatcher()->onFileWatchEvent.Connect(&HandleFileWatch);

	if(archive->watchId == 0)
	{
		// Add the archive to the watch list.
		archive->watchId = GetFileWatcher()->addWatch(archive->path, archive);
	}

	GetFileWatcher()->update();

	return true;
}

#endif

//-----------------------------------//

NAMESPACE_CORE_END<|endoftext|>


<commit_before>// Copyright (c) 2017, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-pinocchio.
// hpp-pinocchio 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
// 3 of the License, or (at your option) any later version.
//
// hpp-pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-pinocchio. If not, see <http://www.gnu.org/licenses/>.

#define BOOST_TEST_MODULE tframe

#include <boost/test/unit_test.hpp>

#include <hpp/pinocchio/joint.hh>
#include <hpp/pinocchio/device.hh>
#include <hpp/pinocchio/simple-device.hh>
#include <hpp/pinocchio/humanoid-robot.hh>
#include <hpp/pinocchio/urdf/util.hh>
#include <hpp/pinocchio/liegroup-space.hh>
#include <hpp/pinocchio/configuration.hh>
static bool verbose = true;

using namespace hpp::pinocchio;

void displayAABB(const fcl::AABB& aabb)
{
    std::cout << "Bounding box is\n"
      << aabb.min_.transpose() << '\n'
      << aabb.max_.transpose() << std::endl;
}

BOOST_AUTO_TEST_CASE (computeAABB)
{
  DevicePtr_t robot = unittest::makeDevice(unittest::HumanoidSimple);
  BOOST_REQUIRE(robot);

  robot->rootJoint()->lowerBounds(vector3_t::Constant(-0));
  robot->rootJoint()->upperBounds(vector3_t::Constant( 0));
  fcl::AABB aabb0 = robot->computeAABB();
  if (verbose) displayAABB(aabb0);

  robot->rootJoint()->lowerBounds(vector3_t(-1, -1, 0));
  robot->rootJoint()->upperBounds(vector3_t( 1,  1, 0));
  fcl::AABB aabb1 = robot->computeAABB();
  if (verbose) displayAABB(aabb1);

  robot->rootJoint()->lowerBounds(vector3_t(-2, -2, 0));
  robot->rootJoint()->upperBounds(vector3_t(-1, -1, 0));
  fcl::AABB aabb2 = robot->computeAABB();
  if (verbose) displayAABB(aabb2);
}
/* -------------------------------------------------------------------------- */
BOOST_AUTO_TEST_CASE (unit_test_device)
{
  DevicePtr_t robot;
  LiegroupSpacePtr_t space;

  robot = unittest::makeDevice (unittest::HumanoidSimple);
  space = LiegroupSpace::createCopy(robot->configSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "SE(3)*R^26");

  space = LiegroupSpace::createCopy(robot->RnxSOnConfigSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "R^3*SO(3)*R^26");

  robot->setDimensionExtraConfigSpace(3);
  BOOST_CHECK_EQUAL(robot->numberDof(), 32+3);
  BOOST_CHECK_EQUAL(robot->configSize(), 33+3);

  space = LiegroupSpace::createCopy(robot->configSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "SE(3)*R^29");

  robot = unittest::makeDevice (unittest::CarLike);
  space = LiegroupSpace::createCopy(robot->configSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "SE(2)*R^2");

  robot = unittest::makeDevice (unittest::ManipulatorArm2);
  space = LiegroupSpace::createCopy(robot->configSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "R^19");
}

// TODO When neutral configuration can be read from XML string, this test should be updated in order to
// read a URDF and SRDF string rather than a file in a different package.
BOOST_AUTO_TEST_CASE(load_neutral_configuration){
  std::string robotName("romeo");
  std::string packageName("romeo_description");
  std::string rootJointType("freeflyer");
  std::string modelName("romeo");
  std::string urdfSuffix("_small");
  std::string srdfSuffix("");

  DevicePtr_t device = Device::create(robotName);
  urdf::loadRobotModel (device,
             rootJointType,  packageName,modelName, urdfSuffix,srdfSuffix);
  BOOST_CHECK(device);
  BOOST_CHECK_EQUAL(device->neutralConfiguration().size(),device->configSize());
  Eigen::VectorXd expected(device->configSize());
  // values fond in the srdf file, if the file change this test need to be updated :
  expected << 0,0,0,0,0,0,1,0,0,-0.3490658,0.6981317,-0.3490658,0,0,0,-0.3490658,0.6981317,-0.3490658,0,0,1.5,0.6,-0.5,-1.05,-0.4,-0.3,-0.2,0,0,0,0,1.5,-0.6,0.5,1.05,-0.4,-0.3,-0.2;
  if(verbose)
    std::cout<<"neutral configuration after loading romeo : "<<displayConfig(device->neutralConfiguration())<<std::endl;
  BOOST_CHECK_MESSAGE(device->neutralConfiguration().isApprox(expected, 1e-12), "neutral configuration - wrong results");
}

<commit_msg>Update unit-test to hpp::fcl namespace.<commit_after>// Copyright (c) 2017, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-pinocchio.
// hpp-pinocchio 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
// 3 of the License, or (at your option) any later version.
//
// hpp-pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-pinocchio. If not, see <http://www.gnu.org/licenses/>.

#define BOOST_TEST_MODULE tframe

#include <boost/test/unit_test.hpp>

#include <hpp/pinocchio/joint.hh>
#include <hpp/pinocchio/device.hh>
#include <hpp/pinocchio/simple-device.hh>
#include <hpp/pinocchio/humanoid-robot.hh>
#include <hpp/pinocchio/urdf/util.hh>
#include <hpp/pinocchio/liegroup-space.hh>
#include <hpp/pinocchio/configuration.hh>
static bool verbose = true;

using namespace hpp::pinocchio;

void displayAABB(const hpp::fcl::AABB& aabb)
{
    std::cout << "Bounding box is\n"
      << aabb.min_.transpose() << '\n'
      << aabb.max_.transpose() << std::endl;
}

BOOST_AUTO_TEST_CASE (computeAABB)
{
  DevicePtr_t robot = unittest::makeDevice(unittest::HumanoidSimple);
  BOOST_REQUIRE(robot);

  robot->rootJoint()->lowerBounds(vector3_t::Constant(-0));
  robot->rootJoint()->upperBounds(vector3_t::Constant( 0));
  hpp::fcl::AABB aabb0 = robot->computeAABB();
  if (verbose) displayAABB(aabb0);

  robot->rootJoint()->lowerBounds(vector3_t(-1, -1, 0));
  robot->rootJoint()->upperBounds(vector3_t( 1,  1, 0));
  hpp::fcl::AABB aabb1 = robot->computeAABB();
  if (verbose) displayAABB(aabb1);

  robot->rootJoint()->lowerBounds(vector3_t(-2, -2, 0));
  robot->rootJoint()->upperBounds(vector3_t(-1, -1, 0));
  hpp::fcl::AABB aabb2 = robot->computeAABB();
  if (verbose) displayAABB(aabb2);
}
/* -------------------------------------------------------------------------- */
BOOST_AUTO_TEST_CASE (unit_test_device)
{
  DevicePtr_t robot;
  LiegroupSpacePtr_t space;

  robot = unittest::makeDevice (unittest::HumanoidSimple);
  space = LiegroupSpace::createCopy(robot->configSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "SE(3)*R^26");

  space = LiegroupSpace::createCopy(robot->RnxSOnConfigSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "R^3*SO(3)*R^26");

  robot->setDimensionExtraConfigSpace(3);
  BOOST_CHECK_EQUAL(robot->numberDof(), 32+3);
  BOOST_CHECK_EQUAL(robot->configSize(), 33+3);

  space = LiegroupSpace::createCopy(robot->configSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "SE(3)*R^29");

  robot = unittest::makeDevice (unittest::CarLike);
  space = LiegroupSpace::createCopy(robot->configSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "SE(2)*R^2");

  robot = unittest::makeDevice (unittest::ManipulatorArm2);
  space = LiegroupSpace::createCopy(robot->configSpace());
  space->mergeVectorSpaces();
  BOOST_CHECK_EQUAL (space->name(), "R^19");
}

// TODO When neutral configuration can be read from XML string, this test should be updated in order to
// read a URDF and SRDF string rather than a file in a different package.
BOOST_AUTO_TEST_CASE(load_neutral_configuration){
  std::string robotName("romeo");
  std::string packageName("romeo_description");
  std::string rootJointType("freeflyer");
  std::string modelName("romeo");
  std::string urdfSuffix("_small");
  std::string srdfSuffix("");

  DevicePtr_t device = Device::create(robotName);
  urdf::loadRobotModel (device,
             rootJointType,  packageName,modelName, urdfSuffix,srdfSuffix);
  BOOST_CHECK(device);
  BOOST_CHECK_EQUAL(device->neutralConfiguration().size(),device->configSize());
  Eigen::VectorXd expected(device->configSize());
  // values fond in the srdf file, if the file change this test need to be updated :
  expected << 0,0,0,0,0,0,1,0,0,-0.3490658,0.6981317,-0.3490658,0,0,0,-0.3490658,0.6981317,-0.3490658,0,0,1.5,0.6,-0.5,-1.05,-0.4,-0.3,-0.2,0,0,0,0,1.5,-0.6,0.5,1.05,-0.4,-0.3,-0.2;
  if(verbose)
    std::cout<<"neutral configuration after loading romeo : "<<displayConfig(device->neutralConfiguration())<<std::endl;
  BOOST_CHECK_MESSAGE(device->neutralConfiguration().isApprox(expected, 1e-12), "neutral configuration - wrong results");
}

<|endoftext|>


<commit_before>//version : 1.1
//02.01.2013

#include "dialogPreferences.hpp"
#include "dialogShortcutPreferences.hpp"
#include "shortcut.hpp"

#include <wx/msgdlg.h>
#include <wx/menu.h>

//TEST
#include <iostream>

//! ****************************************************************************
//! Class DialogPreferences
//! ****************************************************************************

DialogPreferences::DialogPreferences(ActionManager *actionManager)
: GuiDialogPreferences(nullptr), _actionManager(actionManager)
{
    //Magnifier
    _staticTextSetting->SetLabelMarkup(""+_("Setting")+"");
	_staticTextShutdown->SetLabelMarkup(""+_("Shutdown this application")+"");

	//_listCtrlAction->EnableAlternateRowColours();
	_listCtrlAction->AppendColumn(_("Shortcut"), wxLIST_FORMAT_LEFT, 100);
	_listCtrlAction->AppendColumn(_("Action"), wxLIST_FORMAT_LEFT, 100);
	_listCtrlAction->AppendColumn(_("Preferences"), wxLIST_FORMAT_LEFT, 170);

	//Rempli la list.
	for(auto it: *_actionManager->getAction())
	{
		_listCtrlAction->InsertItem(0, ShortcutKey::shortcutKeyToString(it.first));
		_listCtrlAction->SetItem(0, 1, it.second->getName());
		_listCtrlAction->SetItem(0, 2, it.second->getStringPreferences());
	}
}

DialogPreferences::~DialogPreferences()
{
}

void DialogPreferences::OnButtonClickActDelete(wxCommandEvent&)
{
	wxMessageDialog *dlg = nullptr;

	if(_listItemSelected.size() > 1)
		dlg = new wxMessageDialog(this, _("Do you want really delete this actions ?"), _("Delete actions"), wxYES_NO|wxCENTRE);
	else
		dlg = new wxMessageDialog(this, _("Do you want really delete an action ?"), _("Delete action"), wxYES_NO|wxCENTRE);

    if(dlg->ShowModal() == wxID_OK )
	{
	}

    dlg->Destroy();
}

void DialogPreferences::OnButtonClickActPreferences(wxCommandEvent&)
{
	std::cout << "OnButtonClickActPreferences" << std::endl;
}

void DialogPreferences::OnButtonClickActAdd(wxCommandEvent&)
{
	std::cout << "OnButtonClickActAdd" << std::endl;

	//DialogShortcutPreferences *dlg = new DialogShortcutPreferences(this);
	//dlg->ShowModal();
	//delete dlg;
}

void DialogPreferences::OnButtonClickOK(wxCommandEvent& event)
{
	event.Skip();
}

void DialogPreferences::OnButtonClickApply(wxCommandEvent& event)
{
	event.Skip();
}

void DialogPreferences::OnListItemDeselectedAction(wxListEvent& event)
{
	//Recherche et suppression de l'item désélectionner.
	for(size_t i = 0; i<_listItemSelected.size(); i++)
	{
		if(_listItemSelected[i] == event.GetItem())
		{
			_listItemSelected.erase(_listItemSelected.begin()+i);
			break;
		}
	}

	//Si rien n'est sélectionner on désactive les boutons delete.
	if(_listItemSelected.size() <= 0)
	{
		_buttonActDelete->Enable(false);
		_menuItemListDelete->Enable(false);
	}

	//On désactive le bouton Préférence soft si il y a un seul item de sélectionner.
	if(_listItemSelected.size() != 1)
	{
		_buttonActPreferences->Enable(false);
		_menuItemListPreferences->Enable(false);
	}
	else
	{
		_buttonActPreferences->Enable();
		_menuItemListPreferences->Enable();
	}
}

void DialogPreferences::OnListItemSelectedAction(wxListEvent& event)
{
	_listItemSelected.push_back(event.GetItem());

	//activation du bouton delete
	_buttonActDelete->Enable();
	_menuItemListDelete->Enable();

	//on active le bouton préférence seulement si il y a qu'un item de sélectionner.
	if(_listItemSelected.size() == 1)
	{
		_buttonActPreferences->Enable();
		_menuItemListPreferences->Enable();
	}
	else
	{
		_buttonActPreferences->Enable(false);
		_menuItemListPreferences->Enable(false);
	}
}

bool DialogPreferences::shutdownIsToggle()const
{
	return _toggleBtnTurnOff->GetValue();
}

bool DialogPreferences::showIcon()const
{
	return _checkBoxShowMenu->GetValue();
}

<commit_msg>change test<commit_after>//version : 1.1
//02.01.2013

#include "dialogPreferences.hpp"
#include "dialogShortcutPreferences.hpp"
#include "shortcut.hpp"

#include <wx/msgdlg.h>
#include <wx/menu.h>

//TEST
#include <iostream>

//! ****************************************************************************
//! Class DialogPreferences
//! ****************************************************************************

DialogPreferences::DialogPreferences(ActionManager *actionManager)
: GuiDialogPreferences(nullptr), _actionManager(actionManager)
{
    //Magnifier
    _staticTextSetting->SetLabelMarkup(""+_("Setting")+"");
	_staticTextShutdown->SetLabelMarkup(""+_("Shutdown this application")+"");

	//_listCtrlAction->EnableAlternateRowColours();
	_listCtrlAction->AppendColumn(_("Shortcut"), wxLIST_FORMAT_LEFT, 100);
	_listCtrlAction->AppendColumn(_("Action"), wxLIST_FORMAT_LEFT, 100);
	_listCtrlAction->AppendColumn(_("Preferences"), wxLIST_FORMAT_LEFT, 170);

	//Rempli la list.
	for(auto it: *_actionManager->getAction())
	{
		_listCtrlAction->InsertItem(0, ShortcutKey::shortcutKeyToString(it.first));
		_listCtrlAction->SetItem(0, 1, it.second->getName());
		_listCtrlAction->SetItem(0, 2, it.second->getStringPreferences());
	}
}

DialogPreferences::~DialogPreferences()
{
}

void DialogPreferences::OnButtonClickActDelete(wxCommandEvent&)
{
	wxMessageDialog *dlg = nullptr;

	if(_listItemSelected.size() > 1)
		dlg = new wxMessageDialog(this, _("Do you want really delete this actions ?"), _("Delete actions"), wxYES_NO|wxCENTRE);
	else
		dlg = new wxMessageDialog(this, _("Do you want really delete this action ?"), _("Delete action"), wxYES_NO|wxCENTRE);

    if(dlg->ShowModal() == wxID_OK )
	{
	}

    dlg->Destroy();
}

void DialogPreferences::OnButtonClickActPreferences(wxCommandEvent&)
{
	std::cout << "OnButtonClickActPreferences" << std::endl;
}

void DialogPreferences::OnButtonClickActAdd(wxCommandEvent&)
{
	std::cout << "OnButtonClickActAdd" << std::endl;

	//DialogShortcutPreferences *dlg = new DialogShortcutPreferences(this);
	//dlg->ShowModal();
	//delete dlg;
}

void DialogPreferences::OnButtonClickOK(wxCommandEvent& event)
{
	event.Skip();
}

void DialogPreferences::OnButtonClickApply(wxCommandEvent& event)
{
	event.Skip();
}

void DialogPreferences::OnListItemDeselectedAction(wxListEvent& event)
{
	//Recherche et suppression de l'item désélectionner.
	for(size_t i = 0; i<_listItemSelected.size(); i++)
	{
		if(_listItemSelected[i] == event.GetItem())
		{
			_listItemSelected.erase(_listItemSelected.begin()+i);
			break;
		}
	}

	//Si rien n'est sélectionner on désactive les boutons delete.
	if(_listItemSelected.size() <= 0)
	{
		_buttonActDelete->Enable(false);
		_menuItemListDelete->Enable(false);
	}

	//On désactive le bouton Préférence soft si il y a un seul item de sélectionner.
	if(_listItemSelected.size() != 1)
	{
		_buttonActPreferences->Enable(false);
		_menuItemListPreferences->Enable(false);
	}
	else
	{
		_buttonActPreferences->Enable();
		_menuItemListPreferences->Enable();
	}
}

void DialogPreferences::OnListItemSelectedAction(wxListEvent& event)
{
	_listItemSelected.push_back(event.GetItem());

	//activation du bouton delete
	_buttonActDelete->Enable();
	_menuItemListDelete->Enable();

	//on active le bouton préférence seulement si il y a qu'un item de sélectionner.
	if(_listItemSelected.size() == 1)
	{
		_buttonActPreferences->Enable();
		_menuItemListPreferences->Enable();
	}
	else
	{
		_buttonActPreferences->Enable(false);
		_menuItemListPreferences->Enable(false);
	}
}

bool DialogPreferences::shutdownIsToggle()const
{
	return _toggleBtnTurnOff->GetValue();
}

bool DialogPreferences::showIcon()const
{
	return _checkBoxShowMenu->GetValue();
}

<|endoftext|>


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

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

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

#define INSERT_NUM_TYPE_NO_NUMBERING                0x01
#define INSERT_NUM_TYPE_PAGE_STYLE_NUMBERING        0x02
#define INSERT_NUM_TYPE_BITMAP                      0x04
#define INSERT_NUM_TYPE_BULLET                      0x08
#define INSERT_NUM_EXTENDED_TYPES                   0x10

struct SwNumberingTypeListBox_Impl;

class SW_DLLPUBLIC SwNumberingTypeListBox : public ListBox
{
    SwNumberingTypeListBox_Impl* pImpl;

public:
    SwNumberingTypeListBox( Window* pWin, const ResId& rResId,
        USHORT nTypeFlags = INSERT_NUM_TYPE_PAGE_STYLE_NUMBERING|INSERT_NUM_TYPE_NO_NUMBERING|INSERT_NUM_EXTENDED_TYPES );
    ~SwNumberingTypeListBox();

    void        Reload(USHORT nTypeFlags);

    sal_Int16   GetSelectedNumberingType();
    sal_Bool    SelectNumberingType(sal_Int16 nType);
};

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.596); FILE MERGED 2005/09/05 13:45:28 rt 1.2.596.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: numberingtypelistbox.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 09:52:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _NUMBERINGTYPELISTBOX_HXX
#define _NUMBERINGTYPELISTBOX_HXX

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

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

#define INSERT_NUM_TYPE_NO_NUMBERING                0x01
#define INSERT_NUM_TYPE_PAGE_STYLE_NUMBERING        0x02
#define INSERT_NUM_TYPE_BITMAP                      0x04
#define INSERT_NUM_TYPE_BULLET                      0x08
#define INSERT_NUM_EXTENDED_TYPES                   0x10

struct SwNumberingTypeListBox_Impl;

class SW_DLLPUBLIC SwNumberingTypeListBox : public ListBox
{
    SwNumberingTypeListBox_Impl* pImpl;

public:
    SwNumberingTypeListBox( Window* pWin, const ResId& rResId,
        USHORT nTypeFlags = INSERT_NUM_TYPE_PAGE_STYLE_NUMBERING|INSERT_NUM_TYPE_NO_NUMBERING|INSERT_NUM_EXTENDED_TYPES );
    ~SwNumberingTypeListBox();

    void        Reload(USHORT nTypeFlags);

    sal_Int16   GetSelectedNumberingType();
    sal_Bool    SelectNumberingType(sal_Int16 nType);
};

#endif

<|endoftext|>


<commit_before>#include "Database.h"

#include <iostream>
#include <fstream>
#include <string>
#include <sqlite3.h>

#include "Table.h"
#include "CycException.h"
#include "Logger.h"

using namespace std;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Database::Database(std::string filename){
  database_ = NULL;
  exists_ = true;
  isOpen_ = false;
  name_ = filename;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Database::Database(std::string filename, std::string file_path){
  database_ = NULL;
  exists_ = true;
  isOpen_ = false;
  name_ = filename;
  path_ = file_path;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::fexists(const char *filename) {
  ifstream ifile(filename);
  return ifile;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Database::path() {
  string full_path = "";
  if ( !path_.empty() ) {
    full_path += path_ + "/";
  }
  return full_path;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::open() {
  if ( dbExists() ) {
    string path_to_file = path() + name_;
    if(sqlite3_open(path_to_file.c_str(), &database_) == SQLITE_OK) {
      isOpen_ = true;
      return true;
    }
    else {
      throw CycIOException("Unable to open database " + path_to_file);
    }
  } // end if ( dbExists() )
  else {
    throw CycIOException("Trying to open a non-existant Database");
  }
  return false;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::close() {
  if ( isOpen() ) {
    if (sqlite3_close(database_) == SQLITE_OK) {
      isOpen_ = false;
      return true;
    }
    else {
      throw CycIOException("Error closing existing database: " + name_);
      return false;
    }
  } // endif ( isOpen() )
  else {
    throw CycIOException("Trying to close an already-closed database: " + name_);
    return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::isOpen() {
  string err;
  if ( dbExists() )
    return isOpen_;
  else {
    err = "Database " + name_ + " is not open because it does not exist.";
    throw CycIOException(err);
  }
  return false;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::dbExists() {
  if (this != NULL) {
    return true;
  }
  else {
    return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::registerTable(table_ptr t) {
  if ( dbExists() ) {
    tables_.push_back(t);
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::removeTable(table_ptr t) {
  if ( dbExists() ) {
    tables_.erase(find(tables_.begin(), tables_.end(), t));
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::createTable(table_ptr t){
  if ( isOpen() ) {
    bool tExists = tableExists(t);
    if (tExists) {
      // declare members
      string query = t->create();
      this->issueCommand(query);
    }
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::tableExists(table_ptr t) {
  // make sure the table exists before it is accessed
  bool isPresent = false;
  string err;

  // case: the database is not null
  if ( dbExists() ) {
    // case: the table pointer is null
    if ( t == NULL )
      err = "Database " + this->name()
	+ " was asked to interact with a non-existant table.";
    // case: the table pointer is NOT null but the table is not created
    else if ( !t->defined() )
      err = "Database " + this->name()
	+ " was asked to interact with a existant, but non-defined table.";
    // case: table is defined, search for it
    else {
      isPresent =
	(find(tables_.begin(), tables_.end(), t) != tables_.end());
      if (!isPresent)
	err = "Table: " + t->name()
	  + "  is not registered with Database " + this->name() + ".";
    }
  }
  // case: the database is null
  else
    err = "An attempt was made to interact with a non existant Database.";

  // found, return true
  if(isPresent)
    return true;
  else {
    // not found, throw an error and return false
    throw CycIOException(err);
    return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::issueCommand(std::string cmd){
  if ( isOpen() ) {
    sqlite3_stmt *statement;
    // query the database
    int check_query =
      sqlite3_prepare_v2(database_, cmd.c_str(), -1, &statement, 0);
    if(check_query == SQLITE_OK) {
      int result = sqlite3_step(statement);
      sqlite3_finalize(statement);
    }
    // collect errors
    string error = sqlite3_errmsg(database_);
    if(error != "not an error")
      throw CycIOException("SQL error: " + cmd + " " + error);
  }
  else
    throw CycIOException("Tried to issue command to closed table: " + name_);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::writeRows(table_ptr t){
  if ( isOpen() ) {
    bool exists = tableExists(t);
    if (exists) {
      // write each row in the Table's row commands
      int nRows = t->nRows();
      for (int i = 0; i < nRows; i++){
	string cmd_str = t->row_command(i)->str();
	this->issueCommand(cmd_str);
	LOG(LEV_DEBUG4,"db") << "Issued writeRows command to table: "
			     << t->name() << " with the command being "
			     << cmd_str;
      }
    }
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::flush(table_ptr t){
  if ( isOpen() ) {
    bool exists = tableExists(t);
    if (exists) {
      t->flush();
    }
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
query_result Database::query(std::string query){
  // declare members
  sqlite3_stmt *statement;
  query_result results;

  if ( isOpen() ) {
    // query the database
    int check_query =
      sqlite3_prepare_v2(database_, query.c_str(), -1, &statement, 0);
    if(check_query == SQLITE_OK){
      int cols = sqlite3_column_count(statement);
      int result = 0;
      while(true){
	result = sqlite3_step(statement);
	// access the rows
	if(result == SQLITE_ROW){
	  query_row values;
	  for(int col = 0; col < cols; col++){
	    string  val;
	    char * ptr = (char*)sqlite3_column_text(statement, col);
	    if(ptr)
	      val = ptr;
	    else
	      val = "";
	    values.push_back(val);  // now we will never push NULL
	  }
	  results.push_back(values);
	}
	else
	  break;
      }
      sqlite3_finalize(statement);
    }
    // collect errors
    string error = sqlite3_errmsg(database_);
    if(error != "not an error")
      throw CycIOException("SQL error: " + query + " " + error);
  }
  else
    throw CycIOException("Attempted to query the closed database: " + name_);
  return results;
}
<commit_msg>added proper indentation to code (formatting change only)<commit_after>#include "Database.h"

#include <iostream>
#include <fstream>
#include <string>
#include <sqlite3.h>

#include "Table.h"
#include "CycException.h"
#include "Logger.h"

using namespace std;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Database::Database(std::string filename){
  database_ = NULL;
  exists_ = true;
  isOpen_ = false;
  name_ = filename;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Database::Database(std::string filename, std::string file_path){
  database_ = NULL;
  exists_ = true;
  isOpen_ = false;
  name_ = filename;
  path_ = file_path;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::fexists(const char *filename) {
  ifstream ifile(filename);
  return ifile;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Database::path() {
  string full_path = "";
  if ( !path_.empty() ) {
    full_path += path_ + "/";
  }
  return full_path;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::open() {
  if ( dbExists() ) {
    string path_to_file = path() + name_;
    if(sqlite3_open(path_to_file.c_str(), &database_) == SQLITE_OK) {
      isOpen_ = true;
      return true;
    }
    else {
      throw CycIOException("Unable to open database " + path_to_file);
    }
  } // end if ( dbExists() )
  else {
    throw CycIOException("Trying to open a non-existant Database");
  }
  return false;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::close() {
  if ( isOpen() ) {
    if (sqlite3_close(database_) == SQLITE_OK) {
      isOpen_ = false;
      return true;
    }
    else {
      throw CycIOException("Error closing existing database: " + name_);
      return false;
    }
  } // endif ( isOpen() )
  else {
    throw CycIOException("Trying to close an already-closed database: " + name_);
    return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::isOpen() {
  string err;
  if ( dbExists() )
    return isOpen_;
  else {
    err = "Database " + name_ + " is not open because it does not exist.";
    throw CycIOException(err);
  }
  return false;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::dbExists() {
  if (this != NULL) {
    return true;
  }
  else {
    return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::registerTable(table_ptr t) {
  if ( dbExists() ) {
    tables_.push_back(t);
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::removeTable(table_ptr t) {
  if ( dbExists() ) {
    tables_.erase(find(tables_.begin(), tables_.end(), t));
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::createTable(table_ptr t){
  if ( isOpen() ) {
    bool tExists = tableExists(t);
    if (tExists) {
      // declare members
      string query = t->create();
      this->issueCommand(query);
    }
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Database::tableExists(table_ptr t) {
  // make sure the table exists before it is accessed
  bool isPresent = false;
  string err;

  // case: the database is not null
  if ( dbExists() ) {
    // case: the table pointer is null
    if ( t == NULL )
      err = "Database " + this->name()
	+ " was asked to interact with a non-existant table.";
    // case: the table pointer is NOT null but the table is not created
    else if ( !t->defined() )
      err = "Database " + this->name()
	+ " was asked to interact with a existant, but non-defined table.";
    // case: table is defined, search for it
    else {
      isPresent =
	(find(tables_.begin(), tables_.end(), t) != tables_.end());
      if (!isPresent)
	err = "Table: " + t->name()
	  + "  is not registered with Database " + this->name() + ".";
    }
  }
  // case: the database is null
  else
    err = "An attempt was made to interact with a non existant Database.";

  // found, return true
  if(isPresent)
    return true;
  else {
    // not found, throw an error and return false
    throw CycIOException(err);
    return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::issueCommand(std::string cmd){
  if ( isOpen() ) {
    sqlite3_stmt *statement;
    // query the database
    int check_query =
      sqlite3_prepare_v2(database_, cmd.c_str(), -1, &statement, 0);
    if(check_query == SQLITE_OK) {
      int result = sqlite3_step(statement);
      sqlite3_finalize(statement);
    }
    // collect errors
    string error = sqlite3_errmsg(database_);
    if(error != "not an error")
      throw CycIOException("SQL error: " + cmd + " " + error);
  }
  else
    throw CycIOException("Tried to issue command to closed table: " + name_);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::writeRows(table_ptr t){
  if ( isOpen() ) {
    bool exists = tableExists(t);
    if (exists) {
      // write each row in the Table's row commands
      int nRows = t->nRows();
      for (int i = 0; i < nRows; i++){
	string cmd_str = t->row_command(i)->str();
	this->issueCommand(cmd_str);
	LOG(LEV_DEBUG4,"db") << "Issued writeRows command to table: "
			     << t->name() << " with the command being "
			     << cmd_str;
      }
    }
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Database::flush(table_ptr t){
  if ( isOpen() ) {
    bool exists = tableExists(t);
    if (exists) {
      t->flush();
    }
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
query_result Database::query(std::string query){
  // declare members
  sqlite3_stmt *statement;
  query_result results;

  if ( isOpen() ) {
    // query the database
    int check_query =
      sqlite3_prepare_v2(database_, query.c_str(), -1, &statement, 0);
    if(check_query == SQLITE_OK){
      int cols = sqlite3_column_count(statement);
      int result = 0;
      while(true){
        result = sqlite3_step(statement);
        // access the rows
        if(result == SQLITE_ROW){
          query_row values;
          for(int col = 0; col < cols; col++){
            string  val;
            char * ptr = (char*)sqlite3_column_text(statement, col);
            if(ptr)
              val = ptr;
            else
              val = "";
            values.push_back(val);  // now we will never push NULL
          }
          results.push_back(values);
        }
        else
          break;
      }
      sqlite3_finalize(statement);
    }
    // collect errors
    string error = sqlite3_errmsg(database_);
    if(error != "not an error")
      throw CycIOException("SQL error: " + query + " " + error);
  }
  else
    throw CycIOException("Attempted to query the closed database: " + name_);
  return results;
}
<|endoftext|>