Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
  4.  
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 of the License, or (at your option) any later version.
  9.  
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public
  16.     License along with this library; if not, write to the Free
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     Sam Lantinga
  20.     slouken@devolution.com
  21. */
  22.  
  23. /* This file provides a general interface for SDL to read and write
  24.    data sources.  It can easily be extended to files, memory, etc.
  25. */
  26.  
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30.  
  31. #include "SDL_error.h"
  32. #include "SDL_rwops.h"
  33.  
  34. /* Functions to read/write stdio file pointers */
  35.  
  36. static int stdio_seek(SDL_RWops *context, int offset, int whence)
  37. {
  38.  if ( fseek(context->hidden.stdio.fp, offset, whence) == 0 )
  39.  {
  40.   return(ftell(context->hidden.stdio.fp));
  41.  } else {
  42.   SDL_Error(SDL_EFSEEK);
  43.   return(-1);
  44.  }
  45. }
  46.  
  47. static int stdio_read(SDL_RWops *context, void *ptr, int size, int maxnum)
  48. {
  49.  size_t nread;
  50.  nread = fread(ptr, size, maxnum, context->hidden.stdio.fp);
  51.  if ( nread == 0 && ferror(context->hidden.stdio.fp) )
  52.  {
  53.   SDL_Error(SDL_EFREAD);
  54.  }
  55.  return(nread);
  56. }
  57.  
  58. static int stdio_write(SDL_RWops *context, const void *ptr, int size, int num)
  59. {
  60.  size_t nwrote;
  61.  nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp);
  62.  if ( nwrote == 0 && ferror(context->hidden.stdio.fp) )
  63.  {
  64.   SDL_Error(SDL_EFWRITE);
  65.  }
  66.  return(nwrote);
  67. }
  68.  
  69. static int stdio_close(SDL_RWops *context)
  70. {
  71.  if ( context )
  72.  {
  73.   if ( context->hidden.stdio.autoclose )
  74.   {
  75.    fclose(context->hidden.stdio.fp);
  76.   }
  77.   free(context);
  78.  }
  79.  return(0);
  80. }
  81.  
  82. static int mem_seek(SDL_RWops *context, int offset, int whence)
  83. {
  84.  Uint8 *newpos;
  85.  switch (whence)
  86.  {
  87.   case SEEK_SET:
  88.    newpos = context->hidden.mem.base+offset;
  89.    break;
  90.   case SEEK_CUR:
  91.    newpos = context->hidden.mem.here+offset;
  92.    break;
  93.   case SEEK_END:
  94.    newpos = context->hidden.mem.stop+offset;
  95.    break;
  96.   default:
  97.    SDL_SetError("Unknown value for 'whence'");
  98.    return(-1);
  99.  }
  100.  if ( newpos < context->hidden.mem.base )
  101.  {
  102.   newpos = context->hidden.mem.base;
  103.  }
  104.  if ( newpos > context->hidden.mem.stop )
  105.  {
  106.   newpos = context->hidden.mem.stop;
  107.  }
  108.  context->hidden.mem.here = newpos;
  109.  return(context->hidden.mem.here-context->hidden.mem.base);
  110. }
  111.  
  112. static int mem_read(SDL_RWops *context, void *ptr, int size, int maxnum)
  113. {
  114.  int num;
  115.  num = maxnum;
  116.  if ( (context->hidden.mem.here + (num*size)) > context->hidden.mem.stop )
  117.  {
  118.   num = (context->hidden.mem.stop-context->hidden.mem.here)/size;
  119.  }
  120.  memcpy(ptr, context->hidden.mem.here, num*size);
  121.  context->hidden.mem.here += num*size;
  122.  return(num);
  123. }
  124.  
  125. static int mem_write(SDL_RWops *context, const void *ptr, int size, int num)
  126. {
  127.  if ( (context->hidden.mem.here + (num*size)) > context->hidden.mem.stop )
  128.  {
  129.   num = (context->hidden.mem.stop-context->hidden.mem.here)/size;
  130.  }
  131.  memcpy(context->hidden.mem.here, ptr, num*size);
  132.  context->hidden.mem.here += num*size;
  133.  return(num);
  134. }
  135.  
  136. static int mem_close(SDL_RWops *context)
  137. {
  138.  if ( context )
  139.  {
  140.   free(context);
  141.  }
  142.  return(0);
  143. }
  144.  
  145. SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
  146. {
  147.  FILE *fp;
  148.  SDL_RWops *rwops;
  149.  rwops = NULL;
  150.  fp = fopen(file, mode);
  151.  if ( fp == NULL )
  152.  {
  153.   SDL_SetError("Couldn't open %s", file);
  154.  } else {
  155.   rwops = SDL_RWFromFP(fp, 1);
  156.  }
  157.  return(rwops);
  158. }
  159.  
  160. SDL_RWops *SDL_RWFromFP(FILE *fp, int autoclose)
  161. {
  162.  SDL_RWops *rwops;
  163.  rwops = SDL_AllocRW();
  164.  if ( rwops != NULL )
  165.  {
  166.   rwops->seek = stdio_seek;
  167.   rwops->read = stdio_read;
  168.   rwops->write = stdio_write;
  169.   rwops->close = stdio_close;
  170.   rwops->hidden.stdio.fp = fp;
  171.   rwops->hidden.stdio.autoclose = autoclose;
  172.  }
  173.  return(rwops);
  174. }
  175.  
  176. SDL_RWops *SDL_RWFromMem(void *mem, int size)
  177. {
  178.  SDL_RWops *rwops;
  179.  rwops = SDL_AllocRW();
  180.  if ( rwops != NULL )
  181.  {
  182.   rwops->seek = mem_seek;
  183.   rwops->read = mem_read;
  184.   rwops->write = mem_write;
  185.   rwops->close = mem_close;
  186.   rwops->hidden.mem.base = (Uint8 *)mem;
  187.   rwops->hidden.mem.here = rwops->hidden.mem.base;
  188.   rwops->hidden.mem.stop = rwops->hidden.mem.base+size;
  189.  }
  190.  return(rwops);
  191. }
  192.  
  193. SDL_RWops *SDL_AllocRW(void)
  194. {
  195.  SDL_RWops *area;
  196.  area = (SDL_RWops *)malloc(sizeof *area);
  197.  if ( area == NULL )
  198.  {
  199.   SDL_OutOfMemory();
  200.  }
  201.  return(area);
  202. }
  203.  
  204. void SDL_FreeRW(SDL_RWops *area)
  205. {
  206.  free(area);
  207. }
  208.