2008-12-01 00:20:35 +00:00
|
|
|
/*
|
|
|
|
* $Id: sio.c,v 1.30 2006/01/15 06:51:35 bacon Ease $
|
2009-01-06 04:40:25 +00:00
|
|
|
*
|
|
|
|
Copyright 2006-2008 Chung, Hyung-Hwan.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
2008-12-01 00:20:35 +00:00
|
|
|
*/
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
#include <qse/cmn/sio.h>
|
2008-12-01 00:20:35 +00:00
|
|
|
#include "mem.h"
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
static qse_ssize_t __sio_input (int cmd, void* arg, void* buf, qse_size_t size);
|
|
|
|
static qse_ssize_t __sio_output (int cmd, void* arg, void* buf, qse_size_t size);
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2008-12-10 00:52:03 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
static qse_sio_t __sio_in =
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_NULL, /* mmgr */
|
2008-12-01 00:20:35 +00:00
|
|
|
|
|
|
|
/* fio */
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_NULL,
|
2008-12-01 00:20:35 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
(HANDLE)STD_INPUT_HANDLE,
|
|
|
|
#else
|
|
|
|
0,
|
|
|
|
#endif
|
|
|
|
},
|
|
|
|
|
|
|
|
/* tio */
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_NULL,
|
2008-12-01 00:20:35 +00:00
|
|
|
0,
|
|
|
|
|
|
|
|
__sio_input,
|
|
|
|
__sio_output,
|
|
|
|
&__sio_in,
|
|
|
|
&__sio_in,
|
|
|
|
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
|
|
|
|
{ 0 },
|
|
|
|
{ 0 }
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
static qse_sio_t __sio_out =
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_NULL, /* mmgr */
|
2008-12-01 00:20:35 +00:00
|
|
|
|
|
|
|
/* fio */
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_NULL,
|
2008-12-01 00:20:35 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
(HANDLE)STD_OUTPUT_HANDLE,
|
|
|
|
#else
|
|
|
|
1
|
|
|
|
#endif
|
|
|
|
},
|
|
|
|
|
|
|
|
/* tio */
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_NULL,
|
2008-12-01 00:20:35 +00:00
|
|
|
0,
|
|
|
|
|
|
|
|
__sio_input,
|
|
|
|
__sio_output,
|
|
|
|
&__sio_out,
|
|
|
|
&__sio_out,
|
|
|
|
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
|
|
|
|
{ 0 },
|
|
|
|
{ 0 }
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
static qse_sio_t __sio_err =
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_NULL, /* mmgr */
|
2008-12-01 00:20:35 +00:00
|
|
|
|
|
|
|
/* fio */
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_NULL,
|
2008-12-01 00:20:35 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
(HANDLE)STD_ERROR_HANDLE,
|
|
|
|
#else
|
|
|
|
2
|
|
|
|
#endif
|
|
|
|
},
|
|
|
|
|
|
|
|
/* tio */
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_NULL,
|
2008-12-01 00:20:35 +00:00
|
|
|
0,
|
|
|
|
|
|
|
|
__sio_input,
|
|
|
|
__sio_output,
|
|
|
|
&__sio_err,
|
|
|
|
&__sio_err,
|
|
|
|
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
|
|
|
|
{ 0 },
|
|
|
|
{ 0 }
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_sio_t* qse_sio_in = &__sio_in;
|
|
|
|
qse_sio_t* qse_sio_out = &__sio_out;
|
|
|
|
qse_sio_t* qse_sio_err = &__sio_err;
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_sio_t* qse_sio_open (
|
|
|
|
qse_mmgr_t* mmgr, qse_size_t ext, const qse_char_t* file, int flags)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_sio_t* sio;
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (mmgr == QSE_NULL)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
mmgr = QSE_MMGR_GETDFL();
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERTX (mmgr != QSE_NULL,
|
|
|
|
"Set the memory manager with QSE_MMGR_SETDFL()");
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (mmgr == QSE_NULL) return QSE_NULL;
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
sio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_sio_t) + ext);
|
|
|
|
if (sio == QSE_NULL) return QSE_NULL;
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (qse_sio_init (sio, mmgr, file, flags) == QSE_NULL)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_MMGR_FREE (mmgr, sio);
|
|
|
|
return QSE_NULL;
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return sio;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
void qse_sio_close (qse_sio_t* sio)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_sio_fini (sio);
|
|
|
|
QSE_MMGR_FREE (sio->mmgr, sio);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_sio_t* qse_sio_init (
|
|
|
|
qse_sio_t* sio, qse_mmgr_t* mmgr, const qse_char_t* file, int flags)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2009-01-18 00:44:31 +00:00
|
|
|
int mode;
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_MEMSET (sio, 0, QSE_SIZEOF(*sio));
|
2008-12-01 00:20:35 +00:00
|
|
|
sio->mmgr = mmgr;
|
|
|
|
|
2009-01-18 00:44:31 +00:00
|
|
|
mode = QSE_FIO_RUSR | QSE_FIO_WUSR |
|
|
|
|
QSE_FIO_RGRP | QSE_FIO_ROTH;
|
|
|
|
|
|
|
|
if (qse_fio_init (&sio->fio, mmgr, file, flags, mode) == QSE_NULL)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (qse_tio_init(&sio->tio, mmgr) == QSE_NULL)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_fio_fini (&sio->fio);
|
|
|
|
return QSE_NULL;
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (qse_tio_attachin(&sio->tio, __sio_input, sio) == -1 ||
|
|
|
|
qse_tio_attachout(&sio->tio, __sio_output, sio) == -1)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_tio_fini (&sio->tio);
|
|
|
|
qse_fio_fini (&sio->fio);
|
|
|
|
return QSE_NULL;
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return sio;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
void qse_sio_fini (qse_sio_t* sio)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
/*if (qse_sio_flush (sio) == -1) return -1;*/
|
|
|
|
qse_sio_flush (sio);
|
|
|
|
qse_tio_fini (&sio->tio);
|
|
|
|
qse_fio_fini (&sio->fio);
|
|
|
|
|
|
|
|
if (sio == qse_sio_in) qse_sio_in = QSE_NULL;
|
|
|
|
else if (sio == qse_sio_out) qse_sio_out = QSE_NULL;
|
|
|
|
else if (sio == qse_sio_err) qse_sio_err = QSE_NULL;
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_sio_hnd_t qse_sio_gethandle (qse_sio_t* sio)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
/*return qse_fio_gethandle (&sio->fio);*/
|
|
|
|
return QSE_FIO_HANDLE(&sio->fio);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ssize_t qse_sio_flush (qse_sio_t* sio)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
return qse_tio_flush (&sio->tio);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
void qse_sio_purge (qse_sio_t* sio)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_tio_purge (&sio->tio);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2009-01-29 08:50:30 +00:00
|
|
|
#if 0
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ssize_t qse_sio_getc (qse_sio_t* sio, qse_char_t* c)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
return qse_tio_getc (&sio->tio, c);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ssize_t qse_sio_gets (qse_sio_t* sio, qse_char_t* buf, qse_size_t size)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
return qse_tio_gets (&sio->tio, buf, size);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ssize_t qse_sio_getstr (qse_sio_t* sio, qse_str_t* buf)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
return qse_tio_getstr (&sio->tio, buf);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ssize_t qse_sio_putc (qse_sio_t* sio, qse_char_t c)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
return qse_tio_putc (&sio->tio, c);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ssize_t qse_sio_puts (qse_sio_t* sio, const qse_char_t* str)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
return qse_tio_puts (&sio->tio, str);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
2009-01-29 08:50:30 +00:00
|
|
|
#endif
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2009-01-18 01:48:21 +00:00
|
|
|
qse_ssize_t qse_sio_read (qse_sio_t* sio, qse_char_t* buf, qse_size_t size)
|
|
|
|
{
|
|
|
|
return qse_tio_read (&sio->tio, buf, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_ssize_t qse_sio_write (qse_sio_t* sio, const qse_char_t* str, qse_size_t size)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2009-01-18 01:48:21 +00:00
|
|
|
return qse_tio_write (&sio->tio, str, size);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2009-01-29 08:50:30 +00:00
|
|
|
int qse_sio_getpos (qse_sio_t* sio, qse_sio_pos_t* pos)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2009-01-29 08:50:30 +00:00
|
|
|
qse_fio_off_t off;
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2009-01-29 08:50:30 +00:00
|
|
|
off = qse_fio_seek (&sio->fio, 0, QSE_FIO_CURRENT);
|
|
|
|
if (off == (qse_fio_off_t)-1) return -1;
|
2008-12-01 00:20:35 +00:00
|
|
|
|
|
|
|
*pos = off;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-01-29 08:50:30 +00:00
|
|
|
int qse_sio_setpos (qse_sio_t* sio, qse_sio_pos_t pos)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
if (qse_sio_flush(sio) == -1) return -1;
|
|
|
|
return (qse_fio_seek (&sio->fio,
|
2009-01-29 08:50:30 +00:00
|
|
|
pos, QSE_FIO_BEGIN) == (qse_fio_off_t)-1)? -1: 0;
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2009-01-29 08:50:30 +00:00
|
|
|
#if 0
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_sio_rewind (qse_sio_t* sio)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
if (qse_sio_flush(sio) == -1) return -1;
|
|
|
|
return (qse_fio_seek (&sio->fio,
|
2009-01-29 08:50:30 +00:00
|
|
|
0, QSE_FIO_BEGIN) == (qse_fio_off_t)-1)? -1: 0;
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_sio_movetoend (qse_sio_t* sio)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
if (qse_sio_flush(sio) == -1) return -1;
|
|
|
|
return (qse_fio_seek (&sio->fio,
|
2009-01-29 08:50:30 +00:00
|
|
|
0, QSE_FIO_END) == (qse_fio_off_t)-1)? -1: 0;
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
static qse_ssize_t __sio_input (int cmd, void* arg, void* buf, qse_size_t size)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_sio_t* sio = (qse_sio_t*)arg;
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (sio != QSE_NULL);
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (cmd == QSE_TIO_IO_DATA)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-12 04:05:28 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
/* TODO: I hate this way of adjusting the handle value
|
|
|
|
* Is there any good ways to do it statically? */
|
|
|
|
HANDLE h = sio->fio.handle;
|
|
|
|
if (h == (HANDLE)STD_INPUT_HANDLE ||
|
|
|
|
h == (HANDLE)STD_OUTPUT_HANDLE ||
|
|
|
|
h == (HANDLE)STD_ERROR_HANDLE)
|
|
|
|
{
|
|
|
|
h = GetStdHandle((DWORD)h);
|
|
|
|
if (h != INVALID_HANDLE_VALUE && h != NULL)
|
|
|
|
{
|
|
|
|
sio->fio.handle = h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2008-12-21 21:35:07 +00:00
|
|
|
return qse_fio_read (&sio->fio, buf, size);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
static qse_ssize_t __sio_output (int cmd, void* arg, void* buf, qse_size_t size)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_sio_t* sio = (qse_sio_t*)arg;
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (sio != QSE_NULL);
|
2008-12-01 00:20:35 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (cmd == QSE_TIO_IO_DATA)
|
2008-12-01 00:20:35 +00:00
|
|
|
{
|
2008-12-12 04:05:28 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
/* TODO: I hate this way of adjusting the handle value
|
|
|
|
* Is there any good ways to do it statically? */
|
|
|
|
HANDLE h = sio->fio.handle;
|
|
|
|
if (h == (HANDLE)STD_INPUT_HANDLE ||
|
|
|
|
h == (HANDLE)STD_OUTPUT_HANDLE ||
|
|
|
|
h == (HANDLE)STD_ERROR_HANDLE)
|
|
|
|
{
|
|
|
|
h = GetStdHandle((DWORD)h);
|
|
|
|
if (h != INVALID_HANDLE_VALUE && h != NULL)
|
|
|
|
{
|
|
|
|
sio->fio.handle = h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2008-12-21 21:35:07 +00:00
|
|
|
return qse_fio_write (&sio->fio, buf, size);
|
2008-12-01 00:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|