home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
xbase
/
library
/
clipper
/
rettig
/
source
/
arrrest.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-21
|
7KB
|
249 lines
/*********
* 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);
}
/*-------------------------------------------------------------------------*/