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