home *** CD-ROM | disk | FTP | other *** search
- /*********
- * ARRSAVE
- *
- * by Leonard Zerman
- * modified by Tom Rettig
- *
- * Placed in the public domain by Tom Rettig Associates, 10/22/1990.
- *
- * Syntax: ARRSAVE(<filename>, <array>)
- * Return: True if succesful else false.
- * Note : This version will save all the array elements
- * of all data types to a file.
- * 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 DATESTRLEN 9 /* 8 bytes + NULL = 9 */
- #define SEEK_SET 0
- #define UNDEFINED 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);
-
- /*-------------------------------------------------------------------------*/
-
- TRTYPE ARRSAVE()
- {
- static char fnamebuff[MAXFNAMELEN];
- int i;
- int len;
- int retval;
- char * fname;
- DATAINFO item;
- ARRAYTABLE arraytable;
-
- retval = FALSE;
- arraytable.typetable = (char *)0;
- arraytable.lentable = (int *) 0;
- arraytable.postable = (long *)0;
- arraytable.fhandle = ERRORNEG;
-
- if(PCOUNT == 2 && ISCHAR(1) && ISARRAY(2))
- {
- fname = _parc(1);
- if((arraytable.head.nbr_of_items = ALENGTH(2)) < 1)
- goto ERROREXIT;
-
- fname = _tr_strcpy(fnamebuff, fname);
- if(!_tr_stpchr(fname, '.'))
- _tr_strcat(fname, ".ARR");
-
- if((arraytable.fhandle = _tr_creat(fname, FL_NORMAL))
- == ERRORNEG)
- goto ERROREXIT;
- /*-------------------------------------------------------------------------*/
- arraytable.typetablesize = sizeof(char) * arraytable.head.nbr_of_items;
- arraytable.lentablesize = sizeof(int) * arraytable.head.nbr_of_items;
- arraytable.postablesize = sizeof(long) * arraytable.head.nbr_of_items;
-
- /* allocate tables */
- if((arraytable.typetable = (char *)_xalloc(arraytable.typetablesize)) == (char *)0)
- goto ERROREXIT;
- if((arraytable.lentable = (int *)_xalloc(arraytable.lentablesize)) == (int *)0)
- goto ERROREXIT;
- if((arraytable.postable = (long *)_xalloc(arraytable.postablesize)) == (long *)0)
- goto ERROREXIT;
-
- /*-------------------------------------------------------------------------*/
- arraytable.head.largest = 0;
- arraytable.head.headerlen = sizeof(arraytable.head) +
- arraytable.typetablesize +
- arraytable.lentablesize +
- arraytable.postablesize;
-
- if((arraytable.curpos =_tr_lseek(arraytable.fhandle,
- (long)arraytable.head.headerlen, SEEK_SET)) == ERRORNEGL)
- goto ERROREXIT;
- /*-------------------------------------------------------------------------*/
- for(i = 1; i <= arraytable.head.nbr_of_items; i++)
- {
- item.datatype = _parinfa(2,i) & 0x000F; /* find out what data type */
-
- switch(item.datatype)
- {
- case CHARACTER:
- item.data.ptr = _parc(2,i); /* assign char * */
- item.vptr = item.data.ptr;
- item.datalen = _parclen(2,i) + 1;
- if(item.datalen == strlen(item.data.ptr) + 1)
- item.datachar = 'C';
- else
- item.datachar = 'B';
- break;
- case NUMERIC:
- item.data.num = _parnd(2,i); /* assign double */
- item.vptr = &item.data.num;
- item.datalen = sizeof(double);
- item.datachar = 'N';
- break;
- case LOGICAL:
- item.data.log = _parl(2,i); /* assign logical int */
- item.vptr = &item.data.log;
- item.datalen = sizeof(int);
- item.datachar = 'L';
- break;
- case DATE:
- item.data.ptr = _pards(2,i); /* assign char* to date string */
- item.vptr = item.data.ptr;
- item.datalen = DATESTRLEN;
- item.datachar = 'D';
- break;
- case UNDEFINED:
- default:
- item.data.log = 0; /* assign logical int */
- item.vptr = &item.data.log;
- item.datalen = sizeof(int);
- item.datachar = 'L';
- } /* end switch */
- arraytable.typetable[i - 1] = item.datachar;
- arraytable.lentable[i - 1] = item.datalen;
- arraytable.postable[i - 1] = arraytable.curpos;
- arraytable.curpos += item.datalen;
-
- if(item.datalen > arraytable.head.largest)
- arraytable.head.largest = item.datalen;
-
- if(_tr_write(arraytable.fhandle, item.vptr, item.datalen) !=
- item.datalen)
- goto ERROREXIT;
- } /* end of for-loop */
- /*-------------------------------------------------------------------------*/
- arraytable.head.chksum = arraytable.head.headerlen +
- arraytable.head.nbr_of_items +
- arraytable.head.largest;
- /* write header */
- if(_tr_lseek(arraytable.fhandle,0L,SEEK_SET) == ERRORNEGL)
- goto ERROREXIT;
- if(_tr_write(arraytable.fhandle, &arraytable.head,
- sizeof(arraytable.head)) != sizeof(arraytable.head))
- goto ERROREXIT;
- if(_tr_write(arraytable.fhandle, arraytable.typetable,
- arraytable.typetablesize) != arraytable.typetablesize)
- goto ERROREXIT;
- if(_tr_write(arraytable.fhandle, arraytable.lentable,
- arraytable.lentablesize) != arraytable.lentablesize)
- goto ERROREXIT;
- if(_tr_write(arraytable.fhandle, arraytable.postable,
- arraytable.postablesize) != arraytable.postablesize)
- goto ERROREXIT;
-
- retval = TRUE;
- ERROREXIT:
- if(arraytable.fhandle != ERRORNEG)
- _tr_close(arraytable.fhandle);
- _xfree(arraytable.typetable);
- _xfree(arraytable.lentable);
- _xfree(arraytable.postable);
- }
- _retl(retval);
- }
- /*-------------------------------------------------------------------------*/
-