/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2012/X/X - 2015/11/11
/// 
/// @brief  プロセス間メモリ転送マルチマネージャー
/// 
/// ****************************************************************************

#include "CPL_Core_MultiTransPipe.h"


namespace CPL {
namespace Core {

  
// _____________________________________________________________________________
/// @brief 転送パイプオブジェクトの登録
/// 
/// @param[in] in_pipe_ID
///   : 登録する転送パイプのID.
/// @param[in] in_sp_pipe
///   : 登録する転送パイプオブジェクトへのスマートポインタ。
/// 
/// @retval true  : 登録成功。
/// @retval false : 登録失敗。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool
  MultiPipeManager::EntryPipeTransceiver
    ( _in<td_TransPipeID> in_pipe_ID
    , _in<td_SpPipe     > in_sp_pipe
    )
{
  //
  m_TMI_sp_table[ in_pipe_ID ] = in_sp_pipe;

  return true;
}


// _____________________________________________________________________________
/// @brief 受信キャッシュからデータの読み込み
/// 
/// @param[in] in_pipe_ID
///   : 取得する転送パイプのID.
/// @param[out] out_buf
///   : データ取得用バッファ（ByteBuffer）への参照。
/// @param[in] in_time_point_end
///   : タイムアウトとするタイムポイント(TimePoint)を指定。\n
///   : 現時点からオフセットで指定する場合はstd::chrono::durationで指定する(CPL::td_time_msec等でもよし)。\n
///   : 実質タイムアウトさせない場合、TimePoint::Max()を指定する。
/// 
/// @return td_TypeRecvResult の値が返る。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MultiPipeManager::td_TypeRecvResult
  MultiPipeManager::Recv
    ( _in <td_TransPipeID> in_pipe_ID
    , rout<ByteBuffer    > out_buf
    , _in <TimePoint     > in_time_point_end
    )
{
  td_TypeRecvResult res;
  auto itr_tmi = m_TMI_sp_table.find( in_pipe_ID );
  if( itr_tmi == m_TMI_sp_table.end() ) // 該当なし。
  {
    res.first  = 0;
    res.second = eResultTransRecv::NoneData;
  }
  else
  if( auto* ptr_pipe_recv = dynamic_cast<PipeReceiver*>(itr_tmi->second.get()) )
  {
    res.first  = true;
    res.second = ptr_pipe_recv->Recv( out_buf, in_time_point_end );
  }
  else
  {
    res.first = 0;
    res.second = eResultTransRecv::Error;
  }
  return res;
}


// _____________________________________________________________________________
/// @brief 送信キャッシュへデータの書き込み
/// 
/// @param[in] in_pipe_ID
///   : 仕様する登録済みの転送パイプのID.
/// @param[in] in_buf
///   : データ取得用バッファ（ByteBuffer）への参照。
/// @param[in] in_time_point_end
///   : タイムアウトとするタイムポイント(TimePoint)を指定。\n
///   : 現時点からオフセットで指定する場合はstd::chrono::durationで指定する(CPL::td_time_msec等でもよし)。\n
///   : 実質タイムアウトさせない場合、TimePoint::Max()を指定する。
/// 
/// @return td_TypeSendResult の値が返る。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MultiPipeManager::td_TypeSendResult
  MultiPipeManager::Send
    ( _in<td_TransPipeID> in_pipe_ID
    , _in<ByteBuffer    > in_buf
    , _in<TimePoint     > in_time_point_end
    )
{
  td_TypeSendResult res;
  auto itr_tmi = m_TMI_sp_table.find( in_pipe_ID );
  if( itr_tmi == m_TMI_sp_table.end() ) // 該当なし。
  {
    res.first = 0;
    res.second = eResultTransSend::NoneData;
  }
  else
  if( auto* ptr_pipe_sender = dynamic_cast<PipeSender*>(itr_tmi->second.get() ) )
  {
    res.first  = true;
    res.second = ptr_pipe_sender->Send( in_buf, in_time_point_end );
  }
  else
  {
    res.first = 0;
    res.second = eResultTransSend::Error;
  }

  return res;
}


} // namespace Core
} // namespace CPL
