/*
* 2ooM: The Master of Orion II Reverse Engineering Project
* Default file operations structures for liblbx.
* Copyright (C) 2010 Nick Bowler
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include "misc.h"
#include "lbx.h"
/* Default I/O operations for ordinary files. */
static size_t file_read(void *buf, size_t size, void *handle)
{
return fread(buf, 1, size, (FILE *)handle);
}
static int file_seek(void *handle, long offset, int whence)
{
return fseek((FILE *)handle, offset, whence);
}
static long file_tell(void *handle)
{
return ftell((FILE *)handle);
}
static int file_eof(void *handle)
{
return feof((FILE *)handle);
}
const struct lbx_file_ops lbx_default_fops = {
.read = file_read,
.seek = file_seek,
.tell = file_tell,
.eof = file_eof,
};
/* Read function for pipes that tracks the number of bytes read. */
static size_t pipe_read(void *buf, size_t size, void *handle)
{
struct lbx_pipe_state *state = handle;
size_t rc;
rc = fread(buf, 1, size, state->f);
state->offset += rc;
return rc;
}
/* Seek function for pipes that reads data into the void. */
static int pipe_seek(void *handle, long offset, int whence)
{
struct lbx_pipe_state *state = handle;
long distance;
switch (whence) {
case SEEK_SET:
distance = offset - state->offset;
break;
case SEEK_CUR:
distance = offset;
break;
case SEEK_END:
distance = -1;
break;
}
if (distance < 0)
return -1;
while (distance > 0) {
static unsigned char oblivion[1024];
size_t rc, amount = MIN(sizeof oblivion, distance);
rc = pipe_read(oblivion, amount, handle);
distance -= rc;
if (rc < amount)
return -1;
}
return 0;
}
static long pipe_tell(void *handle)
{
struct lbx_pipe_state *state = handle;
return state->offset;
}
static int pipe_eof(void *handle)
{
struct lbx_pipe_state *state = handle;
return feof(state->f);
}
const struct lbx_file_ops lbx_pipe_fops = {
.read = pipe_read,
.seek = pipe_seek,
.tell = pipe_tell,
.eof = pipe_eof,
};
static size_t lbx_read(void *buf, size_t size, void *handle)
{
return lbx_file_read(handle, buf, size);
}
static int lbx_seek(void *handle, long offset, int whence)
{
return lbx_file_seek(handle, offset, whence);
}
static long lbx_tell(void *handle)
{
return lbx_file_tell(handle);
}
static int lbx_eof(void *handle)
{
return lbx_file_eof(handle);
}
const struct lbx_file_ops lbx_arch_fops = {
.read = lbx_read,
.seek = lbx_seek,
.tell = lbx_tell,
.eof = lbx_eof,
};