adding system-level IO functions

This commit is contained in:
hyung-hwan 2008-10-22 04:59:31 +00:00
parent 1278c26d08
commit 4b7d0446a3
2 changed files with 341 additions and 0 deletions

74
ase/include/ase/cmn/io.h Normal file
View File

@ -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 <ase/types.h>
#include <ase/macros.h>
/* 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

267
ase/lib/cmn/io.c Normal file
View File

@ -0,0 +1,267 @@
/*
* $Id: sysapi.c,v 1.45 2007/06/20 14:54:11 baconevi Exp $
*/
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <fcntl.h>
#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
}