Initial import from FreeBSD RELENG_4:
[dragonfly.git] / lib / libc / db / btree / bt_conv.c
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  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #if defined(LIBC_SCCS) && !defined(lint)
38 static char sccsid[] = "@(#)bt_conv.c   8.5 (Berkeley) 8/17/94";
39 #endif /* LIBC_SCCS and not lint */
40
41 #include <sys/param.h>
42
43 #include <stdio.h>
44
45 #include <db.h>
46 #include "btree.h"
47
48 static void mswap __P((PAGE *));
49
50 /*
51  * __BT_BPGIN, __BT_BPGOUT --
52  *      Convert host-specific number layout to/from the host-independent
53  *      format stored on disk.
54  *
55  * Parameters:
56  *      t:      tree
57  *      pg:     page number
58  *      h:      page to convert
59  */
60 void
61 __bt_pgin(t, pg, pp)
62         void *t;
63         pgno_t pg;
64         void *pp;
65 {
66         PAGE *h;
67         indx_t i, top;
68         u_char flags;
69         char *p;
70
71         if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
72                 return;
73         if (pg == P_META) {
74                 mswap(pp);
75                 return;
76         }
77
78         h = pp;
79         M_32_SWAP(h->pgno);
80         M_32_SWAP(h->prevpg);
81         M_32_SWAP(h->nextpg);
82         M_32_SWAP(h->flags);
83         M_16_SWAP(h->lower);
84         M_16_SWAP(h->upper);
85
86         top = NEXTINDEX(h);
87         if ((h->flags & P_TYPE) == P_BINTERNAL)
88                 for (i = 0; i < top; i++) {
89                         M_16_SWAP(h->linp[i]);
90                         p = (char *)GETBINTERNAL(h, i);
91                         P_32_SWAP(p);
92                         p += sizeof(u_int32_t);
93                         P_32_SWAP(p);
94                         p += sizeof(pgno_t);
95                         if (*(u_char *)p & P_BIGKEY) {
96                                 p += sizeof(u_char);
97                                 P_32_SWAP(p);
98                                 p += sizeof(pgno_t);
99                                 P_32_SWAP(p);
100                         }
101                 }
102         else if ((h->flags & P_TYPE) == P_BLEAF)
103                 for (i = 0; i < top; i++) {
104                         M_16_SWAP(h->linp[i]);
105                         p = (char *)GETBLEAF(h, i);
106                         P_32_SWAP(p);
107                         p += sizeof(u_int32_t);
108                         P_32_SWAP(p);
109                         p += sizeof(u_int32_t);
110                         flags = *(u_char *)p;
111                         if (flags & (P_BIGKEY | P_BIGDATA)) {
112                                 p += sizeof(u_char);
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 += sizeof(u_int32_t);
120                                         P_32_SWAP(p);
121                                         p += sizeof(pgno_t);
122                                         P_32_SWAP(p);
123                                 }
124                         }
125                 }
126 }
127
128 void
129 __bt_pgout(t, pg, pp)
130         void *t;
131         pgno_t pg;
132         void *pp;
133 {
134         PAGE *h;
135         indx_t i, top;
136         u_char flags;
137         char *p;
138
139         if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
140                 return;
141         if (pg == P_META) {
142                 mswap(pp);
143                 return;
144         }
145
146         h = pp;
147         top = NEXTINDEX(h);
148         if ((h->flags & P_TYPE) == P_BINTERNAL)
149                 for (i = 0; i < top; i++) {
150                         p = (char *)GETBINTERNAL(h, i);
151                         P_32_SWAP(p);
152                         p += sizeof(u_int32_t);
153                         P_32_SWAP(p);
154                         p += sizeof(pgno_t);
155                         if (*(u_char *)p & P_BIGKEY) {
156                                 p += sizeof(u_char);
157                                 P_32_SWAP(p);
158                                 p += sizeof(pgno_t);
159                                 P_32_SWAP(p);
160                         }
161                         M_16_SWAP(h->linp[i]);
162                 }
163         else if ((h->flags & P_TYPE) == P_BLEAF)
164                 for (i = 0; i < top; i++) {
165                         p = (char *)GETBLEAF(h, i);
166                         P_32_SWAP(p);
167                         p += sizeof(u_int32_t);
168                         P_32_SWAP(p);
169                         p += sizeof(u_int32_t);
170                         flags = *(u_char *)p;
171                         if (flags & (P_BIGKEY | P_BIGDATA)) {
172                                 p += sizeof(u_char);
173                                 if (flags & P_BIGKEY) {
174                                         P_32_SWAP(p);
175                                         p += sizeof(pgno_t);
176                                         P_32_SWAP(p);
177                                 }
178                                 if (flags & P_BIGDATA) {
179                                         p += sizeof(u_int32_t);
180                                         P_32_SWAP(p);
181                                         p += sizeof(pgno_t);
182                                         P_32_SWAP(p);
183                                 }
184                         }
185                         M_16_SWAP(h->linp[i]);
186                 }
187
188         M_32_SWAP(h->pgno);
189         M_32_SWAP(h->prevpg);
190         M_32_SWAP(h->nextpg);
191         M_32_SWAP(h->flags);
192         M_16_SWAP(h->lower);
193         M_16_SWAP(h->upper);
194 }
195
196 /*
197  * MSWAP -- Actually swap the bytes on the meta page.
198  *
199  * Parameters:
200  *      p:      page to convert
201  */
202 static void
203 mswap(pg)
204         PAGE *pg;
205 {
206         char *p;
207
208         p = (char *)pg;
209         P_32_SWAP(p);           /* magic */
210         p += sizeof(u_int32_t);
211         P_32_SWAP(p);           /* version */
212         p += sizeof(u_int32_t);
213         P_32_SWAP(p);           /* psize */
214         p += sizeof(u_int32_t);
215         P_32_SWAP(p);           /* free */
216         p += sizeof(u_int32_t);
217         P_32_SWAP(p);           /* nrecs */
218         p += sizeof(u_int32_t);
219         P_32_SWAP(p);           /* flags */
220         p += sizeof(u_int32_t);
221 }