home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1988
/
05
/
tichnr
/
varray.c
next >
Wrap
Text File
|
1988-04-04
|
4KB
|
175 lines
/* Virtual Array Access Routines */
#include <varray.h>
#define header 7
/****************
* init_v_array *
****************/
int init_v_array(filename,rec_size,filchar)
char *filename, filchar;
int rec_size;
{
long size;
FILE *f;
f = fopen(filename,"wb");
if (f != NULL) {
size = 0;
fwrite(&size,4,1,f); /* write array size of zero */
fwrite(&rec_size,2,1,f); /* and array element size */
fwrite(&filchar,1,1,f); /* and fill char */
fclose(f); /* to file header */
return(1);
}
else
return(NULL);
}
/****************
* open_v_array *
****************/
VACB *open_v_array(filename,buffer_size)
char *filename;
int buffer_size;
{
VACB *v_array;
char *buf_ptr;
int i;
char filchar;
/* allocate virtual array control block */
v_array = (VACB *) malloc(sizeof(VACB));
if (v_array == NULL) return(NULL);
/* open virtual array file */
v_array->file = fopen(filename,"r+b");
if (v_array->file == NULL) {
free(v_array);
return(NULL);
};
/* get array size and element size for control block */
fread(&v_array->size,4,1,v_array->file);
fread(&v_array->elsize,2,1,v_array->file);
fread(&filchar,1,1,v_array->file);
v_array->buf_elsize = v_array->elsize + 4;
/* allocate buffer */
v_array->buffer = (char *) malloc(v_array->buf_elsize * (buffer_size + 1));
if (v_array->buffer == NULL) {
fclose(v_array->file);
free(v_array);
return(NULL);
};
v_array->buf_size = buffer_size;
/* set up blank_rec using the fill character in array header */
/* for initializing new array elements */
buf_ptr = v_array->buffer + v_array->buf_elsize * v_array->buf_size;
v_array->blank_rec = buf_ptr + 4;
for (i=0; i < v_array->buf_elsize; i++)
*buf_ptr++ = filchar;
/* set record index negative for all buffer elements */
buf_ptr = v_array->buffer;
for (i = 0; i < v_array->buf_size; i++) {
*((long *)buf_ptr) = -1L;
buf_ptr += v_array->buf_elsize;
};
return(v_array);
}
/*****************
* close_v_array *
*****************/
void close_v_array(v_array)
VACB *v_array;
{
int i;
char *buf_ptr;
long rec_index, file_offset;
buf_ptr = v_array->buffer;
/* flush buffer */
for (i=0; i < v_array->buf_size; i++) {
/* check each element index */
/* if element present, write it to disk */
rec_index = *((long *)buf_ptr);
if (rec_index >= 0) {
file_offset = header + rec_index * v_array->elsize;
fseek(v_array->file,file_offset,0);
fwrite(buf_ptr + 4, v_array->elsize,1, v_array->file);
};
buf_ptr += v_array->buf_elsize;
};
free(v_array->buffer); /* de-allocate buffer */
fclose(v_array->file); /* close array file */
free(v_array); /* de-allocate VACB */
}
/****************
* access_v_rec *
****************/
void *access_v_rec(v_array,index)
VACB *v_array;
long index;
{
char *buf_ptr;
int buf_index;
long rec_index, temp_index;
/* calculate buffer address of referenced element */
buf_index = index % v_array->buf_size;
buf_ptr = v_array->buffer + buf_index * v_array->buf_elsize;
rec_index = *(long *)buf_ptr;
/* if element present, return its buffer address */
if (rec_index == index) return(buf_ptr + 4);
/* if element doesn't exist, extend the file */
if (index >= v_array->size) {
fseek(v_array->file,0,2);
for (temp_index = v_array->size; temp_index++ <= index; )
fwrite(v_array->blank_rec, v_array->elsize, 1, v_array->file);
v_array->size = index + 1;
fseek(v_array->file,0,0);
fwrite(&v_array->size, 4, 1, v_array->file);
};
/* if buffer slot is occupied by another element, */
/* save it to disk */
if (rec_index >= 0) {
fseek(v_array->file, rec_index * v_array->elsize + header, 0);
fwrite(buf_ptr + 4, v_array->elsize, 1, v_array->file);
};
/* read referenced element into buffer slot */
fseek(v_array->file, index * v_array->elsize + header, 0);
fread(buf_ptr + 4, v_array->elsize, 1, v_array->file);
*((long *)buf_ptr) = index;
/* return address of element in buffer */
return(buf_ptr + 4);
}