| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2020-04-16 03:42:30 +00:00
										 |  |  |     Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |     modification, are permitted provided that the following conditions | 
					
						
							|  |  |  |     are met: | 
					
						
							|  |  |  |     1. Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  |        notice, this list of conditions and the following disclaimer. | 
					
						
							|  |  |  |     2. Redistributions in binary form must reproduce the above copyright | 
					
						
							|  |  |  |        notice, this list of conditions and the following disclaimer in the | 
					
						
							|  |  |  |        documentation and/or other materials provided with the distribution. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | 
					
						
							|  |  |  |     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
					
						
							|  |  |  |     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 
					
						
							|  |  |  |     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 
					
						
							|  |  |  |     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
					
						
							|  |  |  |     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
					
						
							|  |  |  |     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
					
						
							|  |  |  |     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
					
						
							|  |  |  |     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
					
						
							|  |  |  |     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <hawk-sio.h>
 | 
					
						
							|  |  |  | #include "hawk-prv.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | #	include <windows.h> /* for the UGLY hack */
 | 
					
						
							|  |  |  | #elif defined(__OS2__)
 | 
					
						
							|  |  |  | 	/* nothing */ | 
					
						
							|  |  |  | #elif defined(__DOS__)
 | 
					
						
							|  |  |  | 	/* nothing */ | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #	include "syscall.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define LOCK_OUTPUT(sio) do { if ((sio)->mtx) hawk_mtx_lock ((sio)->mtx, HAWK_NULL); } while(0)
 | 
					
						
							|  |  |  | #define UNLOCK_OUTPUT(sio) do { if ((sio)->mtx) hawk_mtx_unlock ((sio)->mtx); } while(0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* TODO: currently, LOCK_INPUT and LOCK_OUTPUT don't have difference.
 | 
					
						
							|  |  |  |  *       can i just use two difference mutex objects to differentiate? */ | 
					
						
							|  |  |  | #define LOCK_INPUT(sio) do { if ((sio)->mtx) hawk_mtx_lock ((sio)->mtx, HAWK_NULL); } while(0)
 | 
					
						
							|  |  |  | #define UNLOCK_INPUT(sio) do { if ((sio)->mtx) hawk_mtx_unlock ((sio)->mtx); } while(0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* internal status codes */ | 
					
						
							|  |  |  | enum | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	STATUS_UTF8_CONSOLE = (1 << 0), | 
					
						
							|  |  |  | 	STATUS_LINE_BREAK   = (1 << 1) | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooi_t file_input (hawk_tio_t* tio, hawk_tio_cmd_t cmd, void* buf, hawk_oow_t size); | 
					
						
							|  |  |  | static hawk_ooi_t file_output (hawk_tio_t* tio, hawk_tio_cmd_t cmd, void* buf, hawk_oow_t size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | hawk_sio_t* hawk_sio_open (hawk_gem_t* gem, hawk_oow_t xtnsize, const hawk_ooch_t* file, int flags) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	hawk_sio_t* sio; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	sio = (hawk_sio_t*)hawk_gem_allocmem(gem, HAWK_SIZEOF(hawk_sio_t) + xtnsize); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	if (sio) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		if (hawk_sio_init(sio, gem, file, flags) <= -1) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 			hawk_gem_freemem (gem, sio); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 			return HAWK_NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else HAWK_MEMSET (sio + 1, 0, xtnsize); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return sio; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | hawk_sio_t* hawk_sio_openstd (hawk_gem_t* gem, hawk_oow_t xtnsize, hawk_sio_std_t std, int flags) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	hawk_sio_t* sio; | 
					
						
							|  |  |  | 	hawk_fio_hnd_t hnd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Is this necessary?
 | 
					
						
							|  |  |  | 	if (flags & HAWK_SIO_KEEPATH) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		hawk_gem_seterrnum (gem, HAWK_NULL, HAWK_EINVAL); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		return HAWK_NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (hawk_get_std_fio_handle(std, &hnd) <= -1) return HAWK_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	sio = hawk_sio_open(gem, xtnsize, (const hawk_ooch_t*)&hnd, flags | HAWK_SIO_HANDLE | HAWK_SIO_NOCLOSE); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	if (sio) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		DWORD mode; | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		if (GetConsoleMode(sio->file.handle, &mode) == TRUE && GetConsoleOutputCP() == CP_UTF8) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			sio->status |= STATUS_UTF8_CONSOLE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return sio; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-10 08:53:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | void hawk_sio_close (hawk_sio_t* sio) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sio_fini (sio); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	hawk_gem_freemem (sio->gem, sio); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | int hawk_sio_init (hawk_sio_t* sio, hawk_gem_t* gem, const hawk_ooch_t* path, int flags) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int mode; | 
					
						
							|  |  |  | 	int topt = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HAWK_MEMSET (sio, 0, HAWK_SIZEOF(*sio)); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	sio->gem = gem; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mode = HAWK_FIO_RUSR | HAWK_FIO_WUSR | HAWK_FIO_RGRP | HAWK_FIO_ROTH; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (flags & HAWK_SIO_REENTRANT) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		sio->mtx = hawk_mtx_open(gem, 0); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		if (!sio->mtx) goto oops00; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	/* sio flag enumerators redefines most fio flag enumerators and
 | 
					
						
							|  |  |  | 	 * compose a superset of fio flag enumerators. when a user calls | 
					
						
							|  |  |  | 	 * this function, a user can specify a sio flag enumerator not | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	 * present in the fio flag enumerator. mask off such an enumerator. */ | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	if (hawk_fio_init(&sio->file, gem, path, (flags & ~HAWK_FIO_RESERVED), mode) <= -1) goto oops01; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (flags & HAWK_SIO_IGNOREECERR) topt |= HAWK_TIO_IGNOREECERR; | 
					
						
							|  |  |  | 	if (flags & HAWK_SIO_NOAUTOFLUSH) topt |= HAWK_TIO_NOAUTOFLUSH; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((flags & HAWK_SIO_KEEPPATH) && !(flags & HAWK_SIO_HANDLE)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	#if defined(HAWK_OOCH_IS_BCH)
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		sio->path = hawk_gem_dupoocstr(gem, path, HAWK_NULL); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	#else
 | 
					
						
							|  |  |  | 		if (flags & HAWK_SIO_BCSTRPATH) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			/* the stored path is always of the hawk_ooch_t type.
 | 
					
						
							|  |  |  | 			 * and the conversion uses the cmgr set on the gem object. | 
					
						
							|  |  |  | 			 * note that cmgr for the actual file content can be set | 
					
						
							|  |  |  | 			 * with hawk_sio_setcmgr(). */ | 
					
						
							|  |  |  | 			sio->path = hawk_gem_dupbtoucstr(gem, (const hawk_bch_t*)path, HAWK_NULL, 1); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			sio->path = hawk_gem_dupoocstr(gem, path, HAWK_NULL); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		if (sio->path == HAWK_NULL) goto oops02; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	if (hawk_tio_init(&sio->tio.io, gem, topt) <= -1) goto oops03; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* store the back-reference to sio in the extension area.*/ | 
					
						
							| 
									
										
										
										
											2025-06-18 23:45:34 +09:00
										 |  |  | 	/*HAWK_ASSERT(hawk, (&sio->tio.io + 1) == &sio->tio.xtn);*/ | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	*(hawk_sio_t**)(&sio->tio.io + 1) = sio; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (hawk_tio_attachin(&sio->tio.io, file_input, sio->inbuf, HAWK_COUNTOF(sio->inbuf)) <= -1 || | 
					
						
							|  |  |  | 	    hawk_tio_attachout(&sio->tio.io, file_output, sio->outbuf, HAWK_COUNTOF(sio->outbuf)) <= -1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		goto oops04; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(__OS2__)
 | 
					
						
							|  |  |  | 	if (flags & HAWK_SIO_LINEBREAK) sio->status |= STATUS_LINE_BREAK; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | oops04: | 
					
						
							|  |  |  | 	hawk_tio_fini (&sio->tio.io); | 
					
						
							|  |  |  | oops03: | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	if (sio->path) hawk_gem_freemem (sio->gem, sio->path); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | oops02: | 
					
						
							|  |  |  | 	hawk_fio_fini (&sio->file); | 
					
						
							|  |  |  | oops01: | 
					
						
							|  |  |  | 	if (sio->mtx) hawk_mtx_close (sio->mtx); | 
					
						
							|  |  |  | oops00: | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | int hawk_sio_initstd (hawk_sio_t* sio, hawk_gem_t* gem, hawk_sio_std_t std, int flags) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | 	hawk_fio_hnd_t hnd; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	if (hawk_get_std_fio_handle(std, &hnd) <= -1) return -1; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	n = hawk_sio_init(sio, gem, (const hawk_ooch_t*)&hnd, flags | HAWK_SIO_HANDLE | HAWK_SIO_NOCLOSE); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	if (n >= 0) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		DWORD mode; | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		if (GetConsoleMode (sio->file.handle, &mode) == TRUE && GetConsoleOutputCP() == CP_UTF8) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			sio->status |= STATUS_UTF8_CONSOLE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void hawk_sio_fini (hawk_sio_t* sio) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/*if (hawk_sio_flush (sio) <= -1) return -1;*/ | 
					
						
							|  |  |  | 	hawk_sio_flush (sio); | 
					
						
							|  |  |  | 	hawk_tio_fini (&sio->tio.io); | 
					
						
							|  |  |  | 	hawk_fio_fini (&sio->file); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	if (sio->path) hawk_gem_freemem (sio->gem, sio->path); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	if (sio->mtx) hawk_mtx_close (sio->mtx); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_cmgr_t* hawk_sio_getcmgr (hawk_sio_t* sio) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	return hawk_tio_getcmgr(&sio->tio.io); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void hawk_sio_setcmgr (hawk_sio_t* sio, hawk_cmgr_t* cmgr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_tio_setcmgr (&sio->tio.io, cmgr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_sio_hnd_t hawk_sio_gethnd (const hawk_sio_t* sio) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	/*return hawk_fio_gethnd(&sio->file);*/ | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	return HAWK_FIO_HANDLE(&sio->file); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const hawk_ooch_t* hawk_sio_getpath (hawk_sio_t* sio) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	/* this path is valid if HAWK_SIO_HANDLE is off and HAWK_SIO_KEEPPATH is on.
 | 
					
						
							|  |  |  | 	 * HAWK_SIO_BCSTRPATH doesn't affect this value. The opening side ensures it | 
					
						
							|  |  |  | 	 * to be in the hawk_ooch_type. */ | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	return sio->path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_flush (hawk_sio_t* sio) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 	LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_flush(&sio->tio.io); | 
					
						
							|  |  |  | 	UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void hawk_sio_drain (hawk_sio_t* sio) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	hawk_tio_drain (&sio->tio.io); | 
					
						
							|  |  |  | 	UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_getbchar (hawk_sio_t* sio, hawk_bch_t* c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 	LOCK_INPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_readbchars(&sio->tio.io, c, 1); | 
					
						
							|  |  |  | 	UNLOCK_INPUT (sio); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_getuchar (hawk_sio_t* sio, hawk_uch_t* c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 	LOCK_INPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_readuchars(&sio->tio.io, c, 1); | 
					
						
							|  |  |  | 	UNLOCK_INPUT (sio); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_getbcstr (hawk_sio_t* sio, hawk_bch_t* buf, hawk_oow_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (size <= 0) return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	/* Using ReadConsoleA() didn't help at all.
 | 
					
						
							|  |  |  | 	 * so I don't implement any hack here */ | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOCK_INPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_readbchars(&sio->tio.io, buf, size - 1); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	if (n <= -1) return -1; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	UNLOCK_INPUT (sio); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	buf[n] = '\0'; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_getbchars (hawk_sio_t* sio, hawk_bch_t* buf, hawk_oow_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	/* Using ReadConsoleA() didn't help at all.
 | 
					
						
							|  |  |  | 	 * so I don't implement any hack here */ | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOCK_INPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_readbchars(&sio->tio.io, buf, size); | 
					
						
							|  |  |  | 	UNLOCK_INPUT (sio); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_getucstr (hawk_sio_t* sio, hawk_uch_t* buf, hawk_oow_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (size <= 0) return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	/* Using ReadConsoleA() didn't help at all.
 | 
					
						
							|  |  |  | 	 * so I don't implement any hack here */ | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOCK_INPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_readuchars(&sio->tio.io, buf, size - 1); | 
					
						
							|  |  |  | 	UNLOCK_INPUT (sio); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	buf[n] = '\0'; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_getuchars(hawk_sio_t* sio, hawk_uch_t* buf, hawk_oow_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	/* Using ReadConsoleW() didn't help at all.
 | 
					
						
							|  |  |  | 	 * so I don't implement any hack here */ | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOCK_INPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_readuchars (&sio->tio.io, buf, size); | 
					
						
							|  |  |  | 	UNLOCK_INPUT (sio); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooi_t putbc_no_mutex (hawk_sio_t* sio, hawk_bch_t c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(__OS2__)
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	if (c == '\n' && (sio->status & STATUS_LINE_BREAK)) | 
					
						
							|  |  |  | 		n = hawk_tio_writebchars(&sio->tio.io, "\r\n", 2); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		n = hawk_tio_writebchars(&sio->tio.io, &c, 1); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	n = hawk_tio_writebchars(&sio->tio.io, &c, 1); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_putbchar (hawk_sio_t* sio, hawk_bch_t c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 	LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	n = putbc_no_mutex(sio, c); | 
					
						
							|  |  |  | 	UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooi_t put_uchar_no_mutex (hawk_sio_t* sio, hawk_uch_t c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(__OS2__)
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	if (c == '\n' && (sio->status & STATUS_LINE_BREAK)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		static hawk_uch_t crnl[2] = { '\r', '\n' }; | 
					
						
							|  |  |  | 		n = hawk_tio_writeuchars(&sio->tio.io, crnl, 2); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		n = hawk_tio_writeuchars(&sio->tio.io, &c, 1); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	n = hawk_tio_writeuchars(&sio->tio.io, &c, 1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_putuchar (hawk_sio_t* sio, hawk_uch_t c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 	LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	n = put_uchar_no_mutex(sio, c); | 
					
						
							|  |  |  | 	UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_putbcstr (hawk_sio_t* sio, const hawk_bch_t* str) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	/* Using WriteConsoleA() didn't help at all.
 | 
					
						
							|  |  |  | 	 * so I don't implement any hacks here */ | 
					
						
							|  |  |  | #elif defined(__OS2__)
 | 
					
						
							|  |  |  | 	if (sio->status & STATUS_LINE_BREAK) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		LOCK_OUTPUT (sio); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		for (n = 0; n < HAWK_TYPE_MAX(hawk_ooi_t) && str[n] != '\0'; n++) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			if ((n = putbc_no_mutex(sio, str[n])) <= -1) | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				n = -1; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 		return n; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_writebchars(&sio->tio.io, str, (hawk_oow_t)-1); | 
					
						
							|  |  |  | 	UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_putbchars (hawk_sio_t* sio, const hawk_bch_t* str, hawk_oow_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	/* Using WriteConsoleA() didn't help at all.
 | 
					
						
							|  |  |  | 	 * so I don't implement any hacks here */ | 
					
						
							|  |  |  | #elif defined(__OS2__)
 | 
					
						
							|  |  |  | 	if (sio->status & STATUS_LINE_BREAK) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (size > HAWK_TYPE_MAX(hawk_ooi_t)) size = HAWK_TYPE_MAX(hawk_ooi_t); | 
					
						
							|  |  |  | 		LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 		for (n = 0; n < size; n++) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 			if (putbc_no_mutex(sio, str[n]) <= -1) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				n = -1; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 		return n; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_writebchars (&sio->tio.io, str, size); | 
					
						
							|  |  |  | 	UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_putucstr (hawk_sio_t* sio, const hawk_uch_t* str) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	/* DAMN UGLY: See comment in hawk_sio_putuchars() */ | 
					
						
							|  |  |  | 	if (sio->status & STATUS_UTF8_CONSOLE) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		DWORD count, left; | 
					
						
							|  |  |  | 		const hawk_uch_t* cur; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (hawk_sio_flush (sio) <= -1) return -1; /* can't do buffering */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 08:16:34 +00:00
										 |  |  | 		for (cur = str, left = hawk_count_ucstr(str); left > 0; cur += count, left -= count) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			if (WriteConsoleW(sio->file.handle, cur, left, &count, HAWK_NULL) == FALSE) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2020-01-01 05:20:28 +00:00
										 |  |  | 				hawk_gem_seterrnum (sio->gem, HAWK_NULL, hawk_syserr_to_errnum(GetLastError())); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (count == 0) break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			if (count > left) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 				hawk_gem_seterrnum (sio->gem, HAWK_NULL, HAWK_ESYSERR); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return cur - str; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #elif defined(__OS2__)
 | 
					
						
							|  |  |  | 	if (sio->status & STATUS_LINE_BREAK) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		LOCK_OUTPUT (sio); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		for (n = 0; n < HAWK_TYPE_MAX(hawk_ooi_t) && str[n] != '\0'; n++) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 			if (put_uchar_no_mutex(sio, str[n]) <= -1) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				n = -1; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 		return n; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_writeuchars(&sio->tio.io, str, (hawk_oow_t)-1); | 
					
						
							|  |  |  | 	UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_ooi_t hawk_sio_putuchars (hawk_sio_t* sio, const hawk_uch_t* str, hawk_oow_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_ooi_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	/* DAMN UGLY:
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	 *  WriteFile returns wrong number of bytes written if it is | 
					
						
							|  |  |  | 	 *  requested to write a utf8 string on utf8 console (codepage 65001). | 
					
						
							|  |  |  | 	 *  it seems to return a number of characters written instead. so | 
					
						
							|  |  |  | 	 *  i have to use an alternate API for console output for | 
					
						
							|  |  |  | 	 *  wide-character strings. Conversion to either an OEM codepage or | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	 *  the utf codepage is handled by the API. This hack at least | 
					
						
							|  |  |  | 	 *  lets you do proper utf8 output on utf8 console using wide-character. | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	 *  Note that the multibyte functions hawk_sio_putbcstr() and | 
					
						
							|  |  |  | 	 *  hawk_sio_putbchars() doesn't handle this. So you may still suffer. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (sio->status & STATUS_UTF8_CONSOLE) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		DWORD count, left; | 
					
						
							|  |  |  | 		const hawk_uch_t* cur; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (hawk_sio_flush (sio) <= -1) return -1; /* can't do buffering */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (cur = str, left = size; left > 0; cur += count, left -= count) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			if (WriteConsoleW(sio->file.handle, cur, left, &count, HAWK_NULL) == FALSE) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2020-01-01 05:20:28 +00:00
										 |  |  | 				hawk_gem_seterrnum (sio->gem, HAWK_NULL, hawk_syserr_to_errnum(GetLastError())); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (count == 0) break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* Note:
 | 
					
						
							|  |  |  | 			 * WriteConsoleW() in unicosw.dll on win 9x/me returns | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			 * the number of bytes via 'count'. If a double byte | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 			 * string is given, 'count' can be greater than 'left'. | 
					
						
							|  |  |  | 			 * this case is a miserable failure. however, i don't | 
					
						
							|  |  |  | 			 * think there is CP_UTF8 codepage for console on win9x/me. | 
					
						
							|  |  |  | 			 * so let me make this function fail if that ever happens. | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			if (count > left) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 				hawk_gem_seterrnum (sio->gem, HAWK_NULL, HAWK_ESYSERR); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return cur - str; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | #elif defined(__OS2__)
 | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	if (sio->status & STATUS_LINE_BREAK) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (size > HAWK_TYPE_MAX(hawk_ooi_t)) size = HAWK_TYPE_MAX(hawk_ooi_t); | 
					
						
							|  |  |  | 		LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 		for (n = 0; n < size; n++) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			if (put_uchar_no_mutex(sio, str[n]) <= -1) | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				n = -1; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 		return n; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	n = hawk_tio_writeuchars(&sio->tio.io, str, size); | 
					
						
							|  |  |  | 	UNLOCK_OUTPUT (sio); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sio_getpos (hawk_sio_t* sio, hawk_sio_pos_t* pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_fio_off_t off; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (hawk_sio_flush(sio) <= -1) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	off = hawk_fio_seek(&sio->file, 0, HAWK_FIO_CURRENT); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	if (off == (hawk_fio_off_t)-1) return -1; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	*pos = off; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sio_setpos (hawk_sio_t* sio, hawk_sio_pos_t pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_fio_off_t off; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (hawk_sio_flush(sio) <= -1) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	off = hawk_fio_seek(&sio->file, pos, HAWK_FIO_BEGIN); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 	if (off == (hawk_fio_off_t)-1) return -1; | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sio_truncate (hawk_sio_t* sio, hawk_sio_pos_t pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (hawk_sio_flush(sio) <= -1) return -1; | 
					
						
							|  |  |  | 	return hawk_fio_truncate(&sio->file, pos); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sio_seek (hawk_sio_t* sio, hawk_sio_pos_t* pos, hawk_sio_ori_t origin) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_fio_off_t x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (hawk_sio_flush(sio) <= -1) return -1; | 
					
						
							|  |  |  | 	x = hawk_fio_seek(&sio->file, *pos, origin); | 
					
						
							|  |  |  | 	if (x == (hawk_fio_off_t)-1) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*pos = x; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooi_t file_input (hawk_tio_t* tio, hawk_tio_cmd_t cmd, void* buf, hawk_oow_t size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	if (cmd == HAWK_TIO_DATA) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		hawk_sio_t* sio; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sio = *(hawk_sio_t**)(tio + 1); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		/*HAWK_ASSERT (tio->hawk, sio != HAWK_NULL);
 | 
					
						
							|  |  |  | 		HAWK_ASSERT (tio->hawk, tio->hawk == sio->hawk);*/ | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		return hawk_fio_read(&sio->file, buf, size); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooi_t file_output (hawk_tio_t* tio, hawk_tio_cmd_t cmd, void* buf, hawk_oow_t size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	if (cmd == HAWK_TIO_DATA) | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		hawk_sio_t* sio; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sio = *(hawk_sio_t**)(tio + 1); | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		/*HAWK_ASSERT (tio->hawk, sio != HAWK_NULL);
 | 
					
						
							|  |  |  | 		HAWK_ASSERT (tio->hawk, tio->hawk == sio->hawk);*/ | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 05:15:03 +00:00
										 |  |  | 		return hawk_fio_write(&sio->file, buf, size); | 
					
						
							| 
									
										
										
										
											2019-12-13 04:29:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } |