Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 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 
28
#include 
29
#include 
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
}