Blame src/liboggz/oggz_io.c

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
}