|
Packit |
a38265 |
/*
|
|
Packit |
a38265 |
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
|
Packit |
a38265 |
Organisation (CSIRO) Australia
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
a38265 |
modification, are permitted provided that the following conditions
|
|
Packit |
a38265 |
are met:
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Redistributions of source code must retain the above copyright
|
|
Packit |
a38265 |
notice, this list of conditions and the following disclaimer.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Redistributions in binary form must reproduce the above copyright
|
|
Packit |
a38265 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit |
a38265 |
documentation and/or other materials provided with the distribution.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Neither the name of CSIRO Australia nor the names of its
|
|
Packit |
a38265 |
contributors may be used to endorse or promote products derived from
|
|
Packit |
a38265 |
this software without specific prior written permission.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
a38265 |
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
a38265 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
Packit |
a38265 |
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
|
Packit |
a38265 |
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
Packit |
a38265 |
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
Packit |
a38265 |
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit |
a38265 |
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit |
a38265 |
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
Packit |
a38265 |
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
Packit |
a38265 |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
a38265 |
*/
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/*
|
|
Packit |
a38265 |
* oggz_io.c
|
|
Packit |
a38265 |
*
|
|
Packit |
a38265 |
* Conrad Parker <conrad@annodex.net>
|
|
Packit |
a38265 |
*/
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include "config.h"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include <stdio.h>
|
|
Packit |
a38265 |
#include <stdlib.h>
|
|
Packit |
a38265 |
#include <string.h>
|
|
Packit |
a38265 |
#include <errno.h>
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include "oggz_compat.h"
|
|
Packit |
a38265 |
#include "oggz_private.h"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/*#define DEBUG*/
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
size_t
|
|
Packit |
a38265 |
oggz_io_read (OGGZ * oggz, void * buf, size_t n)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OggzIO * io;
|
|
Packit |
a38265 |
size_t bytes;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->file != NULL) {
|
|
Packit |
a38265 |
if ((bytes = fread (buf, 1, n, oggz->file)) == 0) {
|
|
Packit |
a38265 |
if (ferror (oggz->file)) {
|
|
Packit |
a38265 |
return (size_t) OGGZ_ERR_SYSTEM;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else if ((io = oggz->io) != NULL) {
|
|
Packit |
a38265 |
if (io->read == NULL) return (size_t) -1;
|
|
Packit |
a38265 |
bytes = io->read (io->read_user_handle, buf, n);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else return (size_t) OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return bytes;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
size_t
|
|
Packit |
a38265 |
oggz_io_write (OGGZ * oggz, void * buf, size_t n)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OggzIO * io;
|
|
Packit |
a38265 |
size_t bytes;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->file != NULL) {
|
|
Packit |
a38265 |
bytes = fwrite (buf, 1, n, oggz->file);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else if ((io = oggz->io) != NULL) {
|
|
Packit |
a38265 |
if (io->write == NULL) return (size_t) -1;
|
|
Packit |
a38265 |
bytes = io->write (io->write_user_handle, buf, n);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else {
|
|
Packit |
a38265 |
return (size_t) OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return bytes;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_io_seek (OGGZ * oggz, long offset, int whence)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OggzIO * io;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->file != NULL) {
|
|
Packit |
a38265 |
if (fseek (oggz->file, offset, whence) == -1) {
|
|
Packit |
a38265 |
if (errno == ESPIPE) {
|
|
Packit |
a38265 |
/*oggz_set_error (oggz, OGGZ_ERR_NOSEEK);*/
|
|
Packit |
a38265 |
} else {
|
|
Packit |
a38265 |
/*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
return OGGZ_ERR_SYSTEM;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else if ((io = oggz->io) != NULL) {
|
|
Packit |
a38265 |
if (io->seek == NULL) return -1;
|
|
Packit |
a38265 |
if (io->seek (io->seek_user_handle, offset, whence) == -1)
|
|
Packit |
a38265 |
return -1;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else return OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
long
|
|
Packit |
a38265 |
oggz_io_tell (OGGZ * oggz)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OggzIO * io;
|
|
Packit |
a38265 |
long offset;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->file != NULL) {
|
|
Packit |
a38265 |
if ((offset = ftell (oggz->file)) == -1) {
|
|
Packit |
a38265 |
if (errno == ESPIPE) {
|
|
Packit |
a38265 |
/*oggz_set_error (oggz, OGGZ_ERR_NOSEEK);*/
|
|
Packit |
a38265 |
} else {
|
|
Packit |
a38265 |
/*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
return -1;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else if ((io = oggz->io) != NULL) {
|
|
Packit |
a38265 |
if (io->tell == NULL) return -1;
|
|
Packit |
a38265 |
if ((offset = io->tell (io->tell_user_handle)) == -1)
|
|
Packit |
a38265 |
return -1;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else return OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return offset;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_io_flush (OGGZ * oggz)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OggzIO * io;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->file != NULL) {
|
|
Packit |
a38265 |
if (fflush (oggz->file) == EOF) {
|
|
Packit |
a38265 |
/* check errno for write-related errors */
|
|
Packit |
a38265 |
return OGGZ_ERR_SYSTEM;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else if ((io = oggz->io) != NULL) {
|
|
Packit |
a38265 |
if (io->flush == NULL) return OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (io->flush (io->flush_user_handle) == -1) {
|
|
Packit |
a38265 |
return -1;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
else return OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/* get/set functions */
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static int
|
|
Packit |
a38265 |
oggz_io_init (OGGZ * oggz)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz->io = (OggzIO *) oggz_malloc (sizeof (OggzIO));
|
|
Packit |
a38265 |
if (oggz->io == NULL) return -1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
memset (oggz->io, 0, sizeof (OggzIO));
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_io_set_read (OGGZ * oggz, OggzIORead read, void * user_handle)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) {
|
|
Packit |
a38265 |
if (oggz_io_init (oggz) == -1)
|
|
Packit |
a38265 |
return OGGZ_ERR_OUT_OF_MEMORY;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
oggz->io->read = read;
|
|
Packit |
a38265 |
oggz->io->read_user_handle = user_handle;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
void *
|
|
Packit |
a38265 |
oggz_io_get_read_user_handle (OGGZ * oggz)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return NULL;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return oggz->io->read_user_handle;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_io_set_write (OGGZ * oggz, OggzIOWrite write, void * user_handle)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) {
|
|
Packit |
a38265 |
if (oggz_io_init (oggz) == -1)
|
|
Packit |
a38265 |
return OGGZ_ERR_OUT_OF_MEMORY;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
oggz->io->write = write;
|
|
Packit |
a38265 |
oggz->io->write_user_handle = user_handle;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
void *
|
|
Packit |
a38265 |
oggz_io_get_write_user_handle (OGGZ * oggz)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return NULL;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return oggz->io->write_user_handle;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_io_set_seek (OGGZ * oggz, OggzIOSeek seek, void * user_handle)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) {
|
|
Packit |
a38265 |
if (oggz_io_init (oggz) == -1)
|
|
Packit |
a38265 |
return OGGZ_ERR_OUT_OF_MEMORY;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
oggz->io->seek = seek;
|
|
Packit |
a38265 |
oggz->io->seek_user_handle = user_handle;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
void *
|
|
Packit |
a38265 |
oggz_io_get_seek_user_handle (OGGZ * oggz)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return NULL;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return oggz->io->seek_user_handle;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_io_set_tell (OGGZ * oggz, OggzIOTell tell, void * user_handle)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) {
|
|
Packit |
a38265 |
if (oggz_io_init (oggz) == -1)
|
|
Packit |
a38265 |
return OGGZ_ERR_OUT_OF_MEMORY;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
oggz->io->tell = tell;
|
|
Packit |
a38265 |
oggz->io->tell_user_handle = user_handle;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
void *
|
|
Packit |
a38265 |
oggz_io_get_tell_user_handle (OGGZ * oggz)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return NULL;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return oggz->io->tell_user_handle;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_io_set_flush (OGGZ * oggz, OggzIOFlush flush, void * user_handle)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) {
|
|
Packit |
a38265 |
if (oggz_io_init (oggz) == -1)
|
|
Packit |
a38265 |
return OGGZ_ERR_OUT_OF_MEMORY;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
oggz->io->flush = flush;
|
|
Packit |
a38265 |
oggz->io->flush_user_handle = user_handle;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
void *
|
|
Packit |
a38265 |
oggz_io_get_flush_user_handle (OGGZ * oggz)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (oggz == NULL) return NULL;
|
|
Packit |
a38265 |
if (oggz->file != NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz->io == NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return oggz->io->flush_user_handle;
|
|
Packit |
a38265 |
}
|