#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