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

  1. /*********
  2. *  ARRREST
  3. *
  4. *  by Leonard Zerman
  5. *  modified by Tom Rettig
  6. *
  7. * Placed in the public domain by Tom Rettig Associates, 10/22/1990.
  8. *
  9. *  Syntax: ARRREST(<C filename> [,<array name>])
  10. *  Return: True if succesful else false.
  11. *  Notes : This version will restore all the array elements
  12. *          of all data types from a file saved with ARRSAVE().
  13. *          Undefined type becomes logical .F.
  14. *          Only single dimension arrays are supported.
  15. *          The file contains a header of the format:
  16. * ------------------------------------------------------------------------
  17. * |Header len|# of items|Largest|chksum|Type table|Len    |Position|Items|
  18. * |int       |int       |int    |int   |char * N  |int * N|long * N|N * N|
  19. * -------------------------------------------------------------------------
  20. *********/
  21.  
  22. #include "trlib.h"
  23.  
  24. #define SEEK_SET   0
  25. #define MAXFNAMELEN 65
  26.  
  27. typedef union                       /* union will handle all data types */
  28. {
  29.    char * ptr;                      /* ptr for string or date */
  30.    int    log;                      /* int for logical */
  31.    double num;                      /* double for numerics */
  32. }DATA;
  33.  
  34. typedef struct
  35. {
  36.    int  datatype;
  37.    int  datalen;
  38.    char datachar;
  39.    void * vptr;
  40.    DATA data;
  41. }DATAINFO;
  42.  
  43. typedef struct
  44. {
  45.    int headerlen;
  46.    int nbr_of_items;
  47.    int largest;
  48.    int chksum;
  49. }ARRAYHEAD;
  50.  
  51. typedef struct
  52. {
  53.    ARRAYHEAD head;
  54.    char * typetable;                      /* pointer to allocated tables */
  55.    int  * lentable;
  56.    long * postable;
  57.    char * buffer;
  58.    int  typetablesize;
  59.    int  lentablesize;
  60.    int  postablesize;
  61.    int  buffersize;
  62.    int  fhandle;
  63.    long curpos;
  64. }ARRAYTABLE;
  65.  
  66. void far * _xalloc(unsigned int size);
  67. void _xfree(void far *mem);
  68. static int arrlen(char * fname);
  69. static int arrget(char * fname, ARRAYTABLE * arrptr, int arrno, int arrlen);
  70.  
  71. /*-------------------------------------------------------------------------*/
  72. TRTYPE ARRREST()
  73. {
  74.    static char fnamebuff[MAXFNAMELEN];
  75.    char * ptr;
  76.    char * fname;
  77.    ARRAYTABLE arraytable;
  78.  
  79.    if(PCOUNT > 0 && ISCHAR(1))
  80.    {
  81.       fname = _parc(1);
  82.       fname = _tr_strcpy(fnamebuff, fname);
  83.       if(!_tr_stpchr(fname, '.'))
  84.          _tr_strcat(fname, ".ARR");
  85.  
  86.       if(PCOUNT == 1)
  87.          _retni(arrlen(fname));
  88.       else if(PCOUNT == 2 && ISARRAY(2))
  89.          _retni(arrget(fname, &arraytable, 2, ALENGTH(2)));
  90.       else
  91.          _retni(-1);
  92.    }
  93.    else
  94.       _retni(-1);
  95. }
  96.  
  97. static int arrlen(char * fname)
  98. {
  99.    int retval;
  100.    int fhandle;
  101.    ARRAYHEAD head;
  102.  
  103.    retval = fhandle = ERRORNEG;
  104.  
  105.    if((fhandle = _tr_open(fname, READONLY)) == ERRORNEG)
  106.       goto EXIT;
  107.    if(_tr_read(fhandle, &head, sizeof(head)) != sizeof(head))
  108.       goto EXIT;
  109.    if(head.chksum != head.headerlen + head.nbr_of_items + head.largest)
  110.       goto EXIT;
  111.  
  112.    retval = head.nbr_of_items;
  113. EXIT:
  114.    if(fhandle != ERRORNEG)
  115.       _tr_close(fhandle);
  116.    return(retval);
  117. }
  118.  
  119. /*-------------------------------------------------------------------------*/
  120. static int arrget(char * fname, ARRAYTABLE * arrptr, int arrno, int arrlen)
  121. {
  122.    int status;
  123.    int itemno;
  124.    DATAINFO item;
  125.  
  126.    arrptr->typetable = (char *)0;
  127.    arrptr->lentable  = (int *) 0;
  128.    arrptr->postable  = (long *)0;
  129.    arrptr->buffer    = (char *)0;
  130.    arrptr->fhandle   = ERRORNEG;
  131.    status            = ERRORNEG;
  132.  
  133.    if((arrptr->fhandle = _tr_open(fname, READONLY)) == ERRORNEG) 
  134.       goto ERROREXIT;
  135.  
  136.    if(_tr_read(arrptr->fhandle, &arrptr->head, sizeof(ARRAYHEAD)) != 
  137.          sizeof(ARRAYHEAD))
  138.       goto ERROREXIT;
  139.  
  140.    if(arrptr->head.nbr_of_items < 1)
  141.       goto ERROREXIT;
  142.  
  143.    if(arrptr->head.chksum != arrptr->head.headerlen + arrptr->head.largest +
  144.                              arrptr->head.nbr_of_items)
  145.       goto ERROREXIT;
  146.  
  147.    /* table size */
  148.    arrptr->typetablesize = sizeof(char) * arrptr->head.nbr_of_items;
  149.    arrptr->lentablesize  = sizeof(int)  * arrptr->head.nbr_of_items;
  150.    arrptr->postablesize  = sizeof(long) * arrptr->head.nbr_of_items;
  151.    arrptr->buffersize    = sizeof(char) * arrptr->head.largest;
  152.  
  153.    /* allocate tables */
  154.    if((arrptr->typetable = (char *)_xalloc(arrptr->typetablesize)) == (char *)0)
  155.       goto ERROREXIT;
  156.  
  157.    if((arrptr->lentable  = (int *)_xalloc(arrptr->lentablesize))   == (int *)0)
  158.       goto ERROREXIT;
  159.  
  160.    if((arrptr->postable  = (long *)_xalloc(arrptr->postablesize))  == (long *)0)
  161.       goto ERROREXIT;
  162.  
  163.    if((arrptr->buffer    = (char *)_xalloc(arrptr->buffersize))    == (char *)0)
  164.       goto ERROREXIT;
  165.  
  166.    if(_tr_read(arrptr->fhandle, arrptr->typetable, arrptr->typetablesize) != 
  167.       arrptr->typetablesize)
  168.       goto ERROREXIT;
  169.  
  170.    if(_tr_read(arrptr->fhandle, arrptr->lentable, arrptr->lentablesize) != 
  171.       arrptr->lentablesize)
  172.       goto ERROREXIT;
  173.  
  174.    if(_tr_read(arrptr->fhandle, arrptr->postable, arrptr->postablesize) != 
  175.       arrptr->postablesize)
  176.       goto ERROREXIT;
  177.  
  178.    if(arrptr->head.nbr_of_items > arrlen)
  179.       arrptr->head.nbr_of_items = arrlen;
  180.  
  181.    for(itemno = 1; itemno <= arrptr->head.nbr_of_items; itemno++)
  182.    {
  183.       item.datachar = arrptr->typetable[itemno - 1];
  184.       item.datalen  = arrptr->lentable[itemno - 1];
  185.  
  186.       if(_tr_lseek(arrptr->fhandle, arrptr->postable[itemno - 1], SEEK_SET)
  187.          == ERRORNEGL)
  188.          goto ERROREXIT;
  189.  
  190.       switch(item.datachar)
  191.       {
  192.          case 'B':
  193.          case 'C':
  194.          case 'D':
  195.             item.vptr = (void *)arrptr->buffer;
  196.             break;
  197.  
  198.          case 'N':
  199.             item.vptr = (void *)&item.data.num;
  200.             break;
  201.  
  202.          case 'L':
  203.             item.vptr = (void *)&item.data.log;
  204.             break;
  205.  
  206.          default :
  207.             goto ERROREXIT;            /* should never happen */
  208.       }
  209.       if(_tr_read(arrptr->fhandle, item.vptr, item.datalen) != item.datalen)
  210.          goto ERROREXIT;
  211.  
  212.       switch(item.datachar)
  213.       {
  214.          case 'B':
  215.             _storclen(item.vptr, item.datalen -1, arrno, itemno);
  216.             break;
  217.  
  218.          case 'C':
  219.             _storc(item.vptr, arrno, itemno);
  220.             break;
  221.  
  222.          case 'D':
  223.             _stords(item.vptr, arrno, itemno);
  224.             break;
  225.  
  226.          case 'N':
  227.             _stornd(item.data.num, arrno, itemno);
  228.             break;
  229.  
  230.          case 'L':
  231.             _storl(item.data.log, arrno, itemno);
  232.             break;
  233.  
  234.          default :                      /* should never happen */
  235.             goto ERROREXIT;
  236.       }
  237.    }
  238.    status = arrptr->head.nbr_of_items;
  239. ERROREXIT:
  240.    if(arrptr->fhandle != ERRORNEG)
  241.       _tr_close(arrptr->fhandle);
  242.    _xfree(arrptr->typetable);
  243.    _xfree(arrptr->lentable);
  244.    _xfree(arrptr->postable);
  245.    _xfree(arrptr->buffer);
  246.    return(status); 
  247. }
  248. /*-------------------------------------------------------------------------*/
  249.