[BACK]Return to rec_get.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / db / recno

Annotation of src/lib/libc/db/recno/rec_get.c, Revision 1.18

1.18    ! christos    1: /*     $NetBSD: rec_get.c,v 1.17 2013/12/14 18:04:56 christos Exp $    */
1.7       cgd         2:
1.1       cgd         3: /*-
1.6       cgd         4:  * Copyright (c) 1990, 1993, 1994
1.1       cgd         5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
1.12      agc        15:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        16:  *    may be used to endorse or promote products derived from this software
                     17:  *    without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  */
                     31:
1.16      joerg      32: #if HAVE_NBTOOL_CONFIG_H
                     33: #include "nbtool_config.h"
                     34: #endif
                     35:
1.9       christos   36: #include <sys/cdefs.h>
1.18    ! christos   37: __RCSID("$NetBSD: rec_get.c,v 1.17 2013/12/14 18:04:56 christos Exp $");
1.1       cgd        38:
1.10      jtc        39: #include "namespace.h"
1.1       cgd        40: #include <sys/types.h>
                     41:
1.13      christos   42: #include <assert.h>
1.1       cgd        43: #include <errno.h>
                     44: #include <stddef.h>
                     45: #include <stdio.h>
                     46: #include <stdlib.h>
                     47: #include <string.h>
                     48: #include <unistd.h>
                     49:
                     50: #include <db.h>
                     51: #include "recno.h"
                     52:
                     53: /*
                     54:  * __REC_GET -- Get a record from the btree.
                     55:  *
                     56:  * Parameters:
                     57:  *     dbp:    pointer to access method
                     58:  *     key:    key to find
                     59:  *     data:   data to return
                     60:  *     flag:   currently unused
                     61:  *
                     62:  * Returns:
                     63:  *     RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
                     64:  */
                     65: int
1.13      christos   66: __rec_get(const DB *dbp, const DBT *key, DBT *data, u_int flags)
1.1       cgd        67: {
                     68:        BTREE *t;
                     69:        EPG *e;
                     70:        recno_t nrec;
                     71:        int status;
                     72:
1.4       cgd        73:        t = dbp->internal;
                     74:
                     75:        /* Toss any page pinned across calls. */
                     76:        if (t->bt_pinned != NULL) {
                     77:                mpool_put(t->bt_mp, t->bt_pinned, 0);
                     78:                t->bt_pinned = NULL;
                     79:        }
                     80:
                     81:        /* Get currently doesn't take any flags, and keys of 0 are illegal. */
1.1       cgd        82:        if (flags || (nrec = *(recno_t *)key->data) == 0) {
                     83:                errno = EINVAL;
                     84:                return (RET_ERROR);
                     85:        }
                     86:
                     87:        /*
                     88:         * If we haven't seen this record yet, try to find it in the
                     89:         * original file.
                     90:         */
                     91:        if (nrec > t->bt_nrecs) {
1.8       cgd        92:                if (F_ISSET(t, R_EOF | R_INMEM))
1.1       cgd        93:                        return (RET_SPECIAL);
                     94:                if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
                     95:                        return (status);
                     96:        }
                     97:
                     98:        --nrec;
                     99:        if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
                    100:                return (RET_ERROR);
                    101:
                    102:        status = __rec_ret(t, e, 0, NULL, data);
1.8       cgd       103:        if (F_ISSET(t, B_DB_LOCK))
1.4       cgd       104:                mpool_put(t->bt_mp, e->page, 0);
                    105:        else
                    106:                t->bt_pinned = e->page;
1.1       cgd       107:        return (status);
                    108: }
                    109:
                    110: /*
                    111:  * __REC_FPIPE -- Get fixed length records from a pipe.
                    112:  *
                    113:  * Parameters:
                    114:  *     t:      tree
                    115:  *     cnt:    records to read
                    116:  *
                    117:  * Returns:
                    118:  *     RET_ERROR, RET_SUCCESS
                    119:  */
                    120: int
