/**
 * @file   AXCRingBuf.hpp
 * @brief  AXCRingBufクラスヘッダ
 *
 * @par    Programming Language
 *         C++
 */

#ifndef AXCRINGBUF_HPP_
#define AXCRINGBUF_HPP_

#include <stdio.h>

/**
 * @class AXCRingBuf
 * @brief AXC層の RingBufクラス に対し、抽象クラスを提供する
 *
 * @n     [注意]モデル層は本クラスは直接使用せず、AXFRingBuf を使用する。
 *
 */
class AXCRingBuf {
 public:
  /** @enum  ringBufStatus
   *  @brief RingBuf実行完了状態
   */
  enum ringBufStatus {
    RINGBUF_SUCCESS = 0,  ///< 正常終了
    RINGBUF_ERROR,       ///< 異常終了
  };

  /** @enum  ringBufRW
   *  @brief RingBufリード・ライト指定
   */
  enum ringBufRW {
    RINGBUF_READ = 0,  ///< リード指定
    RINGBUF_WRITE,    ///< ライト指定
    RINGBUF_RW_NUM,   ///< 指定数
  };

 private:
  char *m_buf;
  int m_size;
  int m_offset[RINGBUF_RW_NUM];

 public:
  /**
   * @brief AXCRingBufコンストラクタ
   */
  AXCRingBuf(char* buf = NULL, int size = 0)
      : m_buf(buf),
        m_size(size) {
  }

  /**
   * @brief AXCRingBufデストラクタ
   */
  virtual ~AXCRingBuf() {
    delete[] m_buf;
  }

  /**
   * @brief 初期化
   * @return AXCRingBuf初期化状況
   * - RINGBUF_SUCCESS 正常終了
   * - RINGBUF_ERROR 異常終了
   */
  virtual ringBufStatus init();

  /**
   * @brief オフセット位置取得
   * @param [in] rw リード・ライト指定
   * @return バイト・オフセット位置
   */
  virtual int getOffset(ringBufRW rw) {
    return m_offset[rw];
  }

  /**
   * @brief オフセット位置設定
   * @param [in] rw リード・ライト指定
   * @param [in] v バイト・オフセット位置
   */
  virtual void setOffset(ringBufRW rw, int v) {
    m_offset[rw] = v;
  }

  /**
   * @brief ロック
   * @param [in] rw リード・ライト指定
   * @return ロック状況
   * - RINGBUF_SUCCESS 正常終了
   * - RINGBUF_ERROR 異常終了
   */
  virtual ringBufStatus lock(ringBufRW rw) {
    return RINGBUF_SUCCESS;
  }

  /**
   * @brief アンロック
   * @param [in] rw リード・ライト指定
   * @return アンロック状況
   * - RINGBUF_SUCCESS 正常終了
   * - RINGBUF_ERROR 異常終了
   */
  virtual ringBufStatus unlock(ringBufRW rw) {
    return RINGBUF_SUCCESS;
  }

  /**
   * @brief ウエイト
   * @param [in] rw リード・ライト指定
   * @return ウエイト状況
   * - RINGBUF_SUCCESS 正常終了
   * - RINGBUF_ERROR 異常終了
   */
  virtual ringBufStatus waitFor(ringBufRW rw) {
    return RINGBUF_SUCCESS;
  }

  /**
   * @brief シグナル発行
   * @param [in] rw リード・ライト指定
   * @return シグナル発行状況
   * - RINGBUF_SUCCESS 正常終了
   * - RINGBUF_ERROR 異常終了
   */
  virtual ringBufStatus signalTo(ringBufRW rw) {
    return RINGBUF_SUCCESS;
  }

  /**
   * @brief データサイズ取得
   * @return バッファ上の有効なデータのバイト数
   */
  int dataSize();

  /**
   * @brief 空きサイズ取得
   * @return バッファ上の空きバイト数
   */
  int freeSize();

  /**
   * @brief バッファ取得
   */
  char* getBuf() {
    return m_buf;
  }

  /**
   * @brief バッファ設定
   */
  void setBuf(char* buf) {
    m_buf = buf;
  }

  /**
   * @brief 読み出し
   * @param [out] data
   * @param [in] size
   * @return 読み出しデータサイズ(エラー時は 0 未満)
   */
  virtual int read(char* data, int size);

  /**
   * @brief 書き込み
   * @param [in] data
   * @param [in] size
   * @return 書き込みデータサイズ(エラー時は 0 未満)
   */
  virtual int write(char* data, int size);

 private:
  // インスタンスのコピーは想定しない(Klockwork指摘対応:CL.FFM.COPY)
  AXCRingBuf(const AXCRingBuf& obj)
      : m_buf(obj.m_buf),
        m_size(obj.m_size) {
  }

 private:
  // インスタンスのコピーは想定しない(Klockwork指摘対応:CL.FFM.ASSIGN)
  AXCRingBuf& operator=(const AXCRingBuf&) {
    return *this;
  }
};

#endif /* AXCRINGBUF_HPP_ */
