/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2015/02/22 - 2015/04/07
/// 
/// @brief  送信パイプレギュレータ
/// 
/// ****************************************************************************

#include "CPL_Core_PipeCacheManager.h"

namespace CPL {
namespace Core {


// _____________________________________________________________________________
/// @brief コンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PipeCacheManager::PipeCacheManager
( _in<size_t      > in_size_max_cache
, _in<td_time_msec> in_timeout_default
) : m_size_cache_max( in_size_max_cache )
  , m_timeout_default( in_timeout_default )
  //, m_sp_mutex_cache_queue_push( new ThreadMutex<std::recursive_timed_mutex> )
  //, m_sp_mutex_cache_queue_pop ( new ThreadMutex<std::recursive_timed_mutex> )
{
  m_itr_active_buffer_block = m_cache_buffer_list_front.begin();

  dbg_buf_list.resize( 100 );
}

// _____________________________________________________________________________
/// @brief キャッシュへ追記。
/// 
/// @param[in] in_addr_src   : 追記するデータを指すアドレス。
/// @param[in] in_size_write : 追記するデータサイズ。
/// 
/// @return
/// 追記されたデータサイズを返す。\n
/// 追記することで最大キャッシュサイズを超える場合、追記せず0を返す。\n
/// 追記データサイズそのものが最大キャッシュサイズを超える場合、-1(全ビットON)を返す。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
size_t
  PipeCacheManager::Store
    ( pin<void  > in_addr_src
    , _in<size_t> in_size_write
    )
{
  if( in_size_write > m_size_cache_max )
  {
    return -1;
  }
  ByteBuffer tmp_buf( in_size_write );

  CPL_EXCTION_( m_timeout_default, m_mutex_cache_push )
  {
    if( m_size_cache_now + in_size_write > m_size_cache_max )
    {
      return 0;
    }
    m_size_cache_now += in_size_write;
    dbg_size_store += in_size_write;

    // user buffer -> cache
    memcpy( &tmp_buf[0], in_addr_src, in_size_write );
    dbg_buf_list.pop_front();
    dbg_buf_list.push_back(tmp_buf);
    m_cache_buffer_list_back.push_back( std::move(tmp_buf) );

    if( Config::Communicator::ShowMsg_CacheStore )
    {
      size_t size_cache_now = m_size_cache_now.load();
      str_type tmp_str[1024];
      CPL_SPRINTF
        ( tmp_str
        , SwS("CorePLi: [time:%.6lf][TID:%Iu]: store: [add:%I64u][new cache size:%d][list")
        , std::chrono::duration_cast<td_time_usec>(TimeCounter::StaticPoint()).count() / 1000000.0
        , GetThreadID()
        , (U64)in_size_write
        , (int)size_cache_now
        );
      Core::String s( tmp_str );
      size_t dbg_cnt = 0;
      size_t dbg_n_cnt = 0;
      //for( auto& buf : m_cache_buffer_list )
      for( auto it = m_cache_buffer_list_back.begin(); it != m_cache_buffer_list_back.end(); ++it )
      {
        auto& buf = *it;
        auto size_ = buf.size();
        if( dbg_n_cnt < 10 )
        {
          s << SwS("/") << (int)size_;
        }
        ++dbg_n_cnt;
        dbg_cnt += size_;
      }
      if( m_cache_buffer_list_back.size() > 10 )
      {
        s << SwS("...");
      }
      s << SwS("]\n");

      CPL_OUTPUT( s.GetTop() );
    }

    return in_size_write;
  }
  return 0;
}

// _____________________________________________________________________________
/// @brief キャッシュへ追記（ByteBuffer仕様）
/// 
/// @param[in] in_buffer
///   : 追記データが格納されたByteBufferオブジェクトへの参照。
/// 
/// @return
/// 追加されたデータサイズを返す。\n
/// 追記することで最大キャッシュサイズを超える場合、0を返す。\n
/// 追記データサイズそのものが最大キャッシュサイズを超える場合、-1(全ビットON)を返す。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
size_t
  PipeCacheManager::Store( cref<ByteBuffer> in_buffer )
{
  return Store( &in_buffer[0], in_buffer.size() );
}


// _____________________________________________________________________________
/// @brief キャッシュへ追記（ByteBuffer仕様）
/// 
/// @param[in] in_buffer
///   : 追記データが格納されたByteBufferオブジェクトへの右辺値参照。
/// 
/// @return
/// 追加されたデータサイズを返す。\n
/// 通常、設定されたキャッシュサイズを超えるデータは追記できないが、
/// 右辺値参照で渡されたオブジェクトはそのまま保持されるので、キャッシュサイズを
/// 超えることが許可されている。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
size_t
  PipeCacheManager::Store( rvref<ByteBuffer> in_buffer )
{
  // user buffer -> cache
  CPL_EXCTION_( m_timeout_default, m_mutex_cache_push )
  {
    m_size_cache_now += in_buffer.size();

    m_cache_buffer_list_back.push_back( std::move(in_buffer) );
  }
  
  return in_buffer.size();
}


// _____________________________________________________________________________
/// @brief キャッシュから読み込み。
/// 
/// @param[out] out_addr_dest
///   : 読込先のアドレス。
/// @param[in]  in_size_read_min
///   : 最低読み込みサイズ。\n
///   : このサイズを読み込むことができない場合、シークせず０を返す。
/// @param[in]  in_size_read_max
///   : 最大読み込み可能サイズ。\n
///   : in_size_read_min未満を指定するとin_size_read_minに補正される。
/// @param[in]  in_is_flush
///   : 現在地より前にあるキャッシュブロックを解放するかどうか。\n
///   : true  - 解放する。\n
///   : false - 解放しない。
/// 
/// @return
/// 実際に読み込まれたサイズ。\n
/// in_size_read_minのサイズ分読み込む事ができない場合0を返す。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
size_t
  PipeCacheManager::Load
    ( pout<void  > out_addr_dest
    , _in <size_t> in_size_read_min
    , _in <size_t> in_size_read_max
    , _in <bool  > in_is_flush
    )
{
  const auto size_read_min = in_size_read_min;
  const auto size_read_max = Max( in_size_read_max, size_read_min );
  if( size_read_max == 0 )
  {
    return 0;
  }
  size_t size_cache = GetCacheSizeNow();
  if( size_cache < size_read_min )
  {
    return 0;
  }

  auto load_info = GetLoadInfo();

  if( load_info.addr == nullptr ) // データなし。
  {
    return 0;
  }

  size_t size_read = Min( size_read_max, load_info.size );

  // cache -> user buffer
  memcpy( out_addr_dest, load_info.addr, size_read );
  

  if( size_read < size_read_min )
  {
    Seek( size_read, false );
    return
      size_read +
      Load
        ( static_cast<char_ptr>(out_addr_dest) + size_read
        , size_read_min - size_read
        , size_read_max - size_read
        , in_is_flush
        );
  }
  else
  {
    return Seek( size_read, in_is_flush );
  }
}


// _____________________________________________________________________________
/// @brief フロントキャッシュから読み込み。
/// 
/// @param[out] out_buffer
///   : 読み込み用のバッファ。
/// @param[in]  in_size_read_min
///   : 最低読み込みサイズ。\n
///   : このサイズを読み込むことができない場合、シークせず０を返す。
/// @param[in]  in_size_read_max
///   : 最大読み込み可能サイズ。\n
///   : in_size_read_min未満を指定するとin_size_read_minに補正される。
/// @param[in]  in_is_flush
///   : 現在地より前にあるキャッシュブロックを解放するかどうか。\n
///   : true  - 解放する。\n
///   : false - 解放しない。
/// 
/// @return
/// 実際に読み込まれたサイズ。\n
/// in_size_read_minのサイズ分読み込む事ができない場合0を返す。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
size_t
  PipeCacheManager::Load
    ( rout<ByteBuffer> out_buffer
    , _in <size_t    > in_size_read_min
    , _in <size_t    > in_size_read_max
    , _in <bool      > in_is_flush
    )
{
  const auto size_read_min = in_size_read_min;
  const auto size_read_max = Max( in_size_read_max, size_read_min );
  if( size_read_max == 0 )
  {
    return 0;
  }
  auto size_cache = GetCacheSizeNow();
  if( size_cache < size_read_min )
  {
    return 0;
  }
  
  size_t size_buf_new = Min( size_cache, size_read_max );
  size_t size_begin = out_buffer.size();
  out_buffer.resize( size_begin + size_buf_new );

  return
    Load
      ( &out_buffer[ size_begin ]
      , size_read_min
      , size_read_max
      , in_is_flush
      );
}


// _____________________________________________________________________________
/// @brief フロントキャッシュとバックキャッシュの結合。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void PipeCacheManager::zzf_spliceCacke_() const
{
  if( !m_cache_buffer_list_back.empty() )
  {
    auto lock2 = Core::LockMutex( m_mutex_cache_push );

    bool is_head = (m_itr_active_buffer_block == m_cache_buffer_list_front.begin());
    bool is_end  = (m_itr_active_buffer_block == m_cache_buffer_list_front.end());
    auto itr_old_prev =
      (is_end  &&  !m_cache_buffer_list_front.empty())
        ? std::prev(m_cache_buffer_list_front.end())
        : m_itr_active_buffer_block;

    m_cache_buffer_list_front.splice
      ( m_cache_buffer_list_front.end()
      , m_cache_buffer_list_back
      );

    if( is_head )
    {
      m_itr_active_buffer_block = m_cache_buffer_list_front.begin();
    } else
    if( is_end )
    {
      m_itr_active_buffer_block = std::next(itr_old_prev);
    }
  }
}

// _____________________________________________________________________________
/// @brief 現在の読み込み開始アドレスと読み出し可能サイズを取得。
/// 
/// @return
/// 読み出しアドレスと読み出し可能最大サイズをstd::pair<void_cptr,size_t>型で返す。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
auto PipeCacheManager::GetLoadInfo() const -> LoadInfo
{
  // 要素無効化の可能性があるため、ポップ用ミューテックスで保護
  auto lock = Core::LockMutex( m_mutex_cache_pop );

  zzf_spliceCacke_();

  if( m_itr_active_buffer_block == m_cache_buffer_list_front.end() )
  {
    return LoadInfo{ nullptr, 0/*, false*/ };
  }

  auto& buf = *m_itr_active_buffer_block;
  return
    LoadInfo
      { &buf[ m_pos_cache ]
      , buf.size() - m_pos_cache
      //, m_pos_cache == 0
      };
}

// _____________________________________________________________________________
/// @brief 次のパケットの読み込み開始アドレスと読み出し可能サイズを取得。
/// 
/// @return
/// 読み出しアドレスと読み出し可能最大サイズをstd::pair<void_cptr,size_t>型で返す。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
auto PipeCacheManager::GetNextLoadInfo() const -> LoadInfo
{
  // 要素無効化の可能性があるため、ポップ用ミューテックスで保護
  auto lock = Core::LockMutex( m_mutex_cache_pop );

  zzf_spliceCacke_();

  if( !m_cache_buffer_list_back.empty() )
  {
    auto lock2 = Core::LockMutex( m_mutex_cache_push );
    m_cache_buffer_list_front.splice
      ( m_cache_buffer_list_front.end()
      , m_cache_buffer_list_back
      );
  }

  auto it_now  = m_itr_active_buffer_block;
  auto it_next = it_now; ++it_next;
  auto it_end  = m_cache_buffer_list_front.end();
  if( it_now == it_end  ||  it_next == it_end )
  {
    return LoadInfo{ nullptr, 0/*, false*/ };
  }

  auto& buf = *it_now;
  return
    LoadInfo
      { &buf[ m_pos_cache ]
      , buf.size() - m_pos_cache
      //, m_pos_cache == 0
      };
}


// _____________________________________________________________________________
/// @brief 読み出し位置を進める。
/// 
/// @return 実際に移動された値を返す。
///
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SDEF PipeCacheManager::Seek( _in<SDEF> in_seek_value, _in<bool> in_is_flush )
{
  if( in_seek_value > 0 )
  {
    return zzf_seekNext_( in_seek_value, in_is_flush );
  }
  else
  if( in_seek_value < 0 )
  {
    return zzf_seekPrev_( -in_seek_value, in_is_flush );
  }
  return 0;
}


// _____________________________________________________________________________
/// @brief 後方シーク
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SDEF PipeCacheManager::zzf_seekNext_( size_t in_seek_value, bool in_is_flush )
{
  if( m_itr_active_buffer_block == m_cache_buffer_list_front.end() )
  {
    if( in_is_flush )
    {
      Flush();
    }
    return 0;
  }

  auto seek_req_value = in_seek_value; // 現在要求するシーク量
  auto lock = Core::LockMutex( m_mutex_cache_pop ); // シーク中はpopに対してのみ保護する。

  while( true )
  {
    auto& buf = *m_itr_active_buffer_block;
    // シーク量がバッファブロックのサイズを超える場合。
    if( m_pos_cache + seek_req_value >= buf.size() )
    {
      auto move_req_value = (buf.size() - m_pos_cache);
      seek_req_value -= move_req_value;
      m_pos_cache = 0;
      ++m_itr_active_buffer_block; // 次のバッファブロックへ。

      if( m_itr_active_buffer_block == m_cache_buffer_list_front.end() )
      {
        break;
      }
    }
    // シーク量がバッファブロックのサイズを超えない場合。
    else
    {
      m_pos_cache += seek_req_value;
      seek_req_value = 0;
      break;
    }
  }

  if( in_is_flush )
  {
    Flush();
  }

  return in_seek_value - seek_req_value;
}

// _____________________________________________________________________________
/// @brief 前方シーク
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SDEF PipeCacheManager::zzf_seekPrev_( size_t in_seek_value, bool in_is_flush )
{
  auto seek_req_value = in_seek_value;
  auto lock = Core::LockMutex( m_mutex_cache_pop );

  while( true )
  {
    if( m_pos_cache < seek_req_value )
    {
      seek_req_value -= m_pos_cache;
      if( m_itr_active_buffer_block == m_cache_buffer_list_front.begin() )
      {
        m_pos_cache = 0;
        break;
      }
      --m_itr_active_buffer_block;
      m_pos_cache = m_itr_active_buffer_block->size();
    }
    else
    {
      m_pos_cache -= seek_req_value;
      seek_req_value = 0;
      break;
    }
  }
  if( in_is_flush )
  {
    Flush();
  }
  return in_seek_value - seek_req_value;
}


// _____________________________________________________________________________
/// @brief
/// 現在位置より前にあるキャッシュブロックを削除。
/// 
/// @retval true  : 削除された要素がある。
/// @retval false : 削除された要素はない。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool PipeCacheManager::Flush()
{
  // アクティブな要素が先頭でなければ、それより前方にある要素を削除する。
  if( m_itr_active_buffer_block != m_cache_buffer_list_front.begin() )
  {
    auto   lock = Core::LockMutex( m_mutex_cache_pop );
    auto   size_cache = m_size_cache_now.load();

    for( auto it_ = m_cache_buffer_list_front.begin()
       ; it_ != m_itr_active_buffer_block
       ; ++it_ )
    {
      // アトミック変数は遅いので非アトミック変数に移して計算しようかと思ったが、
      // その場合はロックが必要になり、アトミック変数の操作より長い間のロック
      // が必要になると考えられるため、そのまま計算した方が良いと判断した。
      // なので、下手にいじらないこと。
      m_size_cache_now -= it_->size();
      dbg_size_load += it_->size();
    }
    m_cache_buffer_list_front.erase
      ( m_cache_buffer_list_front.begin()
      , m_itr_active_buffer_block
      );

    if( Config::Communicator::ShowMsg_CacheFlush )
    {
      CPL_OUTPUT
        ( SwS("CorePLi: [time:%.6lf][TID:%Iu]: flush: [new cache size:%d]\n")
        , std::chrono::duration_cast<td_time_usec>(TimeCounter::StaticPoint()).count() / 1000000.0
        , GetThreadID()
        , (U64)m_size_cache_now
        );
    }

    return m_size_cache_now != size_cache;
  }
  return false;
}


/*
// _____________________________________________________________________________
/// @brief 受信キャッシュから読み込み。
/// 
/// 転送元のデータが更新されていなければ、すぐに処理を返す。\n
/// データの受信待ちをする場合は、Recvを呼び出す前に、
/// WaitStateEqual(CPL::Core::FlagPipeState::Update)を用いること。
/// 
/// @param[out] out_ptr_buf
///   : データ取得用のバッファへのポインタ。\n
///   : この領域は、最低でも設定されている共有バッファ以上のサイズが確保されていなければならない。
/// @param[in] in_time_point_end
///   : タイムアウトとするタイムポイント(TimePoint)を指定。\n
///   : 現時点からオフセットで指定する場合はstd::chrono::durationで指定する(CPL::td_time_msec等でもよし)。\n
///   : 実質タイムアウトさせない場合、TimePoint::Max()を指定する。
/// 
/// @return Transceiver::ResultTransRecvを返す。
/// 
/// @note
/// 読み込み手順は以下の通り。\n
/// 1. 自身の状態をチェック。
/// 2. モードがIntaractiveの場合はRequestチェックとReady設定。
/// 3. 相手側の状態フラグがUpdatingまたはUpdateでなければ抜ける。\n
/// 4. 自身のフラグがReadyの間は待機。
/// 5. 
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ResultTransRecv
  PipeRecvRegulator::Recv
    ( rio <PipeParameter> in_pipe_param
    , pout<void         > out_ptr_buf
    , _in <TimePoint    > in_time_point_end
    )
{
  ////auto size_init = out_buf.size();
  auto sp_buffer = PipeRegulator::GetSharedBuffer( in_pipe_param );
  auto const& mem_name = sp_buffer->GetSharedBufferName(); // デバッグ用
  try
  {
    // 例外設定を一時的に設定。
    // 自身の関数には、エラーおよびタイムアウトの場合例外を投げてもらうようにする。
    TempOptionThrow tmp_op_change( &in_pipe_param, true, true );

    CPL_THROW_X_IF
      ( sp_buffer == nullptr
      , ResultPipe::Error_Invalid_SharedBuffer
      , "%s : Memory pipe for receiving has timed out.\n", mem_name
      )

    auto trans_mode    = GetPipeMode( in_pipe_param );
    auto state_myself  = GetPipeState_forMyself( in_pipe_param );
    auto state_partner = GetPipeState_forPartner( in_pipe_param );

    // 相手が無効の場合。
    CPL_THROW_X_IF
      ( state_partner == FlagPipeState::Empty
      , ResultPipe::Error_Empty_Partner
      , "Error : empty partner.\n"
      )

    // アクセス権チェック（待機）
    auto res_access = WaitUntilReadable( in_pipe_param, in_time_point_end );
    if( res_access == ResultPipe::Timeout_Myself )
    {
      return ResultTransRecv::NoneData;
    }

    auto locking = LockMutex( in_pipe_param.m_mutex_thread );

    ////// 受信処理が継続できる場合は、自身の状態がWait,Timeout,OverSizeの場合。
    ////// そうでなければ、状態異常として例外または戻り値を返す。
    ////bool flag_enable = 
    ////  (state_myself == FlagPipeState::Wait    ||
    ////   state_myself == FlagPipeState::Timeout ||
    ////   state_myself == FlagPipeState::OverSize);
    ////CPL_THROW_X_IF
    ////  ( !flag_enable
    ////  , ResultPipe::Error_Invalid_State
    ////  , "Invalid state.\n"
    ////  )

    ////// モードがインタラクティブの場合、一度リクエスト待ちをし、受信準備完了フラグをセットする。
    ////if( trans_mode == FlagPipeMode::Interactive )
    ////{
    ////  WaitStateEqual( in_pipe_param, FlagPipeState::Request, in_time_point_end );
    ////  ChangePipeState( in_pipe_param, FlagPipeState::Ready, in_time_point_end );
    ////}
  
    // 状態初期化。
    //ChangePipeState( FlagPipeState::Wait, in_time_point_end );

    // 
    PipeHeader header_info;
    GetPipeHeader( in_pipe_param, header_info );

    //// 転送元が更新された場合。
    ////state_myself  = GetPipeState_forMyself( in_pipe_param );
    ////state_partner = GetPipeState_forPartner( in_pipe_param );
    ////if( state_partner == FlagPipeState::Request  ||
    ////    state_partner == FlagPipeState::Updating )
    ////{
    ////  WaitStateEqual( in_pipe_param, FlagPipeState::Update, in_time_point_end );
    ////  state_partner = FlagPipeState::Update;
    ////}
    ////if( flag_access == StatePipeAccess::Updated )
    ////{
      ////while( true )
      ////{
        ////// 転送元（相手）の状態がUpdateになるまで待機する(最初は必ずヒットする)
        ////WaitStateEqual
        ////  ( in_pipe_param
        ////  , FlagPipeState::Update
        ////  , in_time_point_end
        ////  , &header_info
        ////  );

        //// 転送先（自身）のフラグを"読み込み中"にセット。
        //ChangePipeState
        //  ( in_pipe_param
        //  , FlagPipeState::Reading
        //  , in_time_point_end
        //  );

        // 
        U32 data_size = header_info.buf_size;
        ////auto pos_ins = out_buf.size();
        ////out_buf.resize( pos_ins + data_size );
        // データ部読み込み
        size_t read_offset = PipeHeader::GetHeaderSize();
        if( !sp_buffer->Read( read_offset, out_ptr_buf, data_size ) )
        {
          ChangePipeState
            ( in_pipe_param
            , FlagPipeState::RecvError
            , in_time_point_end
            );
          return ResultTransRecv::Error;
        }

        ////// 転送先（自身）のフラグを"読み込み完了"に設定。
        ////ChangePipeState( in_pipe_param, FlagPipeState::Readed, in_time_point_end );

        //// 転送元（相手）の"Wait"待ち。
        //WaitStateEqual( in_pipe_param, FlagPipeState::Wait, in_time_point_end );

        //// 転送先（自身）のフラグを"Wait"に設定。
        //ChangePipeState( in_pipe_param, FlagPipeState::Wait, in_time_point_end );

        // 読み込み完了チェック
        if( header_info.total_size <= out_buf.size() )
        {
          // 読み込み完了していた場合、ループを抜ける。
          break;
        }
      ////}

      // 読み込み正常終了
      return ResultTransRecv::Received;
    ////}
    ////else
    ////{
    ////  return ResultTransRecv::NoneData;
    ////}

    ////return ResultTransRecv::NoneData;
  }
  catch( ResultPipe res_trans )
  {
    switch( res_trans )
    {
    case ResultPipe::Timeout_Myself:
      ChangePipeState( in_pipe_param, FlagPipeState::Timeout, td_time_msec(500) );
      return ResultTransRecv::Timeout_Myself;
    case ResultPipe::Timeout_Partner:
      ChangePipeState( in_pipe_param, FlagPipeState::Timeout, td_time_msec(500) );
      return ResultTransRecv::Timeout_Partner;
    default:
      ChangePipeState( in_pipe_param, FlagPipeState::RecvError, td_time_msec(500) );
      return ResultTransRecv::Error;
    }
  }
  catch( std::bad_alloc const& )
  {
    ChangePipeState( in_pipe_param, FlagPipeState::OverSize, td_time_msec(500) );
    return ResultTransRecv::ErrorAlloc;
  }
  catch(...)
  {
    ChangePipeState( in_pipe_param, FlagPipeState::RecvError, td_time_msec(500) );
    return ResultTransRecv::Error;
  }
}
*/


} // namespace Core
} // namespace CPL