1.13      christos  121: __rec_fpipe(BTREE *t, recno_t top)
1.1       cgd       122: {
                    123:        DBT data;
                    124:        recno_t nrec;
                    125:        size_t len;
                    126:        int ch;
1.14      joerg     127:        uint8_t *p;
1.1       cgd       128:
1.8       cgd       129:        if (t->bt_rdata.size < t->bt_reclen) {
1.17      christos  130:                void *np = realloc(t->bt_rdata.data, t->bt_reclen);
                    131:                if (np == NULL)
1.1       cgd       132:                        return (RET_ERROR);
1.17      christos  133:                t->bt_rdata.data = np;
1.8       cgd       134:                t->bt_rdata.size = t->bt_reclen;
1.1       cgd       135:        }
1.8       cgd       136:        data.data = t->bt_rdata.data;
1.5       cgd       137:        data.size = t->bt_reclen;
1.6       cgd       138:
1.8       cgd       139:        for (nrec = t->bt_nrecs; nrec < top;) {
1.1       cgd       140:                len = t->bt_reclen;
1.8       cgd       141:                for (p = t->bt_rdata.data;; *p++ = ch)
                    142:                        if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
                    143:                                if (ch != EOF)
                    144:                                        *p = ch;
                    145:                                if (len != 0)
                    146:                                        memset(p, t->bt_bval, len);
                    147:                                if (__rec_iput(t,
                    148:                                    nrec, &data, 0) != RET_SUCCESS)
1.1       cgd       149:                                        return (RET_ERROR);
1.8       cgd       150:                                ++nrec;
1.1       cgd       151:                                break;
                    152:                        }
                    153:                if (ch == EOF)
                    154:                        break;
                    155:        }
                    156:        if (nrec < top) {
1.8       cgd       157:                F_SET(t, R_EOF);
1.1       cgd       158:                return (RET_SPECIAL);
                    159:        }
                    160:        return (RET_SUCCESS);
                    161: }
                    162:
                    163: /*
                    164:  * __REC_VPIPE -- Get variable length records from a pipe.
                    165:  *
                    166:  * Parameters:
                    167:  *     t:      tree
                    168:  *     cnt:    records to read
                    169:  *
                    170:  * Returns:
                    171:  *     RET_ERROR, RET_SUCCESS
                    172:  */
                    173: int
1.13      christos  174: __rec_vpipe(BTREE *t, recno_t top)
1.1       cgd       175: {
                    176:        DBT data;
                    177:        recno_t nrec;
                    178:        size_t sz;
                    179:        int bval, ch;
1.14      joerg     180:        uint8_t *p;
1.1       cgd       181:
                    182:        bval = t->bt_bval;
                    183:        for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
1.8       cgd       184:                for (p = t->bt_rdata.data,
                    185:                    sz = t->bt_rdata.size;; *p++ = ch, --sz) {
1.1       cgd       186:                        if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
1.8       cgd       187:                                data.data = t->bt_rdata.data;
1.14      joerg     188:                                data.size = p - (uint8_t *)t->bt_rdata.data;
1.1       cgd       189:                                if (ch == EOF && data.size == 0)
                    190:                                        break;
                    191:                                if (__rec_iput(t, nrec, &data, 0)
                    192:                                    != RET_SUCCESS)
                    193:                                        return (RET_ERROR);
                    194:                                break;
                    195:                        }
                    196:                        if (sz == 0) {
1.18    ! christos  197:                                ptrdiff_t len = p - (uint8_t *)t->bt_rdata.data;
        !           198:                                size_t tot = t->bt_rdata.size + (sz = 256);
        !           199:                                void *np = realloc(t->bt_rdata.data, tot);
1.17      christos  200:                                if (np == NULL)
1.1       cgd       201:                                        return (RET_ERROR);
1.18    ! christos  202:                                t->bt_rdata.size = tot;
1.17      christos  203:                                t->bt_rdata.data = np;
1.14      joerg     204:                                p = (uint8_t *)t->bt_rdata.data + len;
1.1       cgd       205:                        }
                    206:                }
                    207:                if (ch == EOF)
                    208:                        break;
                    209:        }
                    210:        if (nrec < top) {
1.8       cgd       211:                F_SET(t, R_EOF);
1.1       cgd       212:                return (RET_SPECIAL);
                    213:        }
                    214:        return (RET_SUCCESS);
                    215: }
                    216:
                    217: /*
                    218:  * __REC_FMAP -- Get fixed length records from a file.
                    219:  *
                    220:  * Parameters:
                    221:  *     t:      tree
                    222:  *     cnt:    records to read
                    223:  *
                    224:  * Returns:
                    225:  *     RET_ERROR, RET_SUCCESS
                    226:  */
                    227: int
1.13      christos  228: __rec_fmap(BTREE *t, recno_t top)
1.1       cgd       229: {
                    230:        DBT data;
                    231:        recno_t nrec;
1.14      joerg     232:        uint8_t *sp, *ep, *p;
1.1       cgd       233:        size_t len;
                    234:
1.8       cgd       235:        if (t->bt_rdata.size < t->bt_reclen) {
1.17      christos  236:                void *np = realloc(t->bt_rdata.data, t->bt_reclen);
                    237:                if (np == NULL)
1.1       cgd       238:                        return (RET_ERROR);
1.17      christos  239:                t->bt_rdata.data = np;
1.8       cgd       240:                t->bt_rdata.size = t->bt_reclen;
1.1       cgd       241:        }
1.8       cgd       242:        data.data = t->bt_rdata.data;
1.6       cgd       243:        data.size = t->bt_reclen;
                    244:
1.14      joerg     245:        sp = (uint8_t *)t->bt_cmap;
                    246:        ep = (uint8_t *)t->bt_emap;
1.1       cgd       247:        for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
                    248:                if (sp >= ep) {
1.8       cgd       249:                        F_SET(t, R_EOF);
1.1       cgd       250:                        return (RET_SPECIAL);
                    251:                }
                    252:                len = t->bt_reclen;
1.8       cgd       253:                for (p = t->bt_rdata.data;
                    254:                    sp < ep && len > 0; *p++ = *sp++, --len);
                    255:                if (len != 0)
                    256:                        memset(p, t->bt_bval, len);
1.1       cgd       257:                if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
                    258:                        return (RET_ERROR);
                    259:        }
1.8       cgd       260:        t->bt_cmap = (caddr_t)sp;
1.1       cgd       261:        return (RET_SUCCESS);
                    262: }
                    263:
                    264: /*
                    265:  * __REC_VMAP -- Get variable length records from a file.
                    266:  *
                    267:  * Parameters:
                    268:  *     t:      tree
                    269:  *     cnt:    records to read
                    270:  *
                    271:  * Returns:
                    272:  *     RET_ERROR, RET_SUCCESS
                    273:  */
                    274: int
1.13      christos  275: __rec_vmap(BTREE *t, recno_t top)
1.1       cgd       276: {
                    277:        DBT data;
1.14      joerg     278:        uint8_t *sp, *ep;
1.1       cgd       279:        recno_t nrec;
                    280:        int bval;
                    281:
1.14      joerg     282:        sp = (uint8_t *)t->bt_cmap;
                    283:        ep = (uint8_t *)t->bt_emap;
1.1       cgd       284:        bval = t->bt_bval;
                    285:
                    286:        for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
                    287:                if (sp >= ep) {
1.8       cgd       288:                        F_SET(t, R_EOF);
1.1       cgd       289:                        return (RET_SPECIAL);
                    290:                }
                    291:                for (data.data = sp; sp < ep && *sp != bval; ++sp);
1.14      joerg     292:                data.size = sp - (uint8_t *)data.data;
1.1       cgd       293:                if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
                    294:                        return (RET_ERROR);
                    295:                ++sp;
                    296:        }
1.8       cgd       297:        t->bt_cmap = (caddr_t)sp;
1.1       cgd       298:        return (RET_SUCCESS);
                    299: }

CVSweb <webmaster@jp.NetBSD.org>