/* Program: BIGARRAY.C Author : Kim Moser Date : 11/17/1991 System : IBM PC / Borland Turbo C 2.0 Descrip: Disk-based arrays */ #include #include #include #include "bigarray.h" static int BigArray_seek(BigArray *array, index_type i); static int BigArray_seek(BigArray *array, index_type i) { if (array->file_pointer_index != i) { array->file_pointer_index = i; return (fseek(array->fp, i*array->elmt_size, SEEK_SET)); } return (0); } BigArray *BigArray_calloc(char *fname, index_type num_elmts, size_t elmt_size) { BigArray *r; index_type i; if ((r = malloc(sizeof(*r))) != NULL) { if ((r->fname = strdup(fname)) == NULL) { free(r); return (NULL); } if ((r->fp = fopen(fname, "wb+")) == NULL) { free(r->fname); free(r); return (NULL); } r->num_elmts = num_elmts; r->elmt_size = elmt_size; if ((r->last_elmt = calloc((size_t) 1, (size_t) elmt_size)) == NULL) { free(r->fname); fclose(r->fp); free(r); return (NULL); } r->last_elmt_index = -1L; for (i=0; i < num_elmts; i++) { if (fwrite((void*) r->last_elmt, (size_t) elmt_size, (size_t) 1, r->fp) != (size_t) 1) { free(r->fname); free(r->last_elmt); fclose(r->fp); free(r); return (NULL); } } if (fseek(r->fp, 0L, SEEK_SET)) { free(r->fname); fclose(r->fp); free(r->last_elmt); free(r); return (NULL); } r->last_elmt_index = -1L; r->file_pointer_index = 0; } return (r); } int BigArray_free(BigArray *array) { if (fclose(array->fp)) return (0); if (unlink(array->fname)) return (0); free(array->fname); free(array->last_elmt); return (1); } void *BigArray_element(BigArray *array, index_type i, void *dest) { if (i != array->last_elmt_index) { if (BigArray_seek(array, i)) { return (NULL); } if (fread(array->last_elmt, (size_t) array->elmt_size, (size_t) 1, array->fp) != (size_t) 1) { return (NULL); } array->last_elmt_index = i; array->file_pointer_index++; memcpy(dest, array->last_elmt, array->elmt_size); } return (dest); } int BigArray_assign(BigArray *array, index_type i, void *src) { if (i == array->last_elmt_index) { memcpy(array->last_elmt, src, array->elmt_size); } if (BigArray_seek(array, i)) { return (0); } if (fwrite(src, array->elmt_size, 1, array->fp) != 1) { return (0); } array->file_pointer_index++; return (1); } #if 0 #define NUM_ELMTS 10 #define ELMT_TYPE char void main(void) { index_type i, j; ELMT_TYPE e; BigArray *array; if ((array = BigArray_calloc("f:array.$$$", NUM_ELMTS, sizeof(ELMT_TYPE))) == NULL) { fprintf(stderr, "BigArray_calloc() failed.\n"); exit(-1); } for (i=0; i < NUM_ELMTS; i++) { e = random(255); j = random(NUM_ELMTS); fprintf(stderr, "%ld'th elmt = %d\n", j, (int) e); if (!BigArray_assign(array, j, (void*) &e)) { fprintf(stderr, "BigArray_assign() failed for %ld'th elmt.\n", i); exit(-1); } } fprintf(stderr, "\n"); for (i=0; i < NUM_ELMTS; i++) { if (BigArray_element(array, i, &e) == NULL) { fprintf(stderr, "BigArray_element() failed for %ld'th elmt.\n", i); exit(-1); } fprintf(stderr, "%ld'th elmt = %d.\n", i, (int) e); } if (!BigArray_free(array)) { fprintf(stderr, "BigArray_free() failed.\n"); exit(-1); } } #endif