11573Srgrimes/*-
214272Spst * Copyright (c) 1990, 1993, 1994
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 4. Neither the name of the University nor the names of its contributors
141573Srgrimes *    may be used to endorse or promote products derived from this software
151573Srgrimes *    without specific prior written permission.
161573Srgrimes *
171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271573Srgrimes * SUCH DAMAGE.
281573Srgrimes */
291573Srgrimes
301573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
3114272Spststatic char sccsid[] = "@(#)rec_utils.c	8.6 (Berkeley) 7/16/94";
321573Srgrimes#endif /* LIBC_SCCS and not lint */
3392986Sobrien#include <sys/cdefs.h>
3492986Sobrien__FBSDID("$FreeBSD$");
351573Srgrimes
361573Srgrimes#include <sys/param.h>
371573Srgrimes
381573Srgrimes#include <stdio.h>
391573Srgrimes#include <stdlib.h>
401573Srgrimes#include <string.h>
411573Srgrimes
421573Srgrimes#include <db.h>
431573Srgrimes#include "recno.h"
441573Srgrimes
451573Srgrimes/*
4614272Spst * __rec_ret --
4714272Spst *	Build return data.
481573Srgrimes *
491573Srgrimes * Parameters:
501573Srgrimes *	t:	tree
5114272Spst *	e:	key/data pair to be returned
5214272Spst *   nrec:	record number
5314272Spst *    key:	user's key structure
54189327Sdelphij *   data:	user's data structure
551573Srgrimes *
561573Srgrimes * Returns:
571573Srgrimes *	RET_SUCCESS, RET_ERROR.
581573Srgrimes */
591573Srgrimesint
60189291Sdelphij__rec_ret(BTREE *t, EPG *e, recno_t nrec, DBT *key, DBT *data)
611573Srgrimes{
6214272Spst	RLEAF *rl;
6314272Spst	void *p;
641573Srgrimes
6514272Spst	if (key == NULL)
6614272Spst		goto dataonly;
6714272Spst
6814272Spst	/* We have to copy the key, it's not on the page. */
6914272Spst	if (sizeof(recno_t) > t->bt_rkey.size) {
70189387Sdelphij		p = realloc(t->bt_rkey.data, sizeof(recno_t));
7114272Spst		if (p == NULL)
7214272Spst			return (RET_ERROR);
7314272Spst		t->bt_rkey.data = p;
7414272Spst		t->bt_rkey.size = sizeof(recno_t);
7514272Spst	}
7614272Spst	memmove(t->bt_rkey.data, &nrec, sizeof(recno_t));
7714272Spst	key->size = sizeof(recno_t);
7814272Spst	key->data = t->bt_rkey.data;
7914272Spst
8014272Spstdataonly:
811573Srgrimes	if (data == NULL)
8214272Spst		return (RET_SUCCESS);
831573Srgrimes
841573Srgrimes	/*
8514272Spst	 * We must copy big keys/data to make them contigous.  Otherwise,
861573Srgrimes	 * leave the page pinned and don't copy unless the user specified
871573Srgrimes	 * concurrent access.
881573Srgrimes	 */
8914272Spst	rl = GETRLEAF(e->page, e->index);
901573Srgrimes	if (rl->flags & P_BIGDATA) {
911573Srgrimes		if (__ovfl_get(t, rl->bytes,
9214272Spst		    &data->size, &t->bt_rdata.data, &t->bt_rdata.size))
931573Srgrimes			return (RET_ERROR);
9414272Spst		data->data = t->bt_rdata.data;
9514272Spst	} else if (F_ISSET(t, B_DB_LOCK)) {
961573Srgrimes		/* Use +1 in case the first record retrieved is 0 length. */
9714272Spst		if (rl->dsize + 1 > t->bt_rdata.size) {
98189387Sdelphij			p = realloc(t->bt_rdata.data, rl->dsize + 1);
9914272Spst			if (p == NULL)
1001573Srgrimes				return (RET_ERROR);
10114272Spst			t->bt_rdata.data = p;
10214272Spst			t->bt_rdata.size = rl->dsize + 1;
1031573Srgrimes		}
10414272Spst		memmove(t->bt_rdata.data, rl->bytes, rl->dsize);
1051573Srgrimes		data->size = rl->dsize;
10614272Spst		data->data = t->bt_rdata.data;
1071573Srgrimes	} else {
1081573Srgrimes		data->size = rl->dsize;
1091573Srgrimes		data->data = rl->bytes;
1101573Srgrimes	}
1111573Srgrimes	return (RET_SUCCESS);
1121573Srgrimes}
113