3
** This program and library is free software; you can redistribute it and/or
4
** modify it under the terms of the GNU (Library) General Public License
5
** as published by the Free Software Foundation; either version 2
6
** of the License, or any later version.
8
** This program is distributed in the hope that it will be useful,
9
** but WITHOUT ANY WARRANTY; without even the implied warranty of
10
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
** GNU (Library) General Public License for more details.
13
** You should have received a copy of the GNU (Library) General Public License
14
** along with this program; if not, write to the Free Software
15
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
** 2001-06-21 jmruiz ramdisk module or "poor man ramdisk" - Initial coding
19
** to test with LOCATIONS but it can be used with other
21
** Writes: Only sequential write is allowed
22
** Reads: Direct and sequential reads are allowed
23
** Routines and its equivalents:
25
** ramdisk_create fopen
27
** ramdisk_write fwrite
28
** ramdisk_read fwrite
30
** ramdisk_close fclose
41
** Routines to store/extract location data in memory incontigous positions to sa
44
** The data has been compressed previously in memory.
45
** Returns the pointer to the memory.
50
unsigned long cur_pos;
51
unsigned long end_pos;
52
unsigned int n_buffers;
53
unsigned int buf_size;
54
unsigned char **buffer;
59
/* Create a new ramdisk - The size of the internal buffers is buf_size */
60
struct ramdisk *ramdisk_create(char *name, int buf_size)
64
rd = (struct ramdisk *) emalloc(sizeof(struct ramdisk));
65
rd->zone = Mem_ZoneCreate(name, buf_size, 0);
69
rd->buf_size = buf_size;
70
rd->buffer = (unsigned char **)emalloc(sizeof(unsigned char *));
71
rd->buffer[0] = (unsigned char *)Mem_ZoneAlloc(rd->zone, buf_size);
75
/* Closes / frees the memory used by the ramdisk */
76
int ramdisk_close(FILE *fp)
78
struct ramdisk *rd = (struct ramdisk *)fp;
80
Mem_ZoneFree(&rd->zone);
86
void add_buffer_ramdisk(struct ramdisk *rd)
88
rd->buffer = (unsigned char **)erealloc(rd->buffer,(rd->n_buffers + 1) * sizeof(unsigned char *));
89
rd->buffer[rd->n_buffers++] = (unsigned char *)Mem_ZoneAlloc(rd->zone, rd->buf_size);
92
/* Equivalent to ftell to get the position while writing to the ramdisk */
93
long ramdisk_tell(FILE *fp)
95
struct ramdisk *rd = (struct ramdisk *)fp;
101
/* Writes to the ramdisk - The parameters are identical to those in fwrite */
102
size_t ramdisk_write(const void *buffer,size_t sz1, size_t sz2, FILE *fp)
104
unsigned int lenbuf=(unsigned int)(sz1 *sz2);
105
struct ramdisk *rd = (struct ramdisk *)fp;
106
unsigned char *buf = (unsigned char *)buffer;
107
unsigned int num_buffer,start_pos,tmplenbuf = lenbuf;
110
num_buffer = rd->cur_pos / rd->buf_size;
111
start_pos = rd->cur_pos % rd->buf_size;
113
avail = rd->buf_size - start_pos;
114
while(avail<=(unsigned int)lenbuf)
117
memcpy(rd->buffer[num_buffer]+start_pos,buf,avail);
119
rd->cur_pos += avail;
121
add_buffer_ramdisk(rd);
122
avail = rd->buf_size;
128
memcpy(rd->buffer[num_buffer]+start_pos,buf,lenbuf);
129
rd->cur_pos += lenbuf;
131
if(rd->cur_pos > rd->end_pos)
132
rd->end_pos = rd->cur_pos;
134
/* needs to return number of elements, not number of bytes */
138
/* Equivalent to fseek */
139
int ramdisk_seek(FILE *fp,long pos, int set)
141
struct ramdisk *rd = (struct ramdisk *)fp;
152
if( pos > rd->end_pos )
154
while(rd->end_pos < pos)
156
ramdisk_putc(0, (FILE *)rd);
167
/* Reads from the ramdisk - The parameters are identical to those in fread */
168
size_t ramdisk_read(void *buf, size_t sz1, size_t sz2, FILE *fp)
170
struct ramdisk *rd = (struct ramdisk *)fp;
171
unsigned int len = (unsigned int) (sz1 *sz2);
172
unsigned char *buffer = (unsigned char *)buf;
173
unsigned int avail, num_buffer, start_pos, buffer_offset;
175
if(rd->cur_pos >= rd->end_pos)
177
if((rd->cur_pos + len) > rd->end_pos)
179
len = rd->end_pos - rd->cur_pos;
181
num_buffer = rd->cur_pos / rd->buf_size;
182
start_pos = rd->cur_pos % rd->buf_size;
186
avail = rd->buf_size - start_pos;
187
while(avail < (unsigned int)len)
189
memcpy(buffer+buffer_offset,rd->buffer[num_buffer]+start_pos,avail);
190
buffer_offset += avail;
191
rd->cur_pos += avail;
195
avail = rd->buf_size;
196
if(num_buffer == rd->n_buffers)
197
return buffer_offset;
199
memcpy(buffer+buffer_offset,rd->buffer[num_buffer]+start_pos,len);
201
buffer_offset += len;
202
return buffer_offset;
205
int ramdisk_getc(FILE *fp)
209
ramdisk_read((void *)&c, 1, 1, fp);
210
return (int) ((unsigned char)c);
213
int ramdisk_putc(int c, FILE *fp)
215
unsigned char tmp = (unsigned char)c;
217
ramdisk_write((const void *)&tmp,1, 1, fp);