/*
* media.c -
*
* Written by Eryk Vershen
*/

/*
* Copyright 1997,1998 by Apple Computer, Inc.
*              All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/


// for printf()
#include <stdio.h>
// for malloc() & free()
#include <stdlib.h>

#include "media.h"


/*
* Defines
*/


/*
* Types
*/


/*
* Global Constants
*/


/*
* Global Variables
*/
static long media_kind = 0;

/*
* Forward declarations
*/


/*
* Routines
*/
long
allocate_media_kind(void)
{
   media_kind++;
   return media_kind;
}


MEDIA
new_media(long size)
{
   return (MEDIA) malloc(size);
}


void
delete_media(MEDIA m)
{
   if (m == 0) {
       return;
   }
   free(m);
}


uint32_t
media_granularity(MEDIA m)
{
   if (m == 0) {
       return 0;
   } else {
       return m->grain;
   }
}


long long
media_total_size(MEDIA m)
{
   if (m == 0) {
       return 0;
   } else {
       return m->size_in_bytes;
   }
}


long
read_media(MEDIA m, long long offset, uint32_t count, void *address)
{
   long result;

   if (m != 0 && m->do_read != 0) {
       //printf("media: read type %d, offset %Ld, count %d\n\t", m->kind, offset, count);
       result = (*m->do_read)(m, offset, count, address);
       //printf(" - returns %d\n", result);
       return result;
   } else {
       return 0;
   }
}


long
write_media(MEDIA m, long long offset, uint32_t count, void *address)
{
   long result;

   if (m != 0 && m->do_write != 0) {
       //printf("media: write type %d, offset %Ld, count %d\n\t", m->kind, offset, count);
       result = (*m->do_write)(m, offset, count, address);
       //printf(" - returns %d\n", result);
       return result;
   } else {
       return 0;
   }
}


void
close_media(MEDIA m)
{
   if (m == 0) {
       return;
   }
   if (m->kind != 0) {
       if (m->do_close != 0) {
           (*m->do_close)(m);
       }
       m->kind = 0;
       delete_media(m);
   }
}


void
os_reload_media(MEDIA m)
{
   if (m != 0 && m->do_os_reload != 0) {
       (*m->do_os_reload)(m);
   }
}


#if !defined(__linux__) && !defined(__unix__)
#pragma mark -
#endif



MEDIA_ITERATOR
new_media_iterator(long size)
{
   return (MEDIA_ITERATOR) malloc(size);
}


void
private_delete_media_iterator(MEDIA_ITERATOR m)
{
   if (m == 0) {
       return;
   }
   free(m);
}


void
reset_media_iterator(MEDIA_ITERATOR m)
{
   if (m != 0 && m->do_reset != 0) {
       (*m->do_reset)(m);
   }
}


char *
step_media_iterator(MEDIA_ITERATOR m)
{
   char *result;

   if (m != 0 && m->do_step != 0) {
       result = (*m->do_step)(m);
   } else {
       result = 0;
   }
   return result;
}


void
delete_media_iterator(MEDIA_ITERATOR m)
{
   if (m == 0) {
       return;
   }
   if (m->kind != 0) {
       if (m->do_delete != 0) {
           (*m->do_delete)(m);
       }
       m->kind = 0;
       private_delete_media_iterator(m);
   }
}