/* $NetBSD: bt_conv.c,v 1.15 2016/09/24 20:11:12 christos Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: bt_conv.c,v 1.15 2016/09/24 20:11:12 christos Exp $");
#include <assert.h>
#include <stdio.h>
#include <memory.h>
#include <db.h>
#include "btree.h"
static void mswap(PAGE *);
/*
* __BT_BPGIN, __BT_BPGOUT --
* Convert host-specific number layout to/from the host-independent
* format stored on disk.
*
* Parameters:
* t: tree
* pg: page number
* h: page to convert
*/
void
__bt_pgin(void *t, pgno_t pg, void *pp)
{
PAGE *h;
indx_t i, top;
uint8_t flags;
char *p;
uint32_t ksize;
if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
return;
if (pg == P_META) {
mswap(pp);
return;
}
h = pp;
M_32_SWAP(h->pgno);
M_32_SWAP(h->prevpg);
M_32_SWAP(h->nextpg);
M_32_SWAP(h->flags);
M_16_SWAP(h->lower);
M_16_SWAP(h->upper);
top = NEXTINDEX(h);
if ((h->flags & P_TYPE) == P_BINTERNAL)
for (i = 0; i < top; i++) {
M_16_SWAP(h->linp[i]);
p = (char *)(void *)GETBINTERNAL(h, i);
P_32_SWAP(p);
p += sizeof(uint32_t);
P_32_SWAP(p);
p += sizeof(pgno_t);
if (*(uint8_t *)p & P_BIGKEY) {
p += sizeof(uint8_t);
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
}
else if ((h->flags & P_TYPE) == P_BLEAF)
for (i = 0; i < top; i++) {
M_16_SWAP(h->linp[i]);
p = (char *)(void *)GETBLEAF(h, i);
P_32_SWAP(p);
memcpy(&ksize, p, sizeof(ksize));
p += sizeof(uint32_t);
P_32_SWAP(p);
p += sizeof(uint32_t);
flags = *(uint8_t *)p;
if (flags & (P_BIGKEY | P_BIGDATA)) {
p += sizeof(uint8_t);
if (flags & P_BIGKEY) {
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
if (flags & P_BIGDATA) {
p += ksize;
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
}
}
}
void
__bt_pgout(void *t, pgno_t pg, void *pp)
{
PAGE *h;
indx_t i, top;
uint8_t flags;
char *p;
uint32_t ksize;
if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
return;
if (pg == P_META) {
mswap(pp);
return;
}
h = pp;
top = NEXTINDEX(h);
if ((h->flags & P_TYPE) == P_BINTERNAL)
for (i = 0; i < top; i++) {
p = (char *)(void *)GETBINTERNAL(h, i);
P_32_SWAP(p);
p += sizeof(uint32_t);
P_32_SWAP(p);
p += sizeof(pgno_t);
if (*(uint8_t *)p & P_BIGKEY) {
p += sizeof(uint8_t);
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
M_16_SWAP(h->linp[i]);
}
else if ((h->flags & P_TYPE) == P_BLEAF)
for (i = 0; i < top; i++) {
p = (char *)(void *)GETBLEAF(h, i);
ksize = GETBLEAF(h, i)->ksize;
P_32_SWAP(p);
p += sizeof(uint32_t);
P_32_SWAP(p);
p += sizeof(uint32_t);
flags = *(uint8_t *)p;
if (flags & (P_BIGKEY | P_BIGDATA)) {
p += sizeof(uint8_t);
if (flags & P_BIGKEY) {
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
if (flags & P_BIGDATA) {
p += ksize;
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
}
M_16_SWAP(h->linp[i]);
}
M_32_SWAP(h->pgno);
M_32_SWAP(h->prevpg);
M_32_SWAP(h->nextpg);
M_32_SWAP(h->flags);
M_16_SWAP(h->lower);
M_16_SWAP(h->upper);
}
/*
* MSWAP -- Actually swap the bytes on the meta page.
*
* Parameters:
* p: page to convert
*/
static void
mswap(PAGE *pg)
{
char *p;
p = (char *)(void *)pg;
P_32_SWAP(p); /* magic */
p += sizeof(uint32_t);
P_32_SWAP(p); /* version */
p += sizeof(uint32_t);
P_32_SWAP(p); /* psize */
p += sizeof(uint32_t);
P_32_SWAP(p); /* free */
p += sizeof(uint32_t);
P_32_SWAP(p); /* nrecs */
p += sizeof(uint32_t);
P_32_SWAP(p); /* flags */
p += sizeof(uint32_t);
}