home *** CD-ROM | disk | FTP | other *** search
- /*********
- * ARRREST
- *
- * by Leonard Zerman
- * modified by Tom Rettig
- *
- * Placed in the public domain by Tom Rettig Associates, 10/22/1990.
- *
- * Syntax: ARRREST(<C filename> [,<array name>])
- * Return: True if succesful else false.
- * Notes : This version will restore all the array elements
- * of all data types from a file saved with ARRSAVE().
- * Undefined type becomes logical .F.
- * Only single dimension arrays are supported.
- * The file contains a header of the format:
- * ------------------------------------------------------------------------
- * |Header len|# of items|Largest|chksum|Type table|Len |Position|Items|
- * |int |int |int |int |char * N |int * N|long * N|N * N|
- * -------------------------------------------------------------------------
- *********/
-
- #include "trlib.h"
-
- #define SEEK_SET 0
- #define MAXFNAMELEN 65
-
- typedef union /* union will handle all data types */
- {
- char * ptr; /* ptr for string or date */
- int log; /* int for logical */
- double num; /* double for numerics */
- }DATA;
-
- typedef struct
- {
- int datatype;
- int datalen;
- char datachar;
- void * vptr;
- DATA data;
- }DATAINFO;
-
- typedef struct
- {
- int headerlen;
- int nbr_of_items;
- int largest;
- int chksum;
- }ARRAYHEAD;
-
- typedef struct
- {
- ARRAYHEAD head;
- char * typetable; /* pointer to allocated tables */
- int * lentable;
- long * postable;
- char * buffer;
- int typetablesize;
- int lentablesize;
- int postablesize;
- int buffersize;
- int fhandle;
- long curpos;
- }ARRAYTABLE;
-
- void far * _xalloc(unsigned int size);
- void _xfree(void far *mem);
- static int arrlen(char * fname);
- static int arrget(char * fname, ARRAYTABLE * arrptr, int arrno, int arrlen);
-
- /*-------------------------------------------------------------------------*/
- TRTYPE ARRREST()
- {
- static char fnamebuff[MAXFNAMELEN];
- char * ptr;
- char * fname;
- ARRAYTABLE arraytable;
-
- if(PCOUNT > 0 && ISCHAR(1))
- {
- fname = _parc(1);
- fname = _tr_strcpy(fnamebuff, fname);
- if(!_tr_stpchr(fname, '.'))
- _tr_strcat(fname, ".ARR");
-
- if(PCOUNT == 1)
- _retni(arrlen(fname));
- else if(PCOUNT == 2 && ISARRAY(2))
- _retni(arrget(fname, &arraytable, 2, ALENGTH(2)));
- else
- _retni(-1);
- }
- else
- _retni(-1);
- }
-
- static int arrlen(char * fname)
- {
- int retval;
- int fhandle;
- ARRAYHEAD head;
-
- retval = fhandle = ERRORNEG;
-
- if((fhandle = _tr_open(fname, READONLY)) == ERRORNEG)
- goto EXIT;
- if(_tr_read(fhandle, &head, sizeof(head)) != sizeof(head))
- goto EXIT;
- if(head.chksum != head.headerlen + head.nbr_of_items + head.largest)
- goto EXIT;
-
- retval = head.nbr_of_items;
- EXIT:
- if(fhandle != ERRORNEG)
- _tr_close(fhandle);
- return(retval);
- }
-
- /*-------------------------------------------------------------------------*/
- static int arrget(char * fname, ARRAYTABLE * arrptr, int arrno, int arrlen)
- {
- int status;
- int itemno;
- DATAINFO item;
-
- arrptr->typetable = (char *)0;
- arrptr->lentable = (int *) 0;
- arrptr->postable = (long *)0;
- arrptr->buffer = (char *)0;
- arrptr->fhandle = ERRORNEG;
- status = ERRORNEG;
-
- if((arrptr->fhandle = _tr_open(fname, READONLY)) == ERRORNEG)
- goto ERROREXIT;
-
- if(_tr_read(arrptr->fhandle, &arrptr->head, sizeof(ARRAYHEAD)) !=
- sizeof(ARRAYHEAD))
- goto ERROREXIT;
-
- if(arrptr->head.nbr_of_items < 1)
- goto ERROREXIT;
-
- if(arrptr->head.chksum != arrptr->head.headerlen + arrptr->head.largest +
- arrptr->head.nbr_of_items)
- goto ERROREXIT;
-
- /* table size */
- arrptr->typetablesize = sizeof(char) * arrptr->head.nbr_of_items;
- arrptr->lentablesize = sizeof(int) * arrptr->head.nbr_of_items;
- arrptr->postablesize = sizeof(long) * arrptr->head.nbr_of_items;
- arrptr->buffersize = sizeof(char) * arrptr->head.largest;
-
- /* allocate tables */
- if((arrptr->typetable = (char *)_xalloc(arrptr->typetablesize)) == (char *)0)
- goto ERROREXIT;
-
- if((arrptr->lentable = (int *)_xalloc(arrptr->lentablesize)) == (int *)0)
- goto ERROREXIT;
-
- if((arrptr->postable = (long *)_xalloc(arrptr->postablesize)) == (long *)0)
- goto ERROREXIT;
-
- if((arrptr->buffer = (char *)_xalloc(arrptr->buffersize)) == (char *)0)
- goto ERROREXIT;
-
- if(_tr_read(arrptr->fhandle, arrptr->typetable, arrptr->typetablesize) !=
- arrptr->typetablesize)
- goto ERROREXIT;
-
- if(_tr_read(arrptr->fhandle, arrptr->lentable, arrptr->lentablesize) !=
- arrptr->lentablesize)
- goto ERROREXIT;
-
- if(_tr_read(arrptr->fhandle, arrptr->postable, arrptr->postablesize) !=
- arrptr->postablesize)
- goto ERROREXIT;
-
- if(arrptr->head.nbr_of_items > arrlen)
- arrptr->head.nbr_of_items = arrlen;
-
- for(itemno = 1; itemno <= arrptr->head.nbr_of_items; itemno++)
- {
- item.datachar = arrptr->typetable[itemno - 1];
- item.datalen = arrptr->lentable[itemno - 1];
-
- if(_tr_lseek(arrptr->fhandle, arrptr->postable[itemno - 1], SEEK_SET)
- == ERRORNEGL)
- goto ERROREXIT;
-
- switch(item.datachar)
- {
- case 'B':
- case 'C':
- case 'D':
- item.vptr = (void *)arrptr->buffer;
- break;
-
- case 'N':
- item.vptr = (void *)&item.data.num;
- break;
-
- case 'L':
- item.vptr = (void *)&item.data.log;
- break;
-
- default :
- goto ERROREXIT; /* should never happen */
- }
- if(_tr_read(arrptr->fhandle, item.vptr, item.datalen) != item.datalen)
- goto ERROREXIT;
-
- switch(item.datachar)
- {
- case 'B':
- _storclen(item.vptr, item.datalen -1, arrno, itemno);
- break;
-
- case 'C':
- _storc(item.vptr, arrno, itemno);
- break;
-
- case 'D':
- _stords(item.vptr, arrno, itemno);
- break;
-
- case 'N':
- _stornd(item.data.num, arrno, itemno);
- break;
-
- case 'L':
- _storl(item.data.log, arrno, itemno);
- break;
-
- default : /* should never happen */
- goto ERROREXIT;
- }
- }
- status = arrptr->head.nbr_of_items;
- ERROREXIT:
- if(arrptr->fhandle != ERRORNEG)
- _tr_close(arrptr->fhandle);
- _xfree(arrptr->typetable);
- _xfree(arrptr->lentable);
- _xfree(arrptr->postable);
- _xfree(arrptr->buffer);
- return(status);
- }
- /*-------------------------------------------------------------------------*/
-