2 * Copyright (c) 1999, 2005-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 Contains: Single-node operations for the BTree Module.
28 Version: xxx put the technology version here xxx
30 Written by: Gordon Sheridan and Bill Bruffey
32 Copyright: © 1992-1999 by Apple Computer, Inc., all rights reserved.
35 #include "BTreePrivate.h"
36 #include "hfs_endian.h"
37 #include "../fsck_hfs.h"
40 ///////////////////////// BTree Module Node Operations //////////////////////////
42 // GetNode - Call FS Agent to get node
43 // GetNewNode - Call FS Agent to get a new node
44 // ReleaseNode - Call FS Agent to release node obtained by GetNode.
45 // UpdateNode - Mark a node as dirty and call FS Agent to release it.
47 // ClearNode - Clear a node to all zeroes.
49 // InsertRecord - Inserts a record into a BTree node.
50 // InsertKeyRecord - Inserts a key and record pair into a BTree node.
51 // DeleteRecord - Deletes a record from a BTree node.
53 // SearchNode - Return index for record that matches key.
54 // LocateRecord - Return pointer to key and data, and size of data.
56 // GetNodeDataSize - Return the amount of space used for data in the node.
57 // GetNodeFreeSize - Return the amount of free space in the node.
59 // GetRecordOffset - Return the offset for record "index".
60 // GetRecordAddress - Return address of record "index".
61 // GetOffsetAddress - Return address of offset for record "index".
63 // InsertOffset - Inserts a new offset into a node.
64 // DeleteOffset - Deletes an offset from a node.
66 // MoveRecordsLeft - Move records left within a node.
67 // MoveRecordsRight - Move records right within a node.
69 /////////////////////////////////////////////////////////////////////////////////
73 ////////////////////// Routines Internal To BTreeNodeOps.c //////////////////////
75 UInt16
GetRecordOffset (BTreeControlBlockPtr btree
,
79 UInt16
*GetOffsetAddress (BTreeControlBlockPtr btreePtr
,
83 void InsertOffset (BTreeControlBlockPtr btreePtr
,
88 void DeleteOffset (BTreeControlBlockPtr btreePtr
,
93 /////////////////////////////////////////////////////////////////////////////////
95 #define GetRecordOffset(btreePtr,node,index) (*(short *) ((UInt8 *)(node) + (btreePtr)->nodeSize - ((index) << 1) - kOffsetSize))
98 /*-------------------------------------------------------------------------------
100 Routine: GetNode - Call FS Agent to get node
102 Function: Gets an existing BTree node from FS Agent and verifies it.
104 Input: btreePtr - pointer to BTree control block
105 nodeNum - number of node to request
107 Output: nodePtr - pointer to beginning of node (nil if error)
112 -------------------------------------------------------------------------------*/
114 OSStatus
GetNode (BTreeControlBlockPtr btreePtr
,
119 GetBlockProcPtr getNodeProc
;
122 // LogStartTime(kTraceGetNode);
124 //¥¥ is nodeNum within proper range?
125 if( nodeNum
>= btreePtr
->totalNodes
)
127 Panic("\pGetNode:nodeNum >= totalNodes");
128 if (debug
) fprintf(stderr
, "%s(%d): nodeNum %u > totalNodes %u\n", __FUNCTION__
, __LINE__
, nodeNum
, btreePtr
->totalNodes
);
129 err
= fsBTInvalidNodeErr
;
133 getNodeProc
= btreePtr
->getBlockProc
;
134 err
= getNodeProc (btreePtr
->fcbPtr
,
141 Panic ("\pGetNode: getNodeProc returned error.");
142 nodePtr
->buffer
= nil
;
145 ++btreePtr
->numGetNodes
;
147 err
= hfs_swap_BTNode(nodePtr
, btreePtr
->fcbPtr
, kSwapBTNodeBigToHost
);
150 (void) TrashNode (btreePtr
, nodePtr
); // ignore error
154 // LogEndTime(kTraceGetNode, noErr);
159 nodePtr
->buffer
= nil
;
160 nodePtr
->blockHeader
= nil
;
162 // LogEndTime(kTraceGetNode, err);
169 /*-------------------------------------------------------------------------------
171 Routine: GetNewNode - Call FS Agent to get a new node
173 Function: Gets a new BTree node from FS Agent and initializes it to an empty
176 Input: btreePtr - pointer to BTree control block
177 nodeNum - number of node to request
179 Output: returnNodePtr - pointer to beginning of node (nil if error)
181 Result: noErr - success
183 -------------------------------------------------------------------------------*/
185 OSStatus
GetNewNode (BTreeControlBlockPtr btreePtr
,
187 NodeRec
*returnNodePtr
)
192 GetBlockProcPtr getNodeProc
;
195 //////////////////////// get buffer for new node ////////////////////////////
197 getNodeProc
= btreePtr
->getBlockProc
;
198 err
= getNodeProc (btreePtr
->fcbPtr
,
200 kGetBlock
+kGetEmptyBlock
,
205 Panic ("\pGetNewNode: getNodeProc returned error.");
206 returnNodePtr
->buffer
= nil
;
209 ++btreePtr
->numGetNewNodes
;
212 ////////////////////////// initialize the node //////////////////////////////
214 node
= returnNodePtr
->buffer
;
216 ClearNode (btreePtr
, node
); // clear the node
218 pos
= (char *)node
+ btreePtr
->nodeSize
- 2; // find address of last offset
219 *(UInt16
*)pos
= sizeof (BTNodeDescriptor
); // set offset to beginning of free space
227 /*-------------------------------------------------------------------------------
229 Routine: ReleaseNode - Call FS Agent to release node obtained by GetNode.
231 Function: Informs the FS Agent that a BTree node may be released.
233 Input: btreePtr - pointer to BTree control block
234 nodeNum - number of node to release
236 Result: noErr - success
238 -------------------------------------------------------------------------------*/
240 OSStatus
ReleaseNode (BTreeControlBlockPtr btreePtr
,
244 ReleaseBlockProcPtr releaseNodeProc
;
245 ReleaseBlockOptions options
= kReleaseBlock
;
247 // LogStartTime(kTraceReleaseNode);
251 if (nodePtr
->buffer
!= nil
)
254 * The nodes must remain in the cache as big endian!
256 err
= hfs_swap_BTNode(nodePtr
, btreePtr
->fcbPtr
, kSwapBTNodeHostToBig
);
259 options
|= kTrashBlock
;
262 releaseNodeProc
= btreePtr
->releaseBlockProc
;
263 err
= releaseNodeProc (btreePtr
->fcbPtr
,
266 PanicIf (err
, "\pReleaseNode: releaseNodeProc returned error.");
267 ++btreePtr
->numReleaseNodes
;
270 nodePtr
->buffer
= nil
;
271 nodePtr
->blockHeader
= nil
;
273 // LogEndTime(kTraceReleaseNode, err);
279 /*-------------------------------------------------------------------------------
281 Routine: TrashNode - Call FS Agent to release node obtained by GetNode, and
282 not store it...mark it as bad.
284 Function: Informs the FS Agent that a BTree node may be released and thrown away.
286 Input: btreePtr - pointer to BTree control block
287 nodeNum - number of node to release
289 Result: noErr - success
291 -------------------------------------------------------------------------------*/
293 OSStatus
TrashNode (BTreeControlBlockPtr btreePtr
,
297 ReleaseBlockProcPtr releaseNodeProc
;
302 if (nodePtr
->buffer
!= nil
)
304 releaseNodeProc
= btreePtr
->releaseBlockProc
;
305 err
= releaseNodeProc (btreePtr
->fcbPtr
,
307 kReleaseBlock
| kTrashBlock
);
308 PanicIf (err
, "\pTrashNode: releaseNodeProc returned error.");
309 ++btreePtr
->numReleaseNodes
;
312 nodePtr
->buffer
= nil
;
313 nodePtr
->blockHeader
= nil
;
319 /*-------------------------------------------------------------------------------
321 Routine: UpdateNode - Mark a node as dirty and call FS Agent to release it.
323 Function: Marks a BTree node dirty and informs the FS Agent that it may be released.
325 Input: btreePtr - pointer to BTree control block
326 nodeNum - number of node to release
328 Result: noErr - success
330 -------------------------------------------------------------------------------*/
332 OSStatus
UpdateNode (BTreeControlBlockPtr btreePtr
,
336 ReleaseBlockProcPtr releaseNodeProc
;
337 ReleaseBlockOptions options
= kMarkBlockDirty
;
341 if (nodePtr
->buffer
!= nil
) //¥¥ why call UpdateNode if nil ?!?
343 // LogStartTime(kTraceReleaseNode);
345 err
= hfs_swap_BTNode(nodePtr
, btreePtr
->fcbPtr
, kSwapBTNodeHostToBig
);
348 options
= kReleaseBlock
| kTrashBlock
;
351 releaseNodeProc
= btreePtr
->releaseBlockProc
;
352 err
= releaseNodeProc (btreePtr
->fcbPtr
,
356 // LogEndTime(kTraceReleaseNode, err);
359 ++btreePtr
->numUpdateNodes
;
362 nodePtr
->buffer
= nil
;
363 nodePtr
->blockHeader
= nil
;
374 /*-------------------------------------------------------------------------------
376 Routine: ClearNode - Clear a node to all zeroes.
378 Function: Writes zeroes from beginning of node for nodeSize bytes.
380 Input: btreePtr - pointer to BTree control block
381 node - pointer to node to clear
384 -------------------------------------------------------------------------------*/
386 void ClearNode (BTreeControlBlockPtr btreePtr
, NodeDescPtr node
)
388 ClearMemory( node
, btreePtr
->nodeSize
);
391 /*-------------------------------------------------------------------------------
393 Routine: InsertRecord - Inserts a record into a BTree node.
397 Note: Record size must be even!
399 Input: btreePtr - pointer to BTree control block
400 node - pointer to node to insert the record
401 index - position record is to be inserted
402 recPtr - pointer to record to insert
404 Result: noErr - success
405 fsBTFullErr - record larger than remaining free space.
406 -------------------------------------------------------------------------------*/
408 Boolean
InsertRecord (BTreeControlBlockPtr btreePtr
,
421 //// will new record fit in node?
423 freeSpace
= GetNodeFreeSize (btreePtr
, node
);
424 //¥¥ we could get freeOffset & calc freeSpace
425 if ( freeSpace
< recSize
+ 2)
431 //// make hole for new record
433 indexOffset
= GetRecordOffset (btreePtr
, node
, index
);
434 freeOffset
= GetRecordOffset (btreePtr
, node
, node
->numRecords
);
436 src
= ((Ptr
) node
) + indexOffset
;
437 dst
= ((Ptr
) src
) + recSize
;
438 bytesToMove
= freeOffset
- indexOffset
;
439 MoveRecordsRight (src
, dst
, bytesToMove
);
442 //// adjust offsets for moved records
444 InsertOffset (btreePtr
, node
, index
, recSize
);
447 //// move in the new record
449 dst
= ((Ptr
) node
) + indexOffset
;
450 MoveRecordsLeft (recPtr
, dst
, recSize
);
457 /*-------------------------------------------------------------------------------
459 Routine: InsertKeyRecord - Inserts a record into a BTree node.
463 Note: Record size must be even!
465 Input: btreePtr - pointer to BTree control block
466 node - pointer to node to insert the record
467 index - position record is to be inserted
468 keyPtr - pointer to key for record to insert
469 keyLength - length of key (or maxKeyLength)
470 recPtr - pointer to record to insert
471 recSize - number of bytes to copy for record
473 Result: noErr - success
474 fsBTFullErr - record larger than remaining free space.
475 -------------------------------------------------------------------------------*/
477 Boolean
InsertKeyRecord (BTreeControlBlockPtr btreePtr
,
495 //// calculate actual key size
497 if ( btreePtr
->attributes
& kBTBigKeysMask
)
498 keySize
= keyLength
+ sizeof(UInt16
);
500 keySize
= keyLength
+ sizeof(UInt8
);
502 if ( M_IsOdd (keySize
) )
503 ++keySize
; // add pad byte
506 //// will new record fit in node?
508 freeSpace
= GetNodeFreeSize (btreePtr
, node
);
509 //¥¥ we could get freeOffset & calc freeSpace
510 if ( freeSpace
< keySize
+ recSize
+ 2)
516 //// make hole for new record
518 indexOffset
= GetRecordOffset (btreePtr
, node
, index
);
519 freeOffset
= GetRecordOffset (btreePtr
, node
, node
->numRecords
);
521 src
= ((UInt8
*) node
) + indexOffset
;
522 dst
= ((UInt8
*) src
) + keySize
+ recSize
;
523 bytesToMove
= freeOffset
- indexOffset
;
524 MoveRecordsRight (src
, dst
, bytesToMove
);
527 //// adjust offsets for moved records
529 InsertOffset (btreePtr
, node
, index
, keySize
+ recSize
);
534 dst
= ((UInt8
*) node
) + indexOffset
;
536 if ( btreePtr
->attributes
& kBTBigKeysMask
)
538 *((UInt16
*)dst
) = keyLength
; // use keyLength rather than key.length
539 rawKeyLength
= keyPtr
->length16
;
544 *dst
= keyLength
; // use keyLength rather than key.length
545 rawKeyLength
= keyPtr
->length8
;
550 MoveRecordsLeft ( ((UInt8
*) keyPtr
) + sizeOfLength
, dst
, rawKeyLength
); // copy key
553 bytesToMove
= keySize
- rawKeyLength
;
555 ClearMemory (dst
+ rawKeyLength
, bytesToMove
); // clear pad bytes in index key
558 //// copy record data
560 dst
= ((UInt8
*) node
) + indexOffset
+ keySize
;
561 MoveRecordsLeft (recPtr
, dst
, recSize
);
568 /*-------------------------------------------------------------------------------
570 Routine: DeleteRecord - Deletes a record from a BTree node.
574 Input: btreePtr - pointer to BTree control block
575 node - pointer to node to insert the record
576 index - position record is to be inserted
579 -------------------------------------------------------------------------------*/
581 void DeleteRecord (BTreeControlBlockPtr btreePtr
,
592 //// compress records
593 indexOffset
= GetRecordOffset (btreePtr
, node
, index
);
594 nextOffset
= GetRecordOffset (btreePtr
, node
, index
+ 1);
595 freeOffset
= GetRecordOffset (btreePtr
, node
, node
->numRecords
);
597 src
= ((Ptr
) node
) + nextOffset
;
598 dst
= ((Ptr
) node
) + indexOffset
;
599 bytesToMove
= freeOffset
- nextOffset
;
600 MoveRecordsLeft (src
, dst
, bytesToMove
);
602 //// Adjust the offsets
603 DeleteOffset (btreePtr
, node
, index
);
608 /*-------------------------------------------------------------------------------
610 Routine: SearchNode - Return index for record that matches key.
612 Function: Returns the record index for the record that matches the search key.
613 If no record was found that matches the search key, the "insert index"
614 of where the record should go is returned instead.
616 Algorithm: A binary search algorithm is used to find the specified key.
618 Input: btreePtr - pointer to BTree control block
619 node - pointer to node that contains the record
620 searchKey - pointer to the key to match
622 Output: index - pointer to beginning of key for record
624 Result: true - success (index = record index)
625 false - key did not match anything in node (index = insert index)
626 -------------------------------------------------------------------------------*/
628 Boolean
SearchNode (BTreeControlBlockPtr btreePtr
,
631 UInt16
*returnIndex
)
638 #if !SupportsKeyDescriptors
639 KeyCompareProcPtr compareProc
= btreePtr
->keyCompareProc
;
643 upperBound
= node
->numRecords
- 1;
645 while (lowerBound
<= upperBound
)
647 index
= (lowerBound
+ upperBound
) >> 1; // divide by 2
649 trialKey
= (KeyPtr
) GetRecordAddress (btreePtr
, node
, index
);
651 #if SupportsKeyDescriptors
652 result
= CompareKeys (btreePtr
, searchKey
, trialKey
);
654 result
= compareProc(searchKey
, trialKey
);
657 if (result
< 0) upperBound
= index
- 1; // search < trial
658 else if (result
> 0) lowerBound
= index
+ 1; // search > trial
659 else // search = trial
661 *returnIndex
= index
;
666 *returnIndex
= lowerBound
; // lowerBound is insert index
671 /*-------------------------------------------------------------------------------
673 Routine: GetRecordByIndex - Return pointer to key and data, and size of data.
675 Function: Returns a pointer to beginning of key for record, a pointer to the
676 beginning of the data for the record, and the size of the record data
677 (does not include the size of the key).
679 Input: btreePtr - pointer to BTree control block
680 node - pointer to node that contains the record
681 index - index of record to get
683 Output: keyPtr - pointer to beginning of key for record
684 dataPtr - pointer to beginning of data for record
685 dataSize - size of the data portion of the record
688 -------------------------------------------------------------------------------*/
690 OSStatus
GetRecordByIndex (BTreeControlBlockPtr btreePtr
,
702 // Make sure index is valid (in range 0..numRecords-1)
704 if (index
>= node
->numRecords
)
705 return fsBTRecordNotFoundErr
;
708 offset
= GetRecordOffset (btreePtr
, node
, index
);
709 *keyPtr
= (KeyPtr
) ((Ptr
)node
+ offset
);
712 keySize
= CalcKeySize(btreePtr
, *keyPtr
);
713 if ( M_IsOdd (keySize
) )
714 ++keySize
; // add pad byte
716 offset
+= keySize
; // add the key length to find data offset
717 *dataPtr
= (UInt8
*) node
+ offset
;
720 nextOffset
= GetRecordOffset (btreePtr
, node
, index
+ 1);
721 *dataSize
= nextOffset
- offset
;
728 /*-------------------------------------------------------------------------------
730 Routine: GetNodeDataSize - Return the amount of space used for data in the node.
732 Function: Gets the size of the data currently contained in a node, excluding
733 the node header. (record data + offset overhead)
735 Input: btreePtr - pointer to BTree control block
736 node - pointer to node that contains the record
738 Result: - number of bytes used for data and offsets in the node.
739 -------------------------------------------------------------------------------*/
741 UInt16
GetNodeDataSize (BTreeControlBlockPtr btreePtr
, NodeDescPtr node
)
745 freeOffset
= GetRecordOffset (btreePtr
, node
, node
->numRecords
);
747 return freeOffset
+ (node
->numRecords
<< 1) - sizeof (BTNodeDescriptor
);
752 /*-------------------------------------------------------------------------------
754 Routine: GetNodeFreeSize - Return the amount of free space in the node.
758 Input: btreePtr - pointer to BTree control block
759 node - pointer to node that contains the record
761 Result: - number of bytes of free space in the node.
762 -------------------------------------------------------------------------------*/
764 UInt16
GetNodeFreeSize (BTreeControlBlockPtr btreePtr
, NodeDescPtr node
)
768 freeOffset
= GetRecordOffset (btreePtr
, node
, node
->numRecords
); //¥¥ inline?
770 return btreePtr
->nodeSize
- freeOffset
- (node
->numRecords
<< 1) - kOffsetSize
;
775 /*-------------------------------------------------------------------------------
777 Routine: GetRecordOffset - Return the offset for record "index".
781 Input: btreePtr - pointer to BTree control block
782 node - pointer to node that contains the record
783 index - record to obtain offset for
785 Result: - offset (in bytes) from beginning of node of record specified by index
786 -------------------------------------------------------------------------------*/
787 // make this a macro (for inlining)
789 UInt16
GetRecordOffset (BTreeControlBlockPtr btreePtr
,
796 pos
= (UInt8
*)node
+ btreePtr
->nodeSize
- (index
<< 1) - kOffsetSize
;
798 return *(short *)pos
;
804 /*-------------------------------------------------------------------------------
806 Routine: GetRecordAddress - Return address of record "index".
810 Input: btreePtr - pointer to BTree control block
811 node - pointer to node that contains the record
812 index - record to obtain offset address for
814 Result: - pointer to record "index".
815 -------------------------------------------------------------------------------*/
816 // make this a macro (for inlining)
818 UInt8
* GetRecordAddress (BTreeControlBlockPtr btreePtr
,
824 pos
= (UInt8
*)node
+ GetRecordOffset (btreePtr
, node
, index
);
832 /*-------------------------------------------------------------------------------
834 Routine: GetRecordSize - Return size of record "index".
838 Note: This does not work on the FreeSpace index!
840 Input: btreePtr - pointer to BTree control block
841 node - pointer to node that contains the record
842 index - record to obtain record size for
844 Result: - size of record "index".
845 -------------------------------------------------------------------------------*/
847 UInt16
GetRecordSize (BTreeControlBlockPtr btreePtr
,
853 pos
= (UInt16
*) ((Ptr
)node
+ btreePtr
->nodeSize
- (index
<< 1) - kOffsetSize
);
855 return *(pos
-1) - *pos
;
860 /*-------------------------------------------------------------------------------
861 Routine: GetOffsetAddress - Return address of offset for record "index".
865 Input: btreePtr - pointer to BTree control block
866 node - pointer to node that contains the record
867 index - record to obtain offset address for
869 Result: - pointer to offset for record "index".
870 -------------------------------------------------------------------------------*/
872 UInt16
*GetOffsetAddress (BTreeControlBlockPtr btreePtr
,
878 pos
= (Ptr
)node
+ btreePtr
->nodeSize
- (index
<< 1) -2;
880 return (UInt16
*)pos
;
885 /*-------------------------------------------------------------------------------
886 Routine: GetChildNodeNum - Return child node number from index record "index".
888 Function: Returns the first UInt32 stored after the key for record "index".
890 Assumes: The node is an Index Node.
891 The key.length stored at record "index" is ODD. //¥¥ change for variable length index keys
893 Input: btreePtr - pointer to BTree control block
894 node - pointer to node that contains the record
895 index - record to obtain child node number from
897 Result: - child node number from record "index".
898 -------------------------------------------------------------------------------*/
900 UInt32
GetChildNodeNum (BTreeControlBlockPtr btreePtr
,
906 pos
= GetRecordAddress (btreePtr
, nodePtr
, index
);
907 pos
+= CalcKeySize(btreePtr
, (BTreeKey
*) pos
); // key.length + size of length field
909 return *(UInt32
*)pos
;
914 /*-------------------------------------------------------------------------------
915 Routine: InsertOffset - Add an offset and adjust existing offsets by delta.
917 Function: Add an offset at 'index' by shifting 'index+1' through the last offset
918 and adjusting them by 'delta', the size of the record to be inserted.
919 The number of records contained in the node is also incremented.
921 Input: btreePtr - pointer to BTree control block
922 node - pointer to node
923 index - index at which to insert record
924 delta - size of record to be inserted
927 -------------------------------------------------------------------------------*/
929 void InsertOffset (BTreeControlBlockPtr btreePtr
,
937 src
= GetOffsetAddress (btreePtr
, node
, node
->numRecords
); // point to free offset
938 dst
= src
- 1; // point to new offset
939 numOffsets
= node
->numRecords
++ - index
; // subtract index & postincrement
942 *dst
++ = *src
++ + delta
; // to tricky?
943 } while (numOffsets
--);
948 /*-------------------------------------------------------------------------------
950 Routine: DeleteOffset - Delete an offset.
952 Function: Delete the offset at 'index' by shifting 'index+1' through the last offset
953 and adjusting them by the size of the record 'index'.
954 The number of records contained in the node is also decremented.
956 Input: btreePtr - pointer to BTree control block
957 node - pointer to node
958 index - index at which to delete record
961 -------------------------------------------------------------------------------*/
963 void DeleteOffset (BTreeControlBlockPtr btreePtr
,
971 dst
= GetOffsetAddress (btreePtr
, node
, index
);
974 numOffsets
= --node
->numRecords
- index
; // predecrement numRecords & subtract index
978 *--dst
= *--src
- delta
; // work our way left
984 /*-------------------------------------------------------------------------------
986 Routine: MoveRecordsLeft - Move records left within a node.
988 Function: Moves a number of bytes from src to dst. Safely handles overlapping
989 ranges if the bytes are being moved to the "left". No bytes are moved
990 if bytesToMove is zero.
992 Input: src - pointer to source
993 dst - pointer to destination
994 bytesToMove - number of bytes to move records
997 -------------------------------------------------------------------------------*/
999 void MoveRecordsLeft (UInt8
* src
,
1001 UInt16 bytesToMove
)
1003 while (bytesToMove
--)
1009 /*-------------------------------------------------------------------------------
1011 Routine: MoveRecordsRight - Move records right within a node.
1013 Function: Moves a number of bytes from src to dst. Safely handles overlapping
1014 ranges if the bytes are being moved to the "right". No bytes are moved
1015 if bytesToMove is zero.
1017 Input: src - pointer to source
1018 dst - pointer to destination
1019 bytesToMove - number of bytes to move records
1022 -------------------------------------------------------------------------------*/
1024 void MoveRecordsRight (UInt8
* src
,
1026 UInt16 bytesToMove
)
1031 while (bytesToMove
--)