int idxread (unit *ftnunit) { register int i; register char *keyval, *field; int newkeyid = 0, mode = ftnunit->f77idxlist.cimatch; keys = ftnunit->ukeys; ftnunit->f77recend = i = ftnunit->url; if (ftnunit->url > ftnunit->f77fio_size) check_buflen (ftnunit, ftnunit->url); while (i-- > 0) ftnunit->f77fio_buf[i] = '\0'; if (ftnunit->f77idxlist.cikeyid >= 0 && ftnunit->ukeyid != ftnunit->f77idxlist.cikeyid) { ftnunit->ukeyid = ftnunit->f77idxlist.cikeyid; newkeyid = 1; } /* 8/23/89 fix bug 4847 */ else if (ftnunit->ukeyid < 0) { ftnunit->ukeyid = ftnunit->f77idxlist.cikeyid >= 0 ? ftnunit->f77idxlist.cikeyid : 0; newkeyid = 1; } if (mode) { field = ftnunit->f77fio_buf + KEYOFF (ftnunit->ukeyid); if (KEYTYPE (ftnunit->ukeyid) != ftnunit->f77idxlist.cikeytype) err (ftnunit->f77errlist.cierr, 154, "indexed read"); if (KEYTYPE (ftnunit->ukeyid) == CHARTYPE) { keyval = ftnunit->f77idxlist.cikeyval.cicharval; /* fix bug 4779 */ if ((i = ftnunit->f77idxlist.cikeyvallen) > KEYLEN (ftnunit->ukeyid)) err (ftnunit->f77errlist.cierr, 155, "indexed read"); /* For Fortran, there's no such thing as null terminators for the string values, so use the string len value only while (*keyval && i-- > 0) *field++ = *keyval++; while (i-- > 0) *field++ = ' '; */ while (i-- > 0) *field++ = *keyval++; } else stlong (ftnunit->f77idxlist.cikeyval.ciintval, field); } else /* If the last read operation was locked try readign the same record again mode = (newkeyid ? ISFIRST : ISNEXT); */ mode = (newkeyid ? ISFIRST : ftnunit->uerror == F_ERLOCKED ? ISCURR : ISNEXT); ftnunit->uerror = 0; /* clear error for new operation */ if (newkeyid) { dokey (ftnunit->ukeyid, ONEKEY); if (isstart (ftnunit->isfd, &onekey, ftnunit->url, ftnunit->f77fio_buf, mode) < SUCCESS) ierr (ftnunit->f77errlist.cierr, iserrno, "indexed read"); } if (isread (ftnunit->isfd, ftnunit->f77fio_buf, mode) < SUCCESS) if (iserrno == EENDFILE) { ftnunit->uend = 1; err (ftnunit->f77errlist.ciend, EOF, "indexed read"); } else ierr (ftnunit->f77errlist.cierr, iserrno, "indexed read"); /* When the read is successful, make sure the EOF flag is not set */ ftnunit->uend = 0; return SUCCESS; }
/* // // ISAM - START function // */ int tcob_start_idx(struct file_desc *f, int cond, int ikey, struct fld_desc *recfdesc, char *key_ptr) { int iresult, cmode, startpos, poslen, r=0; tcb_fileio_vbidx_handle *h; tcob_file_key *k; char *crecord; struct keydesc *wkeydesc; f->flags.eof_hit = 0; /* additon AL : reset eof if already positioned */ f->flags.read_done = 0; f->flags.start_record = 0; #ifdef DEBUG_FILEISAM_RTS4 fprintf(stderr, "debug : tcob_start_idx 110.040 :\n"); #endif /* ERROR check : File is open */ if (f->dbp == NULL) RETURN_STATUS(47); /* ERROR check : Record length is valid - unknown error */ if (f->reclen == -1) RETURN_STATUS(99); /* ERROR check : Must be in INPUT or IO mode */ if ((f->open_mode != TCB_FILE_OPEN_MODE_INPUT) && (f->open_mode != TCB_FILE_OPEN_MODE_IO)) RETURN_STATUS(47); /* Special case for LT and LTEQ conditionals */ if ((cond == TCB_CONDITIONAL_LT) || (cond == TCB_CONDITIONAL_LTEQ)) { r = tcob_start_lesscond_idx(f, cond, ikey, recfdesc, key_ptr); RETURN_STATUS(r); } h = (tcb_fileio_vbidx_handle *)f->dbp; k = f->keys + ikey; crecord = h->buf->buf[0]; startpos = k->offset; poslen = recfdesc->len; memset (crecord, ' ', f->reclen); memcpy (crecord+startpos, key_ptr, poslen); switch (cond) { case TCB_CONDITIONAL_EQUAL: cmode = ISEQUAL; break; case TCB_CONDITIONAL_GT: cmode = ISGREAT; break; case TCB_CONDITIONAL_GTEQ: cmode = ISGTEQ; break; default: RETURN_STATUS(99); break; } wkeydesc = h->skeydesc + ikey; iresult = isstart(h->ifilehandle, wkeydesc, poslen, crecord, cmode); if (iresult != 0) { r = tcob_eisam2ecob(0); RETURN_STATUS(r); } f->flags.start_record = 1; RETURN_STATUS(r); }
/* // // ISAM - Emulate START function for LT and LTEQ conditionals // Use the inverse start condition and the work backwards // */ int tcob_start_lesscond_idx(struct file_desc *f, int cond, int ikey, struct fld_desc *recfdesc, char *key_ptr) { int iresult, sresult, cmode, startpos, poslen, searchflag, r=0; tcb_fileio_vbidx_handle *h; tcob_file_key *k; char *crecord; struct keydesc *wkeydesc; #ifdef DEBUG_FILEISAM_RTS5 fprintf(stderr, "debug : tcob_start_lesscond_idx 120.020 : \n"); #endif h = (tcb_fileio_vbidx_handle *)f->dbp; k = f->keys + ikey; crecord = h->buf->buf[0]; startpos = k->offset; poslen = recfdesc->len; memset (crecord, ' ', f->reclen); memcpy (crecord+startpos, key_ptr, poslen); /* Process LTEQ conditional */ if (cond == TCB_CONDITIONAL_LTEQ) cmode = ISGREAT; /* Process LT conditional */ else cmode = ISGTEQ; /* Set the initial lower boundary */ wkeydesc = h->skeydesc + ikey; iresult = isstart(h->ifilehandle, wkeydesc, poslen, crecord, cmode); if (iresult != 0) { cmode = ISLAST; iresult = isstart(h->ifilehandle, wkeydesc, poslen, crecord, cmode); if (iresult != 0) return (23); } #ifdef DEBUG_FILEISAM_RTS5 { int i, ilen=poslen; char *pt; fprintf(stderr, "debug : tcob_start_lesscond_idx 120.060 : keyidx=%d, rec=", ikey); pt=crecord+startpos; for (i=0; i<ilen; i++) { fprintf(stderr, "%c", pt[i]); } fprintf(stderr, "; key="); pt=key_ptr; for (i=0; i<ilen; i++) { fprintf(stderr, "%c", pt[i]); } fprintf(stderr, ";\n"); } #endif /* Read previous record to set new lower boundary */ //iresult = isread(h->ifilehandle, crecord, ISPREV); iresult = isread(h->ifilehandle, crecord, ISCURR); if (iresult != 0) return (23); /* Compare keys to check conditional */ /* Loop and check for boundary condition */ searchflag = 0; while (searchflag == 0) { #ifdef DEBUG_FILEISAM_RTS5 { int i, ilen=poslen; char *pt; fprintf(stderr, "debug : tcob_start_lesscond_idx 120.100 : keyidx=%d, rec=", ikey); pt=crecord+startpos; for (i=0; i<ilen; i++) { fprintf(stderr, "%c", pt[i]); } fprintf(stderr, "; key="); pt=key_ptr; for (i=0; i<ilen; i++) { fprintf(stderr, "%c", pt[i]); } fprintf(stderr, ";\n"); } #endif /* Compare keys to check conditional */ sresult = strncmp(crecord+startpos, key_ptr, poslen); #ifdef DEBUG_FILEISAM_RTS5 fprintf(stderr, "debug : tcob_start_lesscond_idx 120.140 : sresult=%d\n", sresult); #endif if (( (sresult < 0) && (cond == TCB_CONDITIONAL_LT)) || ( (!(sresult > 0)) && (cond == TCB_CONDITIONAL_LTEQ)) ) { searchflag = 1; break; } /* Read previous record to set new lower boundary */ iresult = isread(h->ifilehandle, crecord, ISPREV); if (iresult != 0) return (23); } f->flags.start_record = 1; #ifdef DEBUG_FILEISAM_RTS5 fprintf(stderr, "debug : tcob_start_lesscond_idx 120.190 : r=%d\n", r); #endif return r; }
/* // // ISAM read // */ int tcob_read_idx(struct file_desc *f, struct fld_desc *rectofrom_desc, char *rectofrom_buf, struct fld_desc *reclen_desc, char *reclen_buf, int ikey, struct fld_desc *fkey, char *keybuf) { int iresult, r=0, reclen; tcb_fileio_vbidx_handle *h; tcob_file_key *k; char *crecord; struct keydesc *wkeydesc; #ifdef DEBUG_FILEISAM_RTS1 fprintf(stderr, "debug : tcob_read_idx 070.020 : filename=%s, reclen=%d;\n", f->filename, f->reclen); #endif f->flags.read_done = 0; f->flags.start_record = 0; /* ERROR check : File is open */ if (f->dbp == NULL) { /* ERROR check : Set file-status condition when file is not available */ if (f->flags.optional && f->flags.file_missing) RETURN_STATUS(10); RETURN_STATUS(47); } /* ERROR check : Record length is valid - unknown error */ if (f->reclen == -1) RETURN_STATUS(99); /* ERROR check : Must in INPUT or IO mode */ if (((f->open_mode != TCB_FILE_OPEN_MODE_INPUT) && (f->open_mode != TCB_FILE_OPEN_MODE_IO))) RETURN_STATUS(47); /* Check that we didn't already hit eof */ if ((f->open_mode == TCB_FILE_OPEN_MODE_INPUT || f->open_mode == TCB_FILE_OPEN_MODE_IO) && f->flags.eof_hit) RETURN_STATUS(46); /* ERROR check : For random key READ access mode must be RANDOM or DYNAMIC */ if ((f->access_mode != TCB_FILE_ACCESS_MODE_RANDOM) && (f->access_mode != TCB_FILE_ACCESS_MODE_DYNAMIC) ) RETURN_STATUS(39); /* ERROR check : Key is required - unknown compiler error */ if (fkey == NULL) RETURN_STATUS(99); /* ERROR check : Key index is within bounds */ if ((f->nkeys <= ikey) || (0 > ikey)) RETURN_STATUS(99); h = (tcb_fileio_vbidx_handle *)f->dbp; k = f->keys; crecord = h->buf->buf[0]; /* Read with key */ memset (crecord, ' ', f->reclen); k = f->keys + ikey; memcpy (crecord+k->offset, keybuf, fkey->len); wkeydesc = h->skeydesc + ikey; iresult = isstart(h->ifilehandle, wkeydesc, f->reclen, crecord, ISEQUAL); if (iresult != 0) { r = tcob_eisam2ecob(0); RETURN_STATUS(r); } iresult = isread(h->ifilehandle, crecord, ISCURR); if (iresult != 0) { r = tcob_eisam2ecob(0); RETURN_STATUS(r); } /* Variable Length File */ if (reclen_desc != NULL) { reclen = isreclen; if (reclen > f->reclen) RETURN_STATUS(99); /* Set record length buffer for variable length file */ tcob_move(&_generic_4binary, (char *)&reclen, reclen_desc, reclen_buf); } else { reclen = f->reclen; } /* Clear buffer and move data record */ memset(f->record, ' ', f->reclen); memcpy (f->record, crecord, reclen); /* Copy buffer data to INTO identifiers buffer */ if (rectofrom_desc != NULL) { memset(rectofrom_buf, ' ', rectofrom_desc->len); if (rectofrom_desc->len > reclen) memcpy(rectofrom_buf, crecord, reclen); else memcpy(rectofrom_buf, crecord, rectofrom_desc->len); } f->flags.read_done = 1; #ifdef DEBUG_FILEISAM_RTS1 fprintf(stderr, "debug : tcob_read_idx 070.140 : r=%d;\n", r); #endif RETURN_STATUS(r); }