adding system-level IO functions
This commit is contained in:
parent
1278c26d08
commit
4b7d0446a3
74
ase/include/ase/cmn/io.h
Normal file
74
ase/include/ase/cmn/io.h
Normal 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
267
ase/lib/cmn/io.c
Normal 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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user