summaryrefslogblamecommitdiff
path: root/htk_io/src/KaldiLib/StkStream.tcc
blob: e3de1ae5a089de1244c47e03ac05233f1baf538f (plain) (tree)



































































































































































































































                                                                                  
#ifndef TNet_StkStream_tcc
#define TNet_StkStream_tcc

#include <cstring>
#include <iostream>

#include "Common.h"

#pragma GCC system_header

namespace TNet
{
  
  //******************************************************************************
  template<
    typename _CharT, 
    typename _Traits
  > 
  basic_stkbuf<_CharT, _Traits> *
  basic_stkbuf<_CharT, _Traits>::
  close(void)
  {
    // we only want to close an opened file
    if (this->is_open())
    {
      // we want to call the parent close() procedure
      std::basic_filebuf<_CharT, _Traits>::close();

      // and for different stream type we perform different closing
      if (mStreamType == basic_stkbuf::t_file)
      {
        fclose(mpFilePtr);
      }
      else if (mStreamType == basic_stkbuf::t_pipe)
      {
        pclose(mpFilePtr);
      }
      else if (mStreamType == basic_stkbuf::t_stdio)
      {

      }
      
      mpFilePtr     = NULL;
      mFilename    = "";
      mMode        = std::ios_base::openmode(0);
      mStreamType = basic_stkbuf::t_undef;
      return this;
    }
    else
      return 0;
  }


  template<
    typename _CharT, 
    typename _Traits
  > 
  void
  basic_stkbuf<_CharT, _Traits>::
  open_mode(std::ios_base::openmode __mode, int&, int&,  char* __c_mode)
  {
    bool __testb = __mode & std::ios_base::binary;
    bool __testi = __mode & std::ios_base::in;
    bool __testo = __mode & std::ios_base::out;
    bool __testt = __mode & std::ios_base::trunc;
    bool __testa = __mode & std::ios_base::app;

    if (!__testi && __testo && !__testt && !__testa)
      strcpy(__c_mode, "w");
    if (!__testi && __testo && !__testt && __testa)
      strcpy(__c_mode, "a");
    if (!__testi && __testo && __testt && !__testa)
      strcpy(__c_mode, "w");
    if (__testi && !__testo && !__testt && !__testa)
      strcpy(__c_mode, "r");
    if (__testi && __testo && !__testt && !__testa)
      strcpy(__c_mode, "r+");
    if (__testi && __testo && __testt && !__testa)
      strcpy(__c_mode, "w+");
    if (__testb)
      strcat(__c_mode, "b");
  }


  //******************************************************************************
  template<
    typename _CharT, 
    typename _Traits
  > 
  basic_stkbuf<_CharT, _Traits> *
  basic_stkbuf<_CharT, _Traits>::
  open(const char* pFName, std::ios::openmode m, const char* pFilter)
  {
    basic_stkbuf<_CharT, _Traits>* p_ret = NULL;

    if (NULL == pFName)
      return NULL;
      
    // we need to assure, that the stream is not open
    if (!this->is_open())
    {
      char mstr[4] = {'\0', '\0', '\0', '\0'};
      int __p_mode = 0;
      int __rw_mode = 0;

      // now we decide, what kind of file we open
      if (!strcmp(pFName,"-"))
      {
        if      ((m & std::ios::in) && !(m & std::ios::out))
        {
          mpFilePtr   = stdin;
          mMode       = std::ios::in;
          mFilename   = pFName;
          mStreamType = t_stdio;
          p_ret       = this;
        }
        else if ((m & std::ios::out) && !(m & std::ios::in))
        {
          mpFilePtr   = stdout;
          mMode       = std::ios::out;
          mFilename   = pFName;
          mStreamType = t_stdio;
          p_ret       = this;
        }
        else
          p_ret = NULL;
      }
      else if ( pFName[0] == '|' )
      {
        const char* command = pFName + 1;

        if      ((m & std::ios::in) && !(m & std::ios::out)) m = std::ios::in;
        else if ((m & std::ios::out) && !(m & std::ios::in)) m = std::ios::out;
        else return NULL;

        // we need to make some conversion
        // iostream -> stdio open mode string
        this->open_mode(m, __p_mode, __rw_mode, mstr);

        if ((mpFilePtr = popen(command, mstr)))
        {
          mFilename   = command;
          mMode       = m;
          mStreamType = t_pipe;
          p_ret       = this;
        }
        else
          p_ret = 0;
      }
      else
      {
        // maybe we have a filter specified
        if ( pFilter 
        && ('\0' != pFilter[0]))
        {
          char* command = ExpandHtkFilterCmd(pFilter, pFName, "$");

          if      ((m & std::ios::in) && !(m & std::ios::out)) m = std::ios::in;
          else if ((m & std::ios::out) && !(m & std::ios::in)) m = std::ios::out;
          else return NULL;

          // we need to make some conversion
          // iostream -> stdio open mode string
          this->open_mode(m, __p_mode, __rw_mode, mstr);

          if ((mpFilePtr = popen(command, mstr)))
          {
            mFilename     = pFName;
            mMode         = m;
            mStreamType   = t_pipe;
            p_ret         = this;
          }
          else
            p_ret = 0;
        }
        else // if (!filter.empty())
        {
          // we need to make some conversion
          // iostream -> stdio open mode string
          this->open_mode(m, __p_mode, __rw_mode, mstr);

          if ((mpFilePtr = fopen(pFName, mstr)))
          {
            mFilename   = pFName;
            mMode       = m;
            mStreamType = t_file;
            p_ret       = this;
          }
          else {
            p_ret = NULL;
          }
        }
      }

      // here we perform what the stdio_filebuf would do
      if (p_ret) {
        superopen(mpFilePtr, m);
      }
    } //if (!isopen)

    return p_ret;
  }

  //******************************************************************************
  template<
    typename _CharT, 
    typename _Traits
  > 
  void
  basic_stkbuf<_CharT, _Traits>::
  superopen(std::__c_file* __f, std::ios_base::openmode __mode,
        size_t __size)
  {
    this->_M_file.sys_open(__f, __mode);
    if (this->is_open())
    {
      this->_M_mode = __mode;
      this->_M_buf_size = __size;
      this->_M_allocate_internal_buffer();
      this->_M_reading = false;
      this->_M_writing = false;
      this->_M_set_buffer(-1);
    }
  }
}

// TNet_StkStream_tcc
#endif