From 4b7d0446a3bc504232a25850bdd03f38d8caee46 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 22 Oct 2008 04:59:31 +0000 Subject: [PATCH] adding system-level IO functions --- ase/include/ase/cmn/io.h | 74 +++++++++++ ase/lib/cmn/io.c | 267 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 341 insertions(+) create mode 100644 ase/include/ase/cmn/io.h create mode 100644 ase/lib/cmn/io.c diff --git a/ase/include/ase/cmn/io.h b/ase/include/ase/cmn/io.h new file mode 100644 index 00000000..94e0b3f0 --- /dev/null +++ b/ase/include/ase/cmn/io.h @@ -0,0 +1,74 @@ +/* + * $Id: sysapi.h,v 1.56 2006/03/21 16:15:16 bacon Ease $ + */ + +#ifndef _ASE_CMN_IO_H_ +#define _ASE_CMN_IO_H_ + +#include +#include + +/* flags for ase_open */ +enum +{ + ASE_OPEN_READ = (1 << 0), + ASE_OPEN_WRITE = (1 << 1), + ASE_OPEN_CREATE = (1 << 2), + ASE_OPEN_TRUNCATE = (1 << 3), + ASE_OPEN_EXCLUSIVE = (1 << 4), + ASE_OPEN_APPEND = (1 << 5), + ASE_OPEN_NONBLOCK = (1 << 6) +}; + +/* origin for ase_seek */ +enum +{ + ASE_SEEK_BEGIN = 0, + ASE_SEEK_CURRENT = 1, + ASE_SEEK_END = 2 +}; + +#ifdef __cplusplus +extern "C" { +#endif + +ase_hnd_t ase_open ( + const ase_char_t* path, + int flag, + ... +); + +int ase_close ( + ase_hnd_t handle +); + +ase_ssize_t ase_read ( + ase_hnd_t handle, + void* buf, + ase_size_t sz +); + +ase_ssize_t ase_write ( + ase_hnd_t handle, + const void* data, + ase_size_t sz +); + +ase_off_t ase_seek ( + ase_hnd_t handle, + ase_off_t offset, + int origin +); + +/* +int ase_hstat (ase_hnd_t handle, ase_stat_t* buf); +int ase_hchmod (ase_hnd_t handle, ase_mode_t mode); +*/ +int ase_htruncate (ase_hnd_t handle, ase_off_t size); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/ase/lib/cmn/io.c b/ase/lib/cmn/io.c new file mode 100644 index 00000000..bbf4d495 --- /dev/null +++ b/ase/lib/cmn/io.c @@ -0,0 +1,267 @@ +/* + * $Id: sysapi.c,v 1.45 2007/06/20 14:54:11 baconevi Exp $ + */ + +#ifdef _WIN32 + #include +#else + #include + #include +#endif + +#ifdef _WIN32 + static int handle_map_inited = 0; + static ase_map_t handle_map; +#endif + + +ase_hnd_t ase_open (const ase_char_t* path, int flags, ...) +{ + ase_hnd_t handle; + +#ifdef _WIN32 + + DWORD desired_access = 0; + DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE; + DWORD creation_disposition = 0; + DWORD attributes = FILE_ATTRIBUTE_NORMAL; + DWORD file_type; + + if (!handle_map_inited) + { + ase_map_init (&handle_map, ...); + handle_map_inited = 1; + } + + if (flags & ASE_OPEN_READ) desired_access |= GENERIC_READ; + if (flags & ASE_OPEN_WRITE) desired_access |= GENERIC_WRITE; + + if (flags & ASE_OPEN_CREATE) + { + creation_disposition = + (flags & ASE_OPEN_EXCLUSIVE)? CREATE_NEW: + (flags & ASE_OPEN_TRUNCATE)? CREATE_ALWAYS: OPEN_ALWAYS; + } + else if (flags & ASE_OPEN_TRUNCATE) + { + creation_disposition = TRUNCATE_EXISTING; + } + else creation_disposition = OPEN_EXISTING; + + /*if (flags & ASE_FIO_SYNC) attributes |= FILE_FLAG_WRITE_THROUGH; */ + /* TODO: share mode */ + + handle = CreateFile (path, + desired_access, share_mode, ASE_NULL, + creation_disposition, attributes, 0); + if (handle == ASE_HND_INVALID) return ASE_HND_INVALID; + +/* TODO: improve append */ + if (flags & ASE_OPEN_APPEND) + { + /*fio->flags |= ASE_OPEN_APPEND;*/ + if (ase_seek (handle, 0, ASE_SEEK_END) == -1) + { + CloseHandle (handle); + return ASE_HND_INVALID; + } + } + +/* TODO: implement nonblock... + if (flags & ASE_OPEN_NONBLOCK) desired_access |= O_NONBLOCK; +*/ + + file_type = GetFileType(handle); + if (file_type == FILE_TYPE_UNKNOWN) + { + CloseHandle (handle); + return ASE_HND_INVALID; + } + + /* + if (file_type == FILE_TYPE_CHAR) + else if (file_type == FILE_TYPE_PIPE) + */ + /* TODO: a lot more */ + +#else + int desired_access = 0; + ase_va_list arg; + ase_mode_t mode; + + #ifdef ASE_CHAR_IS_MCHAR + const ase_mchar_t* path_mb; + #else + ase_mchar_t path_mb[ASE_PATH_MAX + 1]; + #endif + + ase_va_start (arg, flags); + if (ase_sizeof(ase_mode_t) < ase_sizeof(int)) + mode = ase_va_arg (arg, int); + else + mode = ase_va_arg (arg, ase_mode_t); + ase_va_end (arg); + + #ifdef ASE_CHAR_IS_MCHAR + path_mb = path; + #else + if (ase_wcstomcs_strict ( + path, path_mb, ase_countof(path_mb)) == -1) return -1; + #endif + + if (flags & ASE_OPEN_READ) desired_access = O_RDONLY; + if (flags & ASE_OPEN_WRITE) { + if (desired_access == 0) desired_access |= O_WRONLY; + else desired_access = O_RDWR; + } + + if (flags & ASE_OPEN_APPEND) desired_access |= O_APPEND; + if (flags & ASE_OPEN_CREATE) desired_access |= O_CREAT; + if (flags & ASE_OPEN_TRUNCATE) desired_access |= O_TRUNC; + if (flags & ASE_OPEN_EXCLUSIVE) desired_access |= O_EXCL; + if (flags & ASE_OPEN_NONBLOCK) desired_access |= O_NONBLOCK; + + handle = open (path_mb, desired_access, mode); +#endif + + return handle; +} + +int ase_close (ase_hnd_t handle) +{ +#ifdef _WIN32 + if (CloseHandle(handle) == FALSE) return -1; + return 0; +#else + return close (handle); +#endif +} + +ase_ssize_t ase_read (ase_hnd_t handle, void* buf, ase_size_t size) +{ +#ifdef _WIN32 + + DWORD bytes_read; + ase_size_t n = 0; + ase_byte_t* p = (ase_byte_t*)buf; + + while (1) + { + if (size <= ASE_TYPE_MAX(DWORD)) + { + if (ReadFile(handle, p, size, + &bytes_read, ASE_NULL) == FALSE) return -1; + n += bytes_read; + break; + } + + if (ReadFile(handle, p, ASE_TYPE_MAX(DWORD), + &bytes_read, ASE_NULL) == FALSE) return -1; + if (bytes_read == 0) break; /* reached the end of a file */ + + p += bytes_read; + n += bytes_read; + size -= bytes_read; + } + + return (ase_ssize_t)n; + +#else + return read (handle, buf, size); +#endif +} + +ase_ssize_t ase_write (ase_hnd_t handle, const void* data, ase_size_t size) +{ +#ifdef _WIN32 + + DWORD bytes_written; + ase_size_t n = 0; + const ase_byte_t* p = (const ase_byte_t*)data; + + /* TODO:... + if (fio->flags & ASE_OPEN_APPEND) + { + if (ase_seek (handle, 0, ASE_SEEK_END) == -1) return -1; + }*/ + + for (;;) + { + if (size <= ASE_TYPE_MAX(DWORD)) + { + if (WriteFile(handle, p, size, + &bytes_written, ASE_NULL) == FALSE) return -1; + n += bytes_written; + break; + } + + if (WriteFile(handle, p, ASE_TYPE_MAX(DWORD), + &bytes_written, ASE_NULL) == FALSE) return -1; + if (bytes_written == 0) break; + + p += bytes_written; + n += bytes_written; + size -= bytes_written; + } + + return (ase_ssize_t)n; + +#else + return write (handle, data, size); +#endif +} + +ase_off_t ase_seek (ase_hnd_t handle, ase_off_t offset, int origin) +{ +#ifdef _WIN32 + + static int __seek_map[] = + { + FILE_BEGIN, + FILE_CURRENT, + FILE_END + }; + LARGE_INTEGER x, y; + + ase_assert (ase_sizeof(offset) <= ase_sizeof(x.QuadPart)); + + x.QuadPart = offset; + if (SetFilePointerEx ( + handle, x, &y, __seek_map[origin]) == FALSE) return -1; + + return (ase_off_t)y.QuadPart; + +#else + + static int __seek_map[] = + { + SEEK_SET, + SEEK_CUR, + SEEK_END + }; + + return lseek (handle, offset, __seek_map[origin]); + +#endif +} + +int ase_htruncate (ase_hnd_t handle, ase_off_t size) +{ +#ifdef _WIN32 + #ifndef INVALID_SET_FILE_POINTER + #define INVALID_SET_FILE_POINTER ((DWORD)-1) + #endif + + /* TODO: support lsDistanceToMoveHigh (high 32bits of 64bit offset) */ + if (SetFilePointer( + handle,0,NULL,FILE_CURRENT) == INVALID_SET_FILE_POINTER || + SetFilePointer( + handle,size,NULL,FILE_BEGIN) == INVALID_SET_FILE_POINTER || + SetEndOfFile(handle) == FALSE) return -1; + + return 0; +#else + return ftruncate (handle, size); +#endif +} +