1 /* $NetBSD: bt_conv.c,v 1.15 2016/09/24 20:11:12 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1990, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Mike Olson.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #if HAVE_NBTOOL_CONFIG_H
36 #include "nbtool_config.h"
37 #endif
38
39 #include <sys/cdefs.h>
40 __RCSID("$NetBSD: bt_conv.c,v 1.15 2016/09/24 20:11:12 christos Exp $");
41
42 #include <assert.h>
43 #include <stdio.h>
44 #include <memory.h>
45
46 #include <db.h>
47 #include "btree.h"
48
49 static void mswap(PAGE *);
50
51 /*
52 * __BT_BPGIN, __BT_BPGOUT --
53 * Convert host-specific number layout to/from the host-independent
54 * format stored on disk.
55 *
56 * Parameters:
57 * t: tree
58 * pg: page number
59 * h: page to convert
60 */
61 void
__bt_pgin(void * t,pgno_t pg,void * pp)62 __bt_pgin(void *t, pgno_t pg, void *pp)
63 {
64 PAGE *h;
65 indx_t i, top;
66 uint8_t flags;
67 char *p;
68 uint32_t ksize;
69
70 if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
71 return;
72 if (pg == P_META) {
73 mswap(pp);
74 return;
75 }
76
77 h = pp;
78 M_32_SWAP(h->pgno);
79 M_32_SWAP(h->prevpg);
80 M_32_SWAP(h->nextpg);
81 M_32_SWAP(h->flags);
82 M_16_SWAP(h->lower);
83 M_16_SWAP(h->upper);
84
85 top = NEXTINDEX(h);
86 if ((h->flags & P_TYPE) == P_BINTERNAL)
87 for (i = 0; i < top; i++) {
88 M_16_SWAP(h->linp[i]);
89 p = (char *)(void *)GETBINTERNAL(h, i);
90 P_32_SWAP(p);
91 p += sizeof(uint32_t);
92 P_32_SWAP(p);
93 p += sizeof(pgno_t);
94 if (*(uint8_t *)p & P_BIGKEY) {
95 p += sizeof(uint8_t);
96 P_32_SWAP(p);
97 p += sizeof(pgno_t);
98 P_32_SWAP(p);
99 }
100 }
101 else if ((h->flags & P_TYPE) == P_BLEAF)
102 for (i = 0; i < top; i++) {
103 M_16_SWAP(h->linp[i]);
104 p = (char *)(void *)GETBLEAF(h, i);
105 P_32_SWAP(p);
106 memcpy(&ksize, p, sizeof(ksize));
107 p += sizeof(uint32_t);
108 P_32_SWAP(p);
109 p += sizeof(uint32_t);
110 flags = *(uint8_t *)p;
111 if (flags & (P_BIGKEY | P_BIGDATA)) {
112 p += sizeof(uint8_t);
113 if (flags & P_BIGKEY) {
114 P_32_SWAP(p);
115 p += sizeof(pgno_t);
116 P_32_SWAP(p);
117 }
118 if (flags & P_BIGDATA) {
119 p += ksize;
120 P_32_SWAP(p);
121 p += sizeof(pgno_t);
122 P_32_SWAP(p);
123 }
124 }
125 }
126 }
127
128 void
__bt_pgout(void * t,pgno_t pg,void * pp)129 __bt_pgout(void *t, pgno_t pg, void *pp)
130 {
131 PAGE *h;
132 indx_t i, top;
133 uint8_t flags;
134 char *p;
135 uint32_t ksize;
136
137 if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
138 return;
139 if (pg == P_META) {
140 mswap(pp);
141 return;
142 }
143
144 h = pp;
145 top = NEXTINDEX(h);
146 if ((h->flags & P_TYPE) == P_BINTERNAL)
147 for (i = 0; i < top; i++) {
148 p = (char *)(void *)GETBINTERNAL(h, i);
149 P_32_SWAP(p);
150 p += sizeof(uint32_t);
151 P_32_SWAP(p);
152 p += sizeof(pgno_t);
153 if (*(uint8_t *)p & P_BIGKEY) {
154 p += sizeof(uint8_t);
155 P_32_SWAP(p);
156 p += sizeof(pgno_t);
157 P_32_SWAP(p);
158 }
159 M_16_SWAP(h->linp[i]);
160 }
161 else if ((h->flags & P_TYPE) == P_BLEAF)
162 for (i = 0; i < top; i++) {
163 p = (char *)(void *)GETBLEAF(h, i);
164 ksize = GETBLEAF(h, i)->ksize;
165 P_32_SWAP(p);
166 p += sizeof(uint32_t);
167 P_32_SWAP(p);
168 p += sizeof(uint32_t);
169 flags = *(uint8_t *)p;
170 if (flags & (P_BIGKEY | P_BIGDATA)) {
171 p += sizeof(uint8_t);
172 if (flags & P_BIGKEY) {
173 P_32_SWAP(p);
174 p += sizeof(pgno_t);
175 P_32_SWAP(p);
176 }
177 if (flags & P_BIGDATA) {
178 p += ksize;
179 P_32_SWAP(p);
180 p += sizeof(pgno_t);
181 P_32_SWAP(p);
182 }
183 }
184 M_16_SWAP(h->linp[i]);
185 }
186
187 M_32_SWAP(h->pgno);
188 M_32_SWAP(h->prevpg);
189 M_32_SWAP(h->nextpg);
190 M_32_SWAP(h->flags);
191 M_16_SWAP(h->lower);
192 M_16_SWAP(h->upper);
193 }
194
195 /*
196 * MSWAP -- Actually swap the bytes on the meta page.
197 *
198 * Parameters:
199 * p: page to convert
200 */
201 static void
mswap(PAGE * pg)202 mswap(PAGE *pg)
203 {
204 char *p;
205
206 p = (char *)(void *)pg;
207 P_32_SWAP(p); /* magic */
208 p += sizeof(uint32_t);
209 P_32_SWAP(p); /* version */
210 p += sizeof(uint32_t);
211 P_32_SWAP(p); /* psize */
212 p += sizeof(uint32_t);
213 P_32_SWAP(p); /* free */
214 p += sizeof(uint32_t);
215 P_32_SWAP(p); /* nrecs */
216 p += sizeof(uint32_t);
217 P_32_SWAP(p); /* flags */
218 p += sizeof(uint32_t);
219 }
220