p = t->bt_rdata.data; if (bo->tlen > dbt->doff) if (dbt->dlen > dbt->size) { tlen += len = bo->tlen - dbt->doff - (dbt->dlen - dbt->size); memmove(p + dbt->doff + dbt->size, p + dbt->doff + dbt->dlen, len); } else if (dbt->dlen < dbt->size) { tlen += len = bo->tlen - dbt->doff - (dbt->size - dbt->dlen); memmove(p + dbt->doff + dbt->dlen, p + dbt->doff + dbt->size, len); } else tlen += bo->tlen - dbt->doff;
if (bo->tlen > dbt->doff + dbt->dlen) { len = bo->tlen - (dbt->doff + dbt->dlen); if (dbt->dlen != dbt->size) memmove(p + dbt->size, p + dbt->dlen, len); tlen += len; }
__bam_partial(dbp, dbt, h, indx, nbytes)	DB *dbp;	DBT *dbt;	PAGE *h;	u_int32_t indx, nbytes;{	BTREE *t;	BKEYDATA *bk, tbk;	BOVERFLOW *bo;	DBT copy;	u_int32_t len, tlen;	int ret;	u_int8_t *p;	COMPQUIET(bo, NULL);	t = dbp->internal;	/* We use the record data return memory, it's only a short-term use. */	if (t->bt_rdata.ulen < nbytes) {		t->bt_rdata.data = t->bt_rdata.data == NULL ?		    (void *)__db_malloc(nbytes) :		    (void *)__db_realloc(t->bt_rdata.data, nbytes);		if (t->bt_rdata.data == NULL) {			t->bt_rdata.ulen = 0;			return (ENOMEM);		}		t->bt_rdata.ulen = nbytes;	}	/* Find the current record. */	if (indx < NUM_ENT(h)) {		bk = GET_BKEYDATA(h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0));		bo = (BOVERFLOW *)bk;	} else {		bk = &tbk;		B_TSET(bk->type, B_KEYDATA, 0);		bk->len = 0;	}	/* We use nul bytes for extending the record, get it over with. */	memset(t->bt_rdata.data, 0, nbytes);	tlen = 0;	if (B_TYPE(bk->type) == B_OVERFLOW) {		/* Take up to doff bytes from the record. */		memset(&copy, 0, sizeof(copy));		if ((ret = __db_goff(dbp, &copy, bo->tlen,		    bo->pgno, &t->bt_rdata.data, &t->bt_rdata.ulen)) != 0)			return (ret);		tlen += dbt->doff;		/*		 * If the original record was larger than the offset:		 *	If dlen > size, shift the remaining data down.		 *	If dlen < size, shift the remaining data up.		 * Use memmove(), the regions may overlap.		 */		p = t->bt_rdata.data;		if (bo->tlen > dbt->doff)			if (dbt->dlen > dbt->size) {				tlen += len = bo->tlen -				    dbt->doff - (dbt->dlen - dbt->size);				memmove(p + dbt->doff + dbt->size,				    p + dbt->doff + dbt->dlen, len);			} else if (dbt->dlen < dbt->size) {				tlen += len = bo->tlen -				    dbt->doff - (dbt->size - dbt->dlen);				memmove(p + dbt->doff + dbt->dlen,				    p + dbt->doff + dbt->size, len);			} else				tlen += bo->tlen - dbt->doff;		/* Copy in the user's data. */		memcpy((u_int8_t *)t->bt_rdata.data + dbt->doff,		    dbt->data, dbt->size);		tlen += dbt->size;	} else {		/* Take up to doff bytes from the record. */		memcpy(t->bt_rdata.data,		    bk->data, dbt->doff > bk->len ? bk->len : dbt->doff);		tlen += dbt->doff;		/* Copy in the user's data. */		memcpy((u_int8_t *)t->bt_rdata.data +		    dbt->doff, dbt->data, dbt->size);		tlen += dbt->size;		/* Copy in any remaining data. */		len = dbt->doff + dbt->dlen;		if (bk->len > len) {			memcpy((u_int8_t *)t->bt_rdata.data + dbt->doff +			    dbt->size, bk->data + len, bk->len - len);			tlen += bk->len - len;		}	}	/* Set the DBT to reference our new record. */	t->bt_rdata.size = tlen;	t->bt_rdata.dlen = 0;	t->bt_rdata.doff = 0;	t->bt_rdata.flags = 0;	*dbt = t->bt_rdata;	return (0);}