home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 125.img / PRO-C4.ZIP / BENCH1.ZIP / BENCH / ICISAM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-28  |  22.8 KB  |  924 lines

  1. /* ==( io/src/icisam.c )== */
  2.  
  3. /* ----------------------------------------------- */
  4. /* Pro-C  Copyright (C) 1988 - 1990 Vestronix Inc. */
  5. /* Modification to this source is not supported    */
  6. /* by Vestronix Inc.                               */
  7. /*            All Rights Reserved                  */
  8. /* ----------------------------------------------- */
  9. /* Written   NA   24-Feb-88                        */
  10. /* Modified  VvA  28-Mar-90  See comments below    */
  11. /* ----------------------------------------------- */
  12. /* %W%  (%H% %T%) */
  13.  
  14. /*
  15.  *  Modifications
  16.  *
  17.  *  28-Mar-90  VvA - adjustments for locking modes, transactions
  18.  *  01-Feb-90  VvA - openmode enabled, some bug fixes
  19.  *  14-Dec-89  VvA - V.2 modifications
  20.  *  01-Aug-89  VvA - Modified for generic I/O interface
  21.  *  01-Sep-88  VvA - Numerical & segmented keys added
  22. */
  23.  
  24. /*  C-ISAM specific I/O calls via general IOGEN.C interface  */
  25.  
  26.  
  27. # include <stdio.h>
  28. # include <isam.h>
  29. # include <iodef.h>
  30. # include <iomsg.h>
  31. # include <proc.io>
  32. # include <bench.h>
  33. # include <iosup.h>
  34.  
  35.  
  36. #define  ENOFILE  2      /* C-ISAM */
  37.  
  38.  
  39. /* C-ISAM prototypes */
  40. #ifdef ANSI
  41. int        isstart(int, struct keydesc *, int, char *, int);
  42. int        isbuild(char *, int, struct keydesc *, int);
  43. int        iserase(char *);
  44. int        isopen(char *, int);
  45. int        isclose(int);
  46. int        isread(int, char *, int);
  47. int        iswrcurr(int, char *);
  48. int        isrewcurr(int, char *);
  49. int        isflush(int);
  50. int        isaddindex(int, struct keydesc *);
  51. int        isindexinfo(int, struct keydesc *, int);
  52. int        isdelcurr(int);
  53. int        isrelease(int);
  54. int        isbegin(void);
  55. int        isrollback(void);
  56. int        iscommit(void);
  57. int        islogopen(char *);
  58. int        islogclose(void);
  59. int        ldchar(char *, int, char *);
  60. int        stchar(char *, char *, int);
  61. int        stdbl(double, char *);
  62. int        stfloat(float, char *);
  63. int        stlong(long, char *);
  64. double     lddbl(char *);
  65. double     ldfloat(char *);
  66. long       ldlong(char *);
  67. #else
  68. int        isstart();
  69. int        isbuild();
  70. int        iserase();
  71. int        isopen();
  72. int        isclose();
  73. int        isread();
  74. int        iswrcurr();
  75. int        isrewcurr();
  76. int        isflush();
  77. int        isaddindex();
  78. int        isindexinfo();
  79. int        isdelcurr();
  80. int        isrelease();
  81. int        isbegin();
  82. int        isrollback();
  83. int        iscommit();
  84. int        islogopen();
  85. int        islogclose();
  86. int        ldchar();
  87. int        stchar();
  88. int        stdbl();
  89. int        stfloat();
  90. int        stlong();
  91. long       ldlong();
  92. double     lddbl();
  93. double     ldfloat();
  94. #endif
  95.  
  96.  
  97. /* Function prototypes */
  98. # ifdef ANSI
  99. static int i_addrec(int, char *);
  100. static int i_close_file(int, char *);
  101. static int i_commit(int, char *);
  102. static int i_delrec(int, char *);
  103. static int i_filename(int, char *);
  104. static int i_findkey(int, char *);
  105. static int i_firstkey(int, char *);
  106. static int i_init_file(int, char *);
  107. static int i_lastkey(int, char *);
  108. static int i_lockrec(int, char *);
  109. static int i_login(int, char *);
  110. static int i_logoff(int, char *);
  111. static int i_nextrec(int, char *);
  112. static int i_open_file(int, char *);
  113. static int i_prevrec(int, char *);
  114. static int i_rereadrec(int, char *);
  115. static int i_rollback(int, char *);
  116. static int i_selectinx(int, char *);
  117. static int i_transact(int, char *);
  118. static int i_unlock_rec(int, char *);
  119. static int i_updrec(int, char *);
  120. static int create_file(int);
  121. static int load_keys(int);
  122. static int io_xlate(int, int, char *);
  123. static int start_translog(void);
  124. static void buf2isam(int, char *, char *);
  125. static void isam2buf(int, char *, char *);
  126. static void close_translog(void);
  127. # else
  128. static int i_addrec();
  129. static int i_close_file();
  130. static int i_commit();
  131. static int i_delrec();
  132. static int i_filename();
  133. static int i_findkey();
  134. static int i_firstkey();
  135. static int i_init_file();
  136. static int i_lastkey();
  137. static int i_lockrec();
  138. static int i_login();
  139. static int i_logoff();
  140. static int i_nextrec();
  141. static int i_open_file();
  142. static int i_prevrec();
  143. static int i_rereadrec();
  144. static int i_rollback();
  145. static int i_selectinx();
  146. static int i_transact();
  147. static int i_unlock_rec();
  148. static int i_updrec();
  149. static int create_file();
  150. static int load_keys();
  151. static int io_xlate();
  152. static int start_translog();
  153. static void buf2isam();
  154. static void isam2buf();
  155. static void close_translog();
  156. # endif
  157.  
  158.  
  159. static int IS_OPENMODE;
  160. static int IS_LOCKMODE;
  161. static int IS_TRANSACT = 0;
  162. static int logisopen = FALSE;
  163. static struct keydesc fkey[MAX_FILES][MAX_KEYS];  /* keydescs for each file */
  164. static char storbuff[MAX_RECLEN];         /* for C-ISAM copy of data record */
  165.  
  166.  
  167. /*
  168.  *
  169.  * Interface Functions
  170.  *
  171. */
  172.  
  173.  
  174. /*
  175.  *  Sets up File Name extension.
  176. */
  177. static int i_filename(fd_sys, buffer)
  178. int fd_sys;
  179. char *buffer;
  180. {
  181.    for ( ; (*buffer != '.') && (*buffer != NULL); buffer++)
  182.       ;
  183.    *buffer = NULL;
  184.  
  185.    return(IOGOOD);
  186. }
  187.  
  188. /*
  189.  *  Initialize file
  190. */
  191. static int i_init_file(fd_sys, buffer)
  192. int fd_sys;
  193. char *buffer;
  194. {
  195.    return(IOGOOD);
  196. }
  197.  
  198.  
  199. /*
  200.  *  File open function
  201. */
  202. static int i_open_file(fd_sys, buffer)
  203. int fd_sys;
  204. char *buffer;
  205. {
  206.    int stat;
  207.    struct dictinfo ch;
  208.    struct fd_def *fptr = &fd[fd_sys];
  209.  
  210.    if (fptr->openmode & OUTPUT_FLAG)
  211.       iserase(fptr->filname);          /* for OUTPUT, delete existing files */
  212.  
  213.    if (fptr->openmode & UPDATE_FLAG)
  214.       IS_OPENMODE = ISINOUT;
  215.    else if (fptr->openmode & INPUT_FLAG)
  216.       IS_OPENMODE = ISINPUT;
  217.    else
  218.       IS_OPENMODE = ISOUTPUT;                    /* either OUTPUT or APPEND */
  219.  
  220.    if (fptr->openmode & P_TRANSACT)
  221.    {
  222.       IS_TRANSACT = ISTRANS;
  223.       if (start_translog())
  224.          return(IOERROR);
  225.    }
  226.  
  227.    if ((stat = isopen(fptr->filname, ISMANULOCK+IS_OPENMODE+IS_TRANSACT)) < SUCCESS)
  228.    {                                              /* try to create the file */
  229.       if (fptr->openmode & INPUT_FLAG)
  230.       {
  231.          stat = io_xlate(fd_sys, iserrno, "CISM OPEN1");
  232.          close_translog();
  233.          return(stat);
  234.       }
  235.  
  236.       if ((stat = create_file(fd_sys)) <= IOERROR)
  237.       {
  238.          close_translog();
  239.          return(IOERROR);
  240.       }
  241.    }
  242.    else                   /* at this point, the file is successfully opened */
  243.    {
  244.       isindexinfo(stat, &ch, 0);           /* stat contains file descriptor */
  245.  
  246.       if(ch.di_recsize != fptr->rec_len+1)   /* not same reclen as expected */
  247.       {
  248.          errmsg(FileRecLenChg_s, fptr->filname);
  249.          fptr->fd_num = stat;            /* ensure closing the correct file */
  250.          i_close_file(fd_sys, "");
  251.          return(IOERROR);
  252.       }
  253.  
  254.       load_keys(fd_sys);
  255.    }
  256.  
  257.    fptr->fd_num = stat;                       /* retain the file descriptor */
  258.    return(IOGOOD);
  259. }
  260.  
  261.  
  262. /*
  263.  *  Initialize and open C-ISAM transaction log file
  264.  *  - the file should be named <databasename>.log rather than "recovery"
  265.  *    when some form of overall database or project name is implemented
  266. */
  267. static int start_translog()
  268. {
  269.    if (logisopen)
  270.       return(TRUE);
  271.  
  272.    if (access("recovery.log", 00) < 0)
  273.    {
  274.       if (creat("recovery.log", S_IWRITE) == -1)
  275.       {
  276.          errmsg(FileTrnsLogCreate);
  277.          return(IOERROR);
  278.       }
  279.    }
  280.    if (islogopen("recovery.log") == -1)
  281.    {
  282.       errmsg(FileTrnsLogOpen);
  283.       return(IOERROR);
  284.    }
  285.    logisopen = TRUE;
  286.    return(IOGOOD);
  287. }
  288.  
  289.  
  290. /*
  291.  *  C-ISAM create file function
  292.  *  - file has to be created in exclusive mode to set up indexes; it is
  293.  *    then closed and reopened in shared mode; stat is file descriptor
  294. */
  295. static int create_file(fd_sys)
  296. int fd_sys;
  297. {
  298.    int stat, j, nkeys;
  299.    char fname[FILENAME_LEN];
  300.    struct fd_def *fptr = &fd[fd_sys];
  301.  
  302.    strcpy(fname, fptr->filname);
  303.    strcat(fname, ".dat");
  304.    if (access(fname, 00) == 0)       /* file already exists, do not clobber */
  305.    {                                  /* iserrno here will be from isopen() */
  306.       errmsg("Data file %s already exists", fptr->filname);
  307.       return(io_xlate(fd_sys, iserrno, "CISM OPEN2"));
  308.    }
  309.  
  310.    nkeys = load_keys(fd_sys);
  311.  
  312.    if (isbuild(fptr->filname, fptr->rec_len+1, &fkey[fd_sys][0], ISINOUT+ISEXCLLOCK+IS_TRANSACT) < SUCCESS)
  313.       return(io_xlate(fd_sys, iserrno, "CISM CRT1"));
  314.  
  315.    if ((stat = isopen(fptr->filname, ISINOUT+ISEXCLLOCK+IS_TRANSACT)) < SUCCESS)
  316.       return(io_xlate(fd_sys, iserrno, "CISM CRT2"));
  317.  
  318.    for (j = 1; j < nkeys; j++)                  /* create remaining indexes */
  319.       if (isaddindex(stat, &fkey[fd_sys][j]))
  320.          return(io_xlate(fd_sys, iserrno, "CISM IXCRT"));
  321.  
  322.    if (isclose(fptr->fd_num))
  323.       return(io_xlate(fd_sys, iserrno, "CISM CRT3"));
  324.  
  325.    if ((stat = isopen(fptr->filname, ISMANULOCK+IS_OPENMODE+IS_TRANSACT)) < SUCCESS)
  326.       return(io_xlate(fd_sys, iserrno, "CISM CRT4"));
  327.  
  328.    return(stat);
  329. }
  330.  
  331.  
  332. /*
  333.  *  C-ISAM key load function
  334.  *  - loads into C-ISAM key descriptor structure
  335. */
  336. static int load_keys(fd_sys)
  337. int fd_sys;
  338. {
  339.    int fx, m, n = 0;
  340.    struct fd_def *fptr = &fd[fd_sys];
  341.  
  342.    while (fptr->keys[n].segcount != -1)
  343.    {
  344.       for (m = 0; m < fptr->keys[n].segcount; m++)
  345.       {
  346.          fkey[fd_sys][n].k_part[m].kp_start = fptr->keys[n].segstart[m];
  347.          fkey[fd_sys][n].k_part[m].kp_leng  = fptr->keys[n].seglen[m];
  348.  
  349.          fx = fptr->keys[n].fldindex[m];
  350.          switch(fptr->flds[fx].fldtype)         /* data type of key segment */
  351.          {
  352.             case CHRTYP : 
  353.                fkey[fd_sys][n].k_part[m].kp_type  = CHARTYPE;
  354.                break;
  355.             case INTTYP : 
  356.                fkey[fd_sys][n].k_part[m].kp_leng = INTSIZE;
  357.                fkey[fd_sys][n].k_part[m].kp_type = INTTYPE;
  358.                break;
  359.             case LNGTYP : 
  360.                fkey[fd_sys][n].k_part[m].kp_leng = LONGSIZE;
  361.                fkey[fd_sys][n].k_part[m].kp_type = LONGTYPE;
  362.                break;
  363.             case FLTTYP : 
  364.                fkey[fd_sys][n].k_part[m].kp_type = FLOATTYPE;
  365.                fkey[fd_sys][n].k_part[m].kp_leng = FLOATSIZE;
  366.                break;
  367.             case DBLTYP : 
  368.                fkey[fd_sys][n].k_part[m].kp_type = DOUBLETYPE;
  369.                fkey[fd_sys][n].k_part[m].kp_leng = DOUBLESIZE;
  370.                break;
  371.             case DATTYP :
  372.                if (fptr->keys[n].seglen[m] == 6)
  373.                   fkey[fd_sys][n].k_part[m].kp_type  = CHARTYPE;
  374.                else
  375.                {
  376.                   fkey[fd_sys][n].k_part[m].kp_leng = LONGSIZE;
  377.                   fkey[fd_sys][n].k_part[m].kp_type = LONGTYPE;
  378.                }
  379.                break;
  380.          }
  381.       }
  382.       fkey[fd_sys][n].k_nparts = m;           /* segment count for this key */
  383.  
  384.       if (fptr->keys[n].keytype == KEY_DUPLICATE)
  385.          fkey[fd_sys][n].k_flags = ISDUPS;
  386.       else
  387.          fkey[fd_sys][n].k_flags = ISNODUPS;
  388.  
  389.       n++;                                     /* increment total key count */
  390.    }
  391.    return(n);
  392. }
  393.  
  394.  
  395. /*
  396.  *  File close function
  397. */
  398. static int i_close_file(fd_sys, buffer)
  399. int fd_sys;
  400. char *buffer;
  401. {
  402.    int stat;
  403.    struct fd_def *fptr = &fd[fd_sys];
  404.  
  405.    if (stat = isclose(fptr->fd_num))
  406.       return(io_xlate(fd_sys, iserrno, "CISM CLOSE"));
  407.  
  408.    fptr->active = NO;
  409.    close_translog();
  410.    return(IOGOOD);
  411. }
  412.  
  413.  
  414. /*
  415.  *  Close recovery.log file, if used
  416. */
  417. static void close_translog()
  418. {
  419.    int n;
  420.  
  421.    if (logisopen)
  422.    {
  423.       for (n = 0; n < MAX_FILES; n++)              /* all files closed yet? */
  424.          if (fd[n].active)
  425.             return;
  426.  
  427.       islogclose();
  428.       logisopen = FALSE;
  429.    }
  430. }
  431.  
  432.  
  433. /*
  434.  *  Select an index to perform processing on - already done in IOGEN.C
  435.  *  - also sets C-ISAM's own lock modes for subsequent read
  436. */
  437. static int i_selectinx(fd_sys, buffer)
  438. int fd_sys;
  439. char *buffer;
  440. {
  441.    if (fd[fd_sys].lockmode == NOLOCK)
  442.       IS_LOCKMODE = NOLOCK;
  443.    else
  444.       IS_LOCKMODE = ISLOCK;                       /* C-ISAM's own lock flag */
  445.    return(IOGOOD);
  446. }
  447.  
  448. /*
  449.  *  Find a record by key value
  450. */
  451. static int i_findkey(fd_sys, buffer)
  452. int fd_sys;
  453. char *buffer;
  454. {
  455.    int stat, ck, IS_MD;
  456.    struct fd_def *fptr = &fd[fd_sys];
  457.     
  458.    buf2isam(fd_sys, buffer, storbuff);
  459.    ck = fptr->cur_key;
  460.    IS_MD = (fptr->exact ? ISEQUAL : ISGTEQ);
  461.  
  462.    if((stat = isstart(fptr->fd_num, &fkey[fd_sys][ck], 0, storbuff, IS_MD)) < SUCCESS)
  463.       return(io_xlate(fd_sys, iserrno, "CISM FIND 1"));
  464.  
  465.    if((stat = isread(fptr->fd_num, storbuff, IS_MD + IS_LOCKMODE)) < SUCCESS)
  466.       return(io_xlate(fd_sys, iserrno, "CISM FIND 2"));
  467.  
  468.    isam2buf(fd_sys, buffer, storbuff);
  469.    return(IOGOOD);
  470. }
  471.  
  472. /*
  473.  *  Find first record in the file
  474. */
  475. static int i_firstkey(fd_sys, buffer)
  476. int fd_sys;
  477. char *buffer;
  478. {
  479.    int stat, ck;
  480.    struct fd_def *fptr = &fd[fd_sys];
  481.  
  482.    ck = fptr->cur_key;
  483.  
  484.    if((stat = isstart(fptr->fd_num, &fkey[fd_sys][ck], 0, storbuff, ISFIRST)) < SUCCESS)
  485.       return(io_xlate(fd_sys, iserrno, "CISM FRST 1"));
  486.  
  487.    if ((stat = isread(fptr->fd_num, storbuff, ISNEXT + IS_LOCKMODE)) < SUCCESS)
  488.       return(io_xlate(fd_sys, iserrno, "CISM FRST 2"));
  489.  
  490.    isam2buf(fd_sys, buffer, storbuff); 
  491.    return(IOGOOD);
  492. }
  493.  
  494. /*
  495.  *  Find last physical record in the file
  496. */
  497. static int i_lastkey(fd_sys, buffer)
  498. int fd_sys;
  499. char *buffer;
  500. {
  501.    int stat, ck;
  502.    struct fd_def *fptr = &fd[fd_sys];
  503.  
  504.    ck = fd[fd_sys].cur_key;
  505.  
  506.    if((stat = isstart(fptr->fd_num, &fkey[fd_sys][ck], 0, storbuff, ISLAST)) < SUCCESS)
  507.       return((iserrno == EENDFILE) ? IOEOF : io_xlate(fd_sys, iserrno, "CISM LAST 1"));
  508.  
  509.    if((stat = isread(fptr->fd_num, storbuff, ISPREV + IS_LOCKMODE)) < SUCCESS)
  510.       return((iserrno == EENDFILE) ? IOEOF : io_xlate(fd_sys, iserrno, "CISM LAST 2"));
  511.  
  512.    isam2buf(fd_sys, buffer, storbuff);
  513.    return(IOGOOD);
  514. }
  515.  
  516. /*
  517.  *  Find next record in the file
  518. */
  519. static int i_nextrec(fd_sys, buffer)
  520. int fd_sys;
  521. char *buffer;
  522. {
  523.    int stat;
  524.    struct fd_def *fptr = &fd[fd_sys];
  525.  
  526.    buf2isam(fd_sys, buffer, storbuff);
  527.  
  528.    if ((stat = isread(fptr->fd_num, storbuff, ISNEXT + IS_LOCKMODE)) < SUCCESS)
  529.       return((iserrno == EENDFILE) ? IOEOF : io_xlate(fd_sys, iserrno, "CISM NEXT"));
  530.  
  531.    isam2buf(fd_sys, buffer, storbuff);
  532.    return(IOGOOD);
  533. }
  534.  
  535. /*
  536.  *  Find previous record in the file
  537. */
  538. static int i_prevrec(fd_sys, buffer)
  539. int fd_sys;
  540. char *buffer;
  541. {
  542.    int stat;
  543.    struct fd_def *fptr = &fd[fd_sys];
  544.  
  545.    buf2isam(fd_sys, buffer, storbuff);
  546.  
  547.    if ((stat = isread(fptr->fd_num, storbuff, ISPREV + IS_LOCKMODE)) < SUCCESS)
  548.       return((iserrno == EENDFILE) ? IOTOF : io_xlate(fd_sys, iserrno, "CISM PREV"));
  549.  
  550.    isam2buf(fd_sys, buffer, storbuff);
  551.    return(IOGOOD);
  552. }
  553.  
  554. /*
  555.  *  Re-read/reposition record pointer function - if required
  556. */
  557. static int i_rereadrec(fd_sys, buffer)
  558. int fd_sys;
  559. char *buffer;
  560. {
  561.    return(i_findkey(fd_sys, buffer));
  562. }
  563.  
  564.  
  565. /*
  566.  *  Add a new record.
  567. */
  568. static int i_addrec(fd_sys, buffer)
  569. int fd_sys;
  570. char *buffer;
  571. {
  572.    int stat;
  573.    struct fd_def *fptr = &fd[fd_sys];
  574.  
  575.    buf2isam(fd_sys, buffer, storbuff);    /* NEW */
  576.  
  577.    if ((stat = iswrcurr(fptr->fd_num, storbuff)) < SUCCESS)
  578.       return(io_xlate(fd_sys, iserrno, "CISM ADD"));
  579.  
  580.    isflush(fptr->fd_num);
  581.    return(IOGOOD);
  582. }
  583.  
  584. /*
  585.  *  Update the current record.
  586. */
  587. static int i_updrec(fd_sys, buffer)
  588. int fd_sys;
  589. char *buffer;
  590. {
  591.    int stat;
  592.    struct fd_def *fptr = &fd[fd_sys];
  593.  
  594.    buf2isam(fd_sys, buffer, storbuff);
  595.  
  596.    if ((stat = isrewcurr(fptr->fd_num, storbuff)) < SUCCESS)
  597.       return(io_xlate(fd_sys, iserrno, "CISM UPD"));
  598.  
  599.    isflush(fptr->fd_num);
  600.    return(IOGOOD);
  601. }
  602.  
  603. /*
  604.  *  Delete the current record.
  605. */
  606. static int i_delrec(fd_sys, buffer)
  607. int fd_sys;
  608. char *buffer;
  609. {
  610.    int stat;
  611.  
  612.    if (stat = isdelcurr(fd[fd_sys].fd_num))
  613.       return io_xlate(fd_sys, iserrno, "CISM DEL");
  614.  
  615.    return(IOGOOD);
  616. }
  617.  
  618. /*
  619.  *  Lock Record - rereads current record into storbuff to lock
  620.  *  - to preserve edits, storbuff is NOT converted to PRO-C buffer
  621. */  
  622. static int i_lockrec(fd_sys, buffer)
  623. int fd_sys;
  624. char *buffer;
  625. {
  626.    int stat;
  627.    struct fd_def *fptr = &fd[fd_sys];
  628.  
  629.    if ((stat = isread(fptr->fd_num, storbuff, ISCURR + IS_LOCKMODE)) < SUCCESS)
  630.    {
  631.       if (iserrno == EENDFILE)             /* bypass retry count if EOF/TOF */
  632.          return(IOGOOD);
  633.       return(io_xlate(fd_sys, iserrno, "CISM LOCK"));
  634.    }
  635.  
  636.    return(IOGOOD);
  637. }
  638.  
  639. /*
  640.  *  Unlock Record
  641. */
  642. static int i_unlock_rec(fd_sys, buffer)
  643. int fd_sys;
  644. char *buffer;
  645. {
  646.    int stat;
  647.  
  648.    if (stat = isrelease(fd[fd_sys].fd_num))
  649.       return(io_xlate(fd_sys, iserrno, "CISM ULCK"));
  650.  
  651.    return(IOGOOD);
  652. }
  653.  
  654. /*
  655.  *  Login
  656. */
  657. static int i_login(fd_sys, buffer)
  658. int fd_sys;
  659. char *buffer;
  660. {
  661.    return(IOGOOD);
  662. }
  663.  
  664. /*
  665.  *  Logoff
  666. */
  667. static int i_logoff(fd_sys, buffer)
  668. int fd_sys;
  669. char *buffer;
  670. {
  671.    return(IOGOOD);
  672. }
  673.  
  674. /*
  675.  *  End (Commit) transaction - releases any outstanding locks
  676. */
  677. static int i_commit(fd_sys, buffer)
  678. int fd_sys;
  679. char *buffer;
  680. {
  681.    int stat;
  682.  
  683.    if (!IS_TRANSACT)
  684.       return(IOGOOD);
  685.  
  686.    if (stat = iscommit())
  687.    {
  688.       errmsg(FileTrnsCommit);
  689.       return(io_xlate(fd_sys, iserrno, "CISM ETRN"));
  690.    }
  691.    return(IOGOOD);
  692. }
  693.  
  694. /*
  695.  *  Rollback transaction
  696. */
  697. static int i_rollback(fd_sys, buffer)
  698. int fd_sys;
  699. char *buffer;
  700. {
  701.    int stat;
  702.  
  703.    if (!IS_TRANSACT)
  704.       return(IOGOOD);
  705.  
  706.    if (stat = isrollback())
  707.    {
  708.       errmsg(FileTrnsRlback);
  709.       return(io_xlate(fd_sys, iserrno, "CISM ATRN"));
  710.    }
  711.    return(IOGOOD);
  712. }
  713.  
  714. /*
  715.  *  Start transaction
  716. */
  717. static int i_transact(fd_sys, buffer)
  718. int fd_sys;
  719. char *buffer;
  720. {
  721.    int stat;
  722.  
  723.    if (!IS_TRANSACT)
  724.       return(IOGOOD);
  725.  
  726.    if (stat = isbegin())
  727.    {
  728.       errmsg(FileTrnsBegin);
  729.       return(io_xlate(fd_sys, iserrno, "CISM BTRN"));
  730.    }
  731.    return(IOGOOD);
  732. }
  733.  
  734.  
  735. /*
  736.  *  Convert record to C-ISAM form from PRO-C buffer format before storing
  737. */
  738. static void buf2isam(fd_sys, P_buff, CI_buff)
  739. int fd_sys;
  740. char *P_buff, *CI_buff;
  741. {
  742.    int itmp;
  743.    long ltmp;
  744.    float ftmp;
  745.    double dtmp;
  746.    int x = 0, foff, flen;
  747.    struct fd_def *fptr = &fd[fd_sys];
  748.  
  749.    zerorec(CI_buff, fptr->rec_len+1);
  750.  
  751.    while (fptr->flds[x].fldname)          /* NULL fieldname terminates list */
  752.    {
  753.       foff = fptr->flds[x].fldstart;
  754.       flen = fptr->flds[x].fldlen;
  755.       switch(fptr->flds[x].fldtype)
  756.       {
  757.          case DATTYP :
  758.             if (flen == 6)
  759.                stchar(&P_buff[foff], &CI_buff[foff], flen);
  760.             else
  761.             {
  762.                bytecpy(<mp, &P_buff[foff], flen);
  763.                stlong(ltmp, &CI_buff[foff]);
  764.             }
  765.             break;
  766.          case LOGTYP :
  767.          case MEMTYP :
  768.          case CHRTYP :
  769.             stchar(&P_buff[foff], &CI_buff[foff], flen); 
  770.             break;
  771.          case INTTYP :
  772.             bytecpy(&itmp, &P_buff[foff], flen); 
  773.             stint(itmp, &CI_buff[foff]);
  774.             break;
  775.          case LNGTYP :
  776.             bytecpy(<mp, &P_buff[foff], flen);
  777.             stlong(ltmp, &CI_buff[foff]);
  778.             break;
  779.          case FLTTYP :
  780.             bytecpy(&ftmp, &P_buff[foff], flen);
  781. /*          stfloat(ftmp, &CI_buff[foff]);     (C-ISAM bug)  */
  782.             break;
  783.          case DBLTYP :
  784.             bytecpy(&dtmp, &P_buff[foff], flen);
  785.             stdbl(dtmp, &CI_buff[foff]);
  786.             break;
  787.       }
  788.       x++;
  789.    }
  790. }
  791.  
  792. /*
  793.  *  Convert record to PRO-C buffer format from C-ISAM form before returning
  794. */
  795. static void isam2buf(fd_sys, P_buff, CI_buff)
  796. int fd_sys;
  797. char *P_buff, *CI_buff;
  798. {
  799.    int itmp;
  800.    long ltmp;
  801.    float ftmp;
  802.    double dtmp;
  803.    int x = 0, foff, flen;
  804.    char tbuff[MAX_FLDLEN];        /* dummy buffer for char field extraction */
  805.    struct fd_def *fptr = &fd[fd_sys];
  806.  
  807.    zerorec(P_buff, fptr->rec_len);
  808.  
  809.    while (fptr->flds[x].fldname)          /* NULL fieldname terminates list */
  810.    {
  811.       foff = fptr->flds[x].fldstart;
  812.       flen = fptr->flds[x].fldlen;
  813.       switch(fptr->flds[x].fldtype)
  814.       {
  815.          case DATTYP :
  816.             if (flen == 6)
  817.             {
  818.                ldchar(&CI_buff[foff], flen, tbuff);
  819.                bytecpy(&P_buff[foff], tbuff, flen);
  820.             }
  821.             else
  822.             {
  823.                ltmp = ldlong(&CI_buff[foff]);
  824.                bytecpy(&P_buff[foff], <mp, flen);
  825.             }
  826.             break;
  827.          case LOGTYP :
  828.          case MEMTYP :
  829.          case CHRTYP :
  830.             ldchar(&CI_buff[foff], flen, tbuff);
  831.             bytecpy(&P_buff[foff], tbuff, flen);
  832.             break;
  833.          case INTTYP :
  834.             itmp = ldint(&CI_buff[foff]);
  835.             bytecpy(&P_buff[foff], &itmp, flen);
  836.             break;
  837.          case LNGTYP :
  838.             ltmp = ldlong(&CI_buff[foff]);
  839.             bytecpy(&P_buff[foff], <mp, flen);
  840.             break;
  841.          case FLTTYP :
  842. /*          dtmp = ldfloat(&CI_buff[foff]);   (C-ISAM bug!) */
  843.             ftmp = 0;   /*  for now ... (float)dtmp;  */
  844.             bytecpy(&P_buff[foff], &ftmp, flen);
  845.             break;
  846.          case DBLTYP :
  847.             dtmp = lddbl(&CI_buff[foff]);
  848.             bytecpy(&P_buff[foff], &dtmp, flen);
  849.             break;
  850.       }
  851.       x++;
  852.    }
  853. }
  854.  
  855.  
  856. /*
  857.  *  This routine translates C-ISAM Error codes into PRO-C error codes.
  858.  *  If no PRO-C equivalent, displays the error number.
  859. */
  860. static int io_xlate(fd_sys, ernum, rtnname)
  861. int fd_sys;
  862. int ernum;
  863. char *rtnname;
  864. {
  865.    switch(ernum)
  866.    {
  867.       case  EDUPL      :
  868.          return(IODUP);
  869.       case  ENOTOPEN   :
  870.          return(IOBADOPEN);
  871.       case  ENOFILE    :
  872.          return(IONOFILE);
  873.       case  EENDFILE   :   
  874.       case  ENOREC     :   
  875.       case  ENOCURR    :
  876.          return(IONOKEY);
  877.       case  ELOCKED    :
  878.       case  EFLOCKED   :
  879.          return(IOLOCKED);
  880.       case  ELOGWRIT   :
  881.       case  ENOTRANS   :
  882.       case  ENOBEGIN   :
  883.          return(IONOTRANS);
  884.    }
  885.  
  886.    if (fd_sys >= 0)
  887.       errmsg(FileDbgError_sdss, "C-ISAM", ernum, fd[fd_sys].filname, rtnname);
  888.    else      /* if routines called from generated apps without valid fd_sys */
  889.       errmsg(FileDbgError_sds, "C-ISAM", ernum, rtnname);
  890.    return(IOERROR);
  891. }
  892.  
  893.  
  894. /*
  895.  * Assign section
  896. */
  897.  
  898. void assign_IO_CI(dbnum)
  899. int dbnum;
  900. {
  901.    Fntab[dbnum - 1][0]  = (int(*)())0; /* Empty */
  902.    Fntab[dbnum - 1][1]  = i_init_file;
  903.    Fntab[dbnum - 1][2]  = i_open_file;
  904.    Fntab[dbnum - 1][3]  = i_close_file;
  905.    Fntab[dbnum - 1][4]  = i_addrec;
  906.    Fntab[dbnum - 1][5]  = i_delrec;
  907.    Fntab[dbnum - 1][6]  = i_findkey;
  908.    Fntab[dbnum - 1][7]  = i_firstkey;
  909.    Fntab[dbnum - 1][8]  = i_lastkey;
  910.    Fntab[dbnum - 1][9]  = i_lockrec;
  911.    Fntab[dbnum - 1][10] = i_nextrec;
  912.    Fntab[dbnum - 1][11] = i_prevrec;
  913.    Fntab[dbnum - 1][12] = i_unlock_rec;
  914.    Fntab[dbnum - 1][13] = i_updrec;
  915.    Fntab[dbnum - 1][14] = i_commit;
  916.    Fntab[dbnum - 1][15] = i_login;
  917.    Fntab[dbnum - 1][16] = i_logoff;
  918.    Fntab[dbnum - 1][17] = i_rollback;
  919.    Fntab[dbnum - 1][18] = i_transact;
  920.    Fntab[dbnum - 1][19] = i_selectinx;
  921.    Fntab[dbnum - 1][20] = i_rereadrec;
  922.    Fntab[dbnum - 1][21] = i_filename;
  923. }
  924.