2008-10-14 05:32:58 +00:00
|
|
|
/*
|
2011-09-05 10:21:54 +00:00
|
|
|
* $Id: tio.c 559 2011-09-04 16:21:54Z hyunghwan.chung $
|
2009-01-06 04:40:25 +00:00
|
|
|
*
|
2011-04-23 08:28:43 +00:00
|
|
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
2009-09-16 04:01:02 +00:00
|
|
|
This file is part of QSE.
|
2009-01-06 04:40:25 +00:00
|
|
|
|
2009-09-16 04:01:02 +00:00
|
|
|
QSE is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Lesser General Public License as
|
|
|
|
published by the Free Software Foundation, either version 3 of
|
|
|
|
the License, or (at your option) any later version.
|
2009-01-06 04:40:25 +00:00
|
|
|
|
2009-09-16 04:01:02 +00:00
|
|
|
QSE is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Lesser General Public License for more details.
|
2009-01-06 04:40:25 +00:00
|
|
|
|
2009-09-16 04:01:02 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
2008-10-14 05:32:58 +00:00
|
|
|
*/
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
#include <qse/cmn/tio.h>
|
2008-10-14 05:32:58 +00:00
|
|
|
#include "mem.h"
|
|
|
|
|
2009-02-02 04:12:49 +00:00
|
|
|
QSE_IMPLEMENT_COMMON_FUNCTIONS (tio)
|
2009-01-15 03:58:27 +00:00
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
qse_tio_t* qse_tio_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_tio_t* tio;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (mmgr == QSE_NULL)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
mmgr = QSE_MMGR_GETDFL();
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERTX (mmgr != QSE_NULL,
|
|
|
|
"Set the memory manager with QSE_MMGR_SETDFL()");
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (mmgr == QSE_NULL) return QSE_NULL;
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
tio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_tio_t) + xtnsize);
|
2008-12-21 21:35:07 +00:00
|
|
|
if (tio == QSE_NULL) return QSE_NULL;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
if (qse_tio_init (tio, mmgr) <= -1)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_MMGR_FREE (mmgr, tio);
|
|
|
|
return QSE_NULL;
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return tio;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_tio_close (qse_tio_t* tio)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
int n = qse_tio_fini (tio);
|
|
|
|
QSE_MMGR_FREE (tio->mmgr, tio);
|
2008-10-14 05:32:58 +00:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
int qse_tio_init (qse_tio_t* tio, qse_mmgr_t* mmgr)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2010-08-27 00:26:28 +00:00
|
|
|
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_MEMSET (tio, 0, QSE_SIZEOF(*tio));
|
2008-10-14 05:32:58 +00:00
|
|
|
|
|
|
|
tio->mmgr = mmgr;
|
|
|
|
|
|
|
|
/*
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->input_func = QSE_NULL;
|
|
|
|
tio->input_arg = QSE_NULL;
|
|
|
|
tio->output_func = QSE_NULL;
|
|
|
|
tio->output_arg = QSE_NULL;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
tio->input_status = 0;
|
|
|
|
tio->inbuf_curp = 0;
|
|
|
|
tio->inbuf_len = 0;
|
|
|
|
tio->outbuf_len = 0;
|
2008-10-14 05:32:58 +00:00
|
|
|
*/
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->errnum = QSE_TIO_ENOERR;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
return 0;
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_tio_fini (qse_tio_t* tio)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_tio_flush (tio); /* don't care about the result */
|
|
|
|
if (qse_tio_detachin(tio) == -1) return -1;
|
|
|
|
if (qse_tio_detachout(tio) == -1) return -1;
|
2008-10-14 05:32:58 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-09-08 06:29:25 +00:00
|
|
|
qse_tio_errnum_t qse_tio_geterrnum (qse_tio_t* tio)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
|
|
|
return tio->errnum;
|
|
|
|
}
|
|
|
|
|
2009-02-02 04:12:49 +00:00
|
|
|
const qse_char_t* qse_tio_geterrmsg (qse_tio_t* tio)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2009-02-02 04:12:49 +00:00
|
|
|
static const qse_char_t* __errmsg[] =
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_T("no error"),
|
|
|
|
QSE_T("out of memory"),
|
|
|
|
QSE_T("no more space"),
|
|
|
|
QSE_T("illegal multibyte sequence"),
|
|
|
|
QSE_T("incomplete multibyte sequence"),
|
|
|
|
QSE_T("illegal wide character"),
|
|
|
|
QSE_T("no input function attached"),
|
|
|
|
QSE_T("input function returned an error"),
|
|
|
|
QSE_T("input function failed to open"),
|
|
|
|
QSE_T("input function failed to closed"),
|
|
|
|
QSE_T("no output function attached"),
|
|
|
|
QSE_T("output function returned an error"),
|
|
|
|
QSE_T("output function failed to open"),
|
|
|
|
QSE_T("output function failed to closed"),
|
|
|
|
QSE_T("unknown error")
|
2008-10-14 05:32:58 +00:00
|
|
|
};
|
|
|
|
|
2009-02-02 04:12:49 +00:00
|
|
|
return __errmsg[
|
|
|
|
(tio->errnum < 0 || tio->errnum >= QSE_COUNTOF(__errmsg))?
|
|
|
|
QSE_COUNTOF(__errmsg) - 1: tio->errnum];
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_tio_attachin (qse_tio_t* tio, qse_tio_io_t input, void* arg)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
if (qse_tio_detachin(tio) == -1) return -1;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (tio->input_func == QSE_NULL);
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (input(QSE_TIO_IO_OPEN, arg, QSE_NULL, 0) == -1)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->errnum = QSE_TIO_EINPOP;
|
2008-10-14 05:32:58 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
tio->input_func = input;
|
|
|
|
tio->input_arg = arg;
|
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
tio->input_status = 0;
|
|
|
|
tio->inbuf_curp = 0;
|
|
|
|
tio->inbuf_len = 0;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_tio_detachin (qse_tio_t* tio)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
if (tio->input_func != QSE_NULL)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
|
|
|
if (tio->input_func (
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_TIO_IO_CLOSE, tio->input_arg, QSE_NULL, 0) == -1)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->errnum = QSE_TIO_EINPCL;
|
2008-10-14 05:32:58 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->input_func = QSE_NULL;
|
|
|
|
tio->input_arg = QSE_NULL;
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_tio_attachout (qse_tio_t* tio, qse_tio_io_t output, void* arg)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
if (qse_tio_detachout(tio) == -1) return -1;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (tio->output_func == QSE_NULL);
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (output(QSE_TIO_IO_OPEN, arg, QSE_NULL, 0) == -1)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->errnum = QSE_TIO_EOUTOP;
|
2008-10-14 05:32:58 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
tio->output_func = output;
|
|
|
|
tio->output_arg = arg;
|
2011-09-05 10:21:54 +00:00
|
|
|
tio->outbuf_len = 0;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_tio_detachout (qse_tio_t* tio)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
if (tio->output_func != QSE_NULL)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_tio_flush (tio); /* don't care about the result */
|
2008-10-14 05:32:58 +00:00
|
|
|
|
|
|
|
if (tio->output_func (
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_TIO_IO_CLOSE, tio->output_arg, QSE_NULL, 0) == -1)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->errnum = QSE_TIO_EOUTCL;
|
2008-10-14 05:32:58 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->output_func = QSE_NULL;
|
|
|
|
tio->output_arg = QSE_NULL;
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ssize_t qse_tio_flush (qse_tio_t* tio)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t left, count;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (tio->output_func == QSE_NULL)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->errnum = QSE_TIO_ENOUTF;
|
|
|
|
return (qse_ssize_t)-1;
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
left = tio->outbuf_len;
|
|
|
|
while (left > 0)
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ssize_t n;
|
2008-10-14 05:32:58 +00:00
|
|
|
|
|
|
|
n = tio->output_func (
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_TIO_IO_DATA, tio->output_arg, tio->outbuf, left);
|
2008-10-14 05:32:58 +00:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
|
|
|
tio->outbuf_len = left;
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->errnum = QSE_TIO_EOUTPT;
|
2008-10-14 05:32:58 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (n == 0) break;
|
|
|
|
|
|
|
|
left -= n;
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_MEMCPY (tio->outbuf, &tio->inbuf[n], left);
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
count = tio->outbuf_len - left;
|
|
|
|
tio->outbuf_len = left;
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
return (qse_ssize_t)count;
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
void qse_tio_purge (qse_tio_t* tio)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2011-09-05 10:21:54 +00:00
|
|
|
tio->input_status = 0;
|
|
|
|
tio->inbuf_curp = 0;
|
|
|
|
tio->inbuf_len = 0;
|
|
|
|
tio->outbuf_len = 0;
|
2008-12-21 21:35:07 +00:00
|
|
|
tio->errnum = QSE_TIO_ENOERR;
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|