mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
262 lines
8.3 KiB
C
262 lines
8.3 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/*
|
|
* COMPONENT_NAME: austext
|
|
*
|
|
* FUNCTIONS: swab_page
|
|
*
|
|
* ORIGINS: 27
|
|
*
|
|
* (C) COPYRIGHT International Business Machines Corp. 1996
|
|
* All Rights Reserved
|
|
* Licensed Materials - Property of IBM
|
|
* US Government Users Restricted Rights - Use, duplication or
|
|
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
|
*/
|
|
/********************* DBSWAB.C **********************************
|
|
* $XConsortium: dbswab.c /main/3 1996/10/28 13:59:11 drk $
|
|
* July 1996.
|
|
* These functions do byte swap and other manipulations on
|
|
* vista cache pages to ensure that database files are
|
|
* maintained in a canonical format no matter what machine
|
|
* they are used on.
|
|
* The DtSearch data records are presumed already in external
|
|
* file format by code at the DtSearch level (dtsrswab.c).
|
|
* These functions use the standard htonl, htons, ntohl, and ntohs
|
|
* network conversion functions for byte order neutrality.
|
|
* They use the LONG and INT typedefs in vista.h
|
|
* to control integer size.
|
|
* The external database files are in the canonical,
|
|
* big-endian "network" order.
|
|
* So that they can be defined as "null" macros on big endian machines,
|
|
* the functions (1) always byte swap in place, and (2) always succeed.
|
|
*
|
|
* $Log$
|
|
*/
|
|
#include "vista.h"
|
|
#include "dbtype.h"
|
|
#include "dbswab.h"
|
|
|
|
#define DEBUG_DBSWAB
|
|
#ifdef DEBUG_DBSWAB
|
|
#include <stdio.h>
|
|
int debugging_dbswab = FALSE;
|
|
int debugging_key_swabs = FALSE;
|
|
#endif
|
|
|
|
|
|
/********************************/
|
|
/* */
|
|
/* swab_page */
|
|
/* */
|
|
/********************************/
|
|
/* Performs byte swap on all slots of any cache page except page 0.
|
|
* 4-byte timestamp page header already swapped by caller.
|
|
*
|
|
* WARNING! The algorithms will only work for the
|
|
* DtSearch schema. For data pages, they ignore the
|
|
* 1-byte optional key flags except for the OR_MISC record.
|
|
* The first 6 bytes of each slot (rectype, dba)
|
|
* are always byte swapped. Thereafter every 4-bytes
|
|
* is swapped as set or member ptrs until we reach
|
|
* the data offset. For OR_MISC records we presume
|
|
* exactly 1 byte of optional key flags before the
|
|
* set/member ptrs.
|
|
*/
|
|
void swab_page (char *pgbuf, FILE_ENTRY *file_ptr, SWABDIR direction)
|
|
{
|
|
#if defined(WORDS_BIGENDIAN)
|
|
return;
|
|
#else
|
|
INT slotno;
|
|
char *slotptr;
|
|
char *cptr;
|
|
INT slsize = file_ptr->ft_slsize;
|
|
INT slots = file_ptr->ft_slots; /* # slots per page */
|
|
INT recno;
|
|
INT used_count;
|
|
INT key_prefix;
|
|
INT curr_offset, data_offset;
|
|
INT align_INT;
|
|
LONG align_LONG;
|
|
|
|
/*----------------- DATA PAGES --------------------
|
|
* If file is 'data' file, slots begin immediately after
|
|
* the page's timestamp. For each slot we have to swap
|
|
* the optional set and member tables as well as fixed
|
|
* slot header data.
|
|
*/
|
|
if (file_ptr->ft_type == DATA) {
|
|
#ifdef DEBUG_DBSWAB
|
|
if (debugging_dbswab) {
|
|
printf (__FILE__"073 %s DATA page '%s': slct=%d slsz=%d pgsz=%d\n",
|
|
(direction == HTON)? "WRITE" : "READ",
|
|
file_ptr->ft_name, (int)file_ptr->ft_slots,
|
|
(int)file_ptr->ft_slsize, (int)file_ptr->ft_pgsize);
|
|
fflush(stdout);
|
|
}
|
|
#endif
|
|
|
|
for ( slotno = 0, slotptr = pgbuf + 4; /* over timestamp */
|
|
slotno < slots;
|
|
slotno++, slotptr += slsize) {
|
|
|
|
/* record number (= record type)
|
|
* Save the correct host order value in 'recno'.
|
|
*/
|
|
memcpy (&align_INT, slotptr, sizeof(INT));
|
|
if (direction == HTON) {
|
|
recno = align_INT;
|
|
HTONS (align_INT);
|
|
}
|
|
else {
|
|
NTOHS (align_INT);
|
|
recno = align_INT;
|
|
}
|
|
memcpy (slotptr, &align_INT, sizeof(INT));
|
|
|
|
/* dba, or delete chain ptr */
|
|
memcpy (&align_LONG, slotptr + sizeof(INT), sizeof(LONG));
|
|
align_LONG = HTONL (align_LONG);
|
|
memcpy (slotptr + sizeof(INT), &align_LONG, sizeof(LONG));
|
|
|
|
/* If this is a deleted record, we're done */
|
|
if (recno & 0x8000)
|
|
continue;
|
|
|
|
/* Swap 4-byte set/member ptrs till we hit data */
|
|
recno &= 0x0fff; /* switch off delete and lock bits */
|
|
data_offset = record_table[recno].rt_data;
|
|
for ( curr_offset = (recno == MISCREC_RECNO)? 7 : 6;
|
|
curr_offset < data_offset;
|
|
curr_offset += sizeof(LONG)) {
|
|
memcpy (&align_LONG, slotptr + curr_offset, sizeof(LONG));
|
|
align_LONG = HTONL (align_LONG);
|
|
memcpy (slotptr + curr_offset, &align_LONG, sizeof(LONG));
|
|
}
|
|
} /* end loop on each slot */
|
|
} /* end if (data page) */
|
|
|
|
/*----------------- KEY PAGES --------------------
|
|
* DtSearch doesn't use anything but key and data files
|
|
* so this must be a key file. A b-tree node = one cache page.
|
|
* Before the slots begin in a key file page there is
|
|
* additional header data to be swapped after the timestamp:
|
|
* the used_slots count (2 bytes) and the orphan ptr (4 bytes).
|
|
* If used_slots == 0, then the page is not used and the
|
|
* orphan ptr is really a delete chain ptr for the entire node.
|
|
*/
|
|
else {
|
|
/* 'used_slots'
|
|
* Save the correct host order value in 'used_count'.
|
|
*/
|
|
memcpy (&align_INT, pgbuf + 4, sizeof(INT));
|
|
if (direction == HTON) {
|
|
used_count = align_INT;
|
|
HTONS (align_INT);
|
|
}
|
|
else {
|
|
NTOHS (align_INT);
|
|
used_count = align_INT;
|
|
}
|
|
memcpy (pgbuf + 4, &align_INT, sizeof(INT));
|
|
|
|
/* 'orphan' ptr or 'delete chain' ptr */
|
|
memcpy (&align_LONG, pgbuf + 6, sizeof(LONG));
|
|
align_LONG = HTONL (align_LONG);
|
|
memcpy (pgbuf + 6, &align_LONG, sizeof(LONG));
|
|
|
|
#ifdef DEBUG_DBSWAB
|
|
if (debugging_dbswab || debugging_key_swabs) {
|
|
printf (__FILE__
|
|
"124 %s KEY page '%s': slct=%d used=%d slsz=%d pgsz=%d\n",
|
|
(direction == HTON)? "WRITE" : "READ",
|
|
file_ptr->ft_name, (int)slots,
|
|
(int)used_count,
|
|
(int)slsize, (int)file_ptr->ft_pgsize);
|
|
fflush (stdout);
|
|
}
|
|
#endif
|
|
/* For each used slot we have to swap the key prefix
|
|
* at the beginning of the slot, then at the *end*
|
|
* of the key, the dba, followed by the child node ptr.
|
|
* (This is not the format raima published but it's true!)
|
|
* Slots start at pg offset 10: timestamp + used_slots + orphan ptr.
|
|
* Note that if used_count == 0, we won't process
|
|
* this deleted node any further.
|
|
*/
|
|
for ( slotno = 0, slotptr = pgbuf + 10;
|
|
slotno < used_count;
|
|
slotno++, slotptr += slsize) {
|
|
|
|
/* 'key prefix. Save host order value. */
|
|
memcpy (&align_INT, slotptr, sizeof(INT));
|
|
if (direction == HTON) {
|
|
key_prefix = align_INT;
|
|
HTONS (align_INT);
|
|
}
|
|
else {
|
|
NTOHS (align_INT);
|
|
key_prefix = align_INT;
|
|
}
|
|
memcpy (slotptr, &align_INT, sizeof(INT));
|
|
|
|
#ifdef DEBUG_DBSWAB
|
|
if (debugging_key_swabs)
|
|
printf (" slot #%02d: prefix=%d",
|
|
(int)slotno, (int)key_prefix);
|
|
#endif
|
|
/* database address.
|
|
* All DtSearch keys are unswapped char strings.
|
|
* The dba is just past the key, 8 bytes before
|
|
* of the end of the slot.
|
|
*/
|
|
cptr = slotptr + slsize - 8;
|
|
|
|
memcpy (&align_LONG, cptr, sizeof(LONG));
|
|
align_LONG = HTONL (align_LONG);
|
|
memcpy (cptr, &align_LONG, sizeof(LONG));
|
|
|
|
#ifdef DEBUG_DBSWAB
|
|
if (debugging_key_swabs) {
|
|
printf (" dba=x%08lx key='%s'\n", (direction == NTOH)?
|
|
(long)align_LONG : (long)ntohl(align_LONG),
|
|
slotptr + 2);
|
|
fflush (stdout);
|
|
}
|
|
#endif
|
|
|
|
/* 'child ptr'. after dba, 4 bytes before end of slot. */
|
|
cptr += 4;
|
|
memcpy (&align_LONG, cptr, sizeof(LONG));
|
|
align_LONG = HTONL (align_LONG);
|
|
memcpy (cptr, &align_LONG, sizeof(LONG));
|
|
|
|
} /* end loop on each slot */
|
|
} /* end if (key page) */
|
|
|
|
return;
|
|
#endif /* BYTE_SWAP */
|
|
} /* swab_page() */
|
|
|
|
/********************* DBSWAB.C **********************************/
|