version 1.1, 2012/02/02 15:58:14
|
version 1.2, 2012/02/02 21:32:42
|
Line 0
|
Line 1
|
|
#include "global.h" |
|
|
|
|
|
static void |
|
unmap_cf(struct tagBufIO *buf) |
|
{ |
|
if (buf) |
|
munmap(buf->buf_base, buf->buf_size); |
|
} |
|
|
|
static int |
|
cf_(struct tagBufIO *buf) |
|
{ |
|
if (!buf) { |
|
io_SetErr(EINVAL, "Invalid arguments ..."); |
|
return -1; |
|
} |
|
|
|
if (buf->buf_mode == BUFIO_MODE_INFINIT) |
|
free(buf->buf_base); |
|
else if (buf->buf_unmap) |
|
buf->buf_unmap(buf); |
|
|
|
free(buf); |
|
return 0; |
|
} |
|
|
|
static fpos_t |
|
sf_lim(struct tagBufIO *buf, fpos_t pos, int w) |
|
{ |
|
if (!buf) |
|
goto err; |
|
|
|
switch (w) { |
|
case SEEK_SET: |
|
if (buf->buf_size < pos || pos < 0) |
|
goto err; |
|
buf->buf_offset = pos; |
|
break; |
|
case SEEK_CUR: |
|
if (buf->buf_size < (buf->buf_offset + pos) || (buf->buf_offset + pos) < 0) |
|
goto err; |
|
buf->buf_offset += pos; |
|
break; |
|
case SEEK_END: |
|
if (buf->buf_size < (buf->buf_size + pos) || (buf->buf_size + pos) < 0) |
|
goto err; |
|
buf->buf_offset = buf->buf_size + pos; |
|
break; |
|
default: |
|
goto err; |
|
} |
|
|
|
return buf->buf_offset; |
|
err: |
|
io_SetErr(EINVAL, "Invalid arguments ..."); |
|
return -1; |
|
} |
|
|
|
static int |
|
rf_lim(struct tagBufIO *buf, char *dat, int siz) |
|
{ |
|
if (!buf || !dat) { |
|
io_SetErr(EINVAL, "Invalid arguments ..."); |
|
return -1; |
|
} |
|
|
|
if (buf->buf_offset + siz > buf->buf_size) |
|
siz = buf->buf_size - buf->buf_offset; |
|
|
|
memcpy(dat, buf->buf_base + buf->buf_offset, siz); |
|
buf->buf_offset += siz; |
|
return siz; |
|
} |
|
|
|
static int |
|
wf_lim(struct tagBufIO *buf, const char *dat, int siz) |
|
{ |
|
if (!buf || !dat) { |
|
io_SetErr(EINVAL, "Invalid arguments ..."); |
|
return -1; |
|
} |
|
|
|
if (buf->buf_offset + siz > buf->buf_size) |
|
siz = buf->buf_size - buf->buf_offset; |
|
|
|
memcpy(buf->buf_base + buf->buf_offset, dat, siz); |
|
buf->buf_offset += siz; |
|
return siz; |
|
} |
|
|
|
static fpos_t |
|
sf_inf(struct tagBufIO *buf, fpos_t pos, int w) |
|
{ |
|
void *b; |
|
|
|
if (!buf) |
|
goto err; |
|
|
|
switch (w) { |
|
case SEEK_SET: |
|
if (pos < 0) |
|
goto err; |
|
if (buf->buf_size < pos) { |
|
b = realloc(buf->buf_base, pos); |
|
if (!b) { |
|
LOGERR; |
|
return -1; |
|
} else { |
|
buf->buf_base = b; |
|
memset(buf->buf_base + buf->buf_size, 0, pos - buf->buf_size); |
|
buf->buf_size = pos; |
|
} |
|
} |
|
buf->buf_offset = pos; |
|
break; |
|
case SEEK_CUR: |
|
if ((buf->buf_offset + pos) < 0) |
|
goto err; |
|
if (buf->buf_size < (buf->buf_offset + pos)) { |
|
b = realloc(buf->buf_base, buf->buf_offset + pos); |
|
if (!b) { |
|
LOGERR; |
|
return -1; |
|
} else { |
|
buf->buf_base = b; |
|
memset(buf->buf_base + buf->buf_size, 0, |
|
buf->buf_offset + pos - buf->buf_size); |
|
buf->buf_size = buf->buf_offset + pos; |
|
} |
|
} |
|
buf->buf_offset += pos; |
|
break; |
|
case SEEK_END: |
|
if ((buf->buf_size + pos) < 0) |
|
goto err; |
|
if (buf->buf_size < (buf->buf_size + pos)) { |
|
b = realloc(buf->buf_base, buf->buf_size + pos); |
|
if (!b) { |
|
LOGERR; |
|
return -1; |
|
} else { |
|
buf->buf_base = b; |
|
memset(buf->buf_base + buf->buf_size, 0, pos); |
|
buf->buf_size += pos; |
|
buf->buf_offset = buf->buf_size; |
|
} |
|
} else |
|
buf->buf_offset = buf->buf_size + pos; |
|
break; |
|
default: |
|
goto err; |
|
} |
|
|
|
return buf->buf_offset; |
|
err: |
|
io_SetErr(EINVAL, "Invalid arguments ..."); |
|
return -1; |
|
} |
|
|
|
static int |
|
wf_inf(struct tagBufIO *buf, const char *dat, int siz) |
|
{ |
|
void *b; |
|
|
|
if (!buf || !dat) { |
|
io_SetErr(EINVAL, "Invalid arguments ..."); |
|
return -1; |
|
} |
|
|
|
if (buf->buf_offset + siz > buf->buf_size) { |
|
b = realloc(buf->buf_base, buf->buf_offset + siz); |
|
if (!b) { |
|
LOGERR; |
|
return -1; |
|
} else { |
|
buf->buf_base = b; |
|
memset(buf->buf_base + buf->buf_size, 0, |
|
buf->buf_offset + siz - buf->buf_size); |
|
buf->buf_size = buf->buf_offset + siz; |
|
} |
|
} |
|
|
|
memcpy(buf->buf_base + buf->buf_offset, dat, siz); |
|
buf->buf_offset += siz; |
|
return siz; |
|
} |
|
|
|
|
|
/* |
|
* io_fmemopen() File buffered stream operations over memory block |
|
* |
|
* @base = Base address of memory block, if =NULL Infinit length(auto-grow) |
|
* @basesize = Size of memory block |
|
* return: NULL error or !=NULL Opened file resource |
|
*/ |
|
FILE * |
|
io_fmemopen(void ** __restrict base, off_t basesize) |
|
{ |
|
FILE *f = NULL; |
|
struct tagBufIO *buf; |
|
|
|
if (!base) { |
|
io_SetErr(EINVAL, "Invalid base argument ..."); |
|
return NULL; |
|
} |
|
|
|
buf = malloc(sizeof(struct tagBufIO)); |
|
if (!buf) { |
|
LOGERR; |
|
return NULL; |
|
} else |
|
memset(buf, 0, sizeof(struct tagBufIO)); |
|
|
|
if (!*base) { |
|
*base = malloc(basesize); |
|
if (!*base) { |
|
LOGERR; |
|
free(buf); |
|
return NULL; |
|
} else |
|
memset(*base, 0, basesize); |
|
|
|
buf->buf_mode = BUFIO_MODE_INFINIT; |
|
} else |
|
buf->buf_mode = BUFIO_MODE_LIMIT; |
|
|
|
buf->buf_base = *base; |
|
buf->buf_size = basesize; |
|
|
|
if (buf->buf_mode == BUFIO_MODE_INFINIT) |
|
f = funopen(buf, (int (*)(void *, char *, int)) rf_lim, |
|
(int (*)(void *, char const *, int)) wf_inf, |
|
(fpos_t (*)(void *, fpos_t, int)) sf_inf, |
|
(int (*)(void *)) cf_); |
|
else |
|
f = funopen(buf, (int (*)(void *, char *, int)) rf_lim, |
|
(int (*)(void *, char const *, int)) wf_lim, |
|
(fpos_t (*)(void *, fpos_t, int)) sf_lim, |
|
(int (*)(void *)) cf_); |
|
if (!f) { |
|
LOGERR; |
|
if (buf->buf_mode == BUFIO_MODE_INFINIT) { |
|
free(*base); |
|
*base = NULL; |
|
} |
|
free(buf); |
|
return NULL; |
|
} |
|
|
|
return f; |
|
} |
|
|
|
/* |
|
* io_fmapopen() File buffered stream operations over MMAP block |
|
* |
|
* @csFile = Filename for MMAP, if =NULL private MMAP block |
|
* @mode = File open mode |
|
* @perm = If file not exists will be created with this access permissions |
|
* @prot = MMAP protection |
|
* @flags = MMAP mode flags |
|
* @offset = Map from file offset, if csFile==NULL then this is size of MMAP private block |
|
* return: NULL error or !=NULL Opened file resource |
|
*/ |
|
FILE * |
|
io_fmapopen(const char *csFile, int mode, int perm, int prot, int flags, off_t offset) |
|
{ |
|
FILE *f; |
|
struct tagBufIO *buf; |
|
void *base; |
|
off_t basesize; |
|
int fd = -1; |
|
|
|
if (csFile) { |
|
fd = open(csFile, mode, perm); |
|
if (fd == -1) { |
|
LOGERR; |
|
return NULL; |
|
} |
|
basesize = lseek(fd, 0, SEEK_END); |
|
if (basesize == -1) { |
|
LOGERR; |
|
close(fd); |
|
return NULL; |
|
} else |
|
lseek(fd, 0, SEEK_SET); |
|
|
|
base = mmap(NULL, basesize, prot, flags | MAP_FILE, fd, offset); |
|
if (base == MAP_FAILED) { |
|
LOGERR; |
|
close(fd); |
|
return NULL; |
|
} else |
|
close(fd); |
|
} else if (offset) { |
|
basesize = offset; |
|
base = mmap(NULL, basesize, prot, MAP_ANON, -1, 0); |
|
if (base == MAP_FAILED) { |
|
LOGERR; |
|
return NULL; |
|
} |
|
} else { |
|
io_SetErr(EINVAL, "Invalid base argument ..."); |
|
return NULL; |
|
} |
|
|
|
|
|
buf = malloc(sizeof(struct tagBufIO)); |
|
if (!buf) { |
|
LOGERR; |
|
munmap(base, basesize); |
|
return NULL; |
|
} else |
|
memset(buf, 0, sizeof(struct tagBufIO)); |
|
|
|
buf->buf_mode = BUFIO_MODE_LIMIT; |
|
buf->buf_base = base; |
|
buf->buf_size = basesize; |
|
buf->buf_unmap = unmap_cf; |
|
|
|
f = funopen(buf, (int (*)(void *, char *, int)) rf_lim, |
|
(int (*)(void *, char const *, int)) wf_lim, |
|
(fpos_t (*)(void *, fpos_t, int)) sf_lim, |
|
(int (*)(void *)) cf_); |
|
if (!f) { |
|
LOGERR; |
|
free(buf); |
|
munmap(base, basesize); |
|
return NULL; |
|
} |
|
|
|
return f; |
|
} |
|
|
|
/* |
|
* io_dumbFile() Create empry or dumb file with fixed size |
|
* |
|
* @csFile = Filename for create |
|
* @mode = File access permissions |
|
* @size = File size |
|
* return: -1 error or open file handle |
|
*/ |
|
int |
|
io_dumbFile(const char *csFile, int mode, off_t size) |
|
{ |
|
int fd; |
|
|
|
fd = open(csFile, O_RDWR | O_CREAT, mode); |
|
if (fd == -1) { |
|
LOGERR; |
|
return -1; |
|
} |
|
|
|
if (lseek(fd, size - 1, SEEK_SET) == -1) |
|
goto err; |
|
if (write(fd, "", 1) != 1) |
|
goto err; |
|
else |
|
lseek(fd, 0, SEEK_SET); |
|
|
|
return fd; |
|
err: |
|
LOGERR; |
|
close(fd); |
|
return -1; |
|
} |
|
|
|
/* |
|
* io_fd2buf() Convert open file handle to buffered file I/O |
|
* |
|
* @fd = File handle |
|
* @mode = Permissions for new buffered file I/O |
|
* return: NULL error or open buffered file |
|
*/ |
|
inline FILE * |
|
io_fd2buf(int fd, const char *mode) |
|
{ |
|
FILE *f; |
|
|
|
f = fdopen(fd, mode); |
|
if (!f) |
|
LOGERR; |
|
|
|
return f; |
|
} |