~ubuntu-branches/ubuntu/trusty/hfsprogs/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/91-remove-nils.patch/fsck_hfs.tproj/dfalib/BTreeMiscOps.c

  • Committer: Package Import Robot
  • Author(s): Rogério Brito
  • Date: 2013-10-24 01:20:15 UTC
  • Revision ID: package-import@ubuntu.com-20131024012015-qsncxmr4cielybvz
Tags: 332.25-11
* debian/control: Remove DMUA flag.
* debian/rules: Override rules for which we don't have makefiles.
  (Closes: #724195)
* debian/patches:
  + Change the headers to be friendlier with gbp pq.
  + Remove unreferenced patches in series file.
  + Coalesce all patches touching man pages into one.
  + Regenerate everything from patch-queue branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3
 
 *
4
 
 * @APPLE_LICENSE_HEADER_START@
5
 
 * 
6
 
 * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
7
 
 * Reserved.  This file contains Original Code and/or Modifications of
8
 
 * Original Code as defined in and that are subject to the Apple Public
9
 
 * Source License Version 1.0 (the 'License').  You may not use this file
10
 
 * except in compliance with the License.  Please obtain a copy of the
11
 
 * License at http://www.apple.com/publicsource and read it before using
12
 
 * this file.
13
 
 * 
14
 
 * The Original Code and all software distributed under the License are
15
 
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16
 
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17
 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18
 
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
19
 
 * License for the specific language governing rights and limitations
20
 
 * under the License."
21
 
 * 
22
 
 * @APPLE_LICENSE_HEADER_END@
23
 
 */
24
 
/*
25
 
        File:           BTreeMiscOps.c
26
 
 
27
 
        Contains:       Miscellaneous operations for the BTree Module.
28
 
 
29
 
        Version:        xxx put the technology version here xxx
30
 
 
31
 
        Written by:     Gordon Sheridan and Bill Bruffey
32
 
 
33
 
        Copyright:      � 1992-1999 by Apple Computer, Inc., all rights reserved.
34
 
*/
35
 
 
36
 
#include "BTreePrivate.h"
37
 
 
38
 
 
39
 
////////////////////////////// Routine Definitions //////////////////////////////
40
 
 
41
 
/*-------------------------------------------------------------------------------
42
 
Routine:        CalcKeyRecordSize       -       Return size of combined key/record structure.
43
 
 
44
 
Function:       Rounds keySize and recSize so they will end on word boundaries.
45
 
                        Does NOT add size of offset.
46
 
 
47
 
Input:          keySize         - length of key (including length field)
48
 
                        recSize         - length of record data
49
 
 
50
 
Output:         none
51
 
                        
52
 
Result:         UInt16          - size of combined key/record that will be inserted in btree
53
 
-------------------------------------------------------------------------------*/
54
 
 
55
 
UInt16          CalcKeyRecordSize               (UInt16                                  keySize,
56
 
                                                                         UInt16                                  recSize )
57
 
{
58
 
        if ( M_IsOdd (keySize) )        keySize += 1;   // pad byte
59
 
        
60
 
        if (M_IsOdd (recSize) )         recSize += 1;   // pad byte
61
 
        
62
 
        return  (keySize + recSize);
63
 
}
64
 
 
65
 
 
66
 
 
67
 
/*-------------------------------------------------------------------------------
68
 
Routine:        VerifyHeader    -       Validate fields of the BTree header record.
69
 
 
70
 
Function:       Examines the fields of the BTree header record to determine if the
71
 
                        fork appears to contain a valid BTree.
72
 
                        
73
 
Input:          forkPtr         - pointer to fork control block
74
 
                        header          - pointer to BTree header
75
 
                        
76
 
                        
77
 
Result:         noErr           - success
78
 
                        != noErr        - failure
79
 
-------------------------------------------------------------------------------*/
80
 
 
81
 
OSStatus        VerifyHeader    (SFCB                           *filePtr,
82
 
                                                         BTHeaderRec            *header )
83
 
{
84
 
        UInt32          forkSize;
85
 
        UInt32          totalNodes;
86
 
        
87
 
 
88
 
        switch (header->nodeSize)                                                       // node size == 512*2^n
89
 
        {
90
 
                case   512:
91
 
                case  1024:
92
 
                case  2048:
93
 
                case  4096:
94
 
                case  8192:
95
 
                case 16384:
96
 
                case 32768:             break;
97
 
                default:                return  fsBTInvalidHeaderErr;                   //�� E_BadNodeType
98
 
        }
99
 
        
100
 
        totalNodes = header->totalNodes;
101
 
 
102
 
        forkSize = totalNodes * header->nodeSize;
103
 
        
104
 
        if ( forkSize != filePtr->fcbLogicalSize )
105
 
                return fsBTInvalidHeaderErr;
106
 
        
107
 
        if ( header->freeNodes >= totalNodes )
108
 
                return fsBTInvalidHeaderErr;
109
 
        
110
 
        if ( header->rootNode >= totalNodes )
111
 
                return fsBTInvalidHeaderErr;
112
 
        
113
 
        if ( header->firstLeafNode >= totalNodes )
114
 
                return fsBTInvalidHeaderErr;
115
 
        
116
 
        if ( header->lastLeafNode >= totalNodes )
117
 
                return fsBTInvalidHeaderErr;
118
 
        
119
 
        if ( header->treeDepth > kMaxTreeDepth )
120
 
                return fsBTInvalidHeaderErr;
121
 
 
122
 
 
123
 
        /////////////////////////// Check BTree Type ////////////////////////////////
124
 
        
125
 
        switch (header->btreeType)
126
 
        {
127
 
                case    0:                                      // HFS Type - no Key Descriptor
128
 
                case    kUserBTreeType:         // with Key Descriptors etc.
129
 
                case    kReservedBTreeType:     // Desktop Mgr BTree ?
130
 
                                                                        break;
131
 
 
132
 
                default:                                        return fsBTUnknownVersionErr;           
133
 
        }
134
 
        
135
 
        return noErr;
136
 
}
137
 
 
138
 
 
139
 
 
140
 
/*-------------------------------------------------------------------------------
141
 
Routine:        UpdateHeader    -       Write BTreeInfoRec fields to Header node.
142
 
 
143
 
Function:       Checks the kBTHeaderDirty flag in the BTreeInfoRec and updates the
144
 
                        header node if necessary.
145
 
                        
146
 
Input:          btreePtr                - pointer to BTreeInfoRec
147
 
                        
148
 
                        
149
 
Result:         noErr           - success
150
 
                        != noErr        - failure
151
 
-------------------------------------------------------------------------------*/
152
 
 
153
 
OSStatus        UpdateHeader    (BTreeControlBlockPtr           btreePtr)
154
 
{
155
 
        OSStatus                                err;
156
 
        BlockDescriptor                 node;
157
 
        BTHeaderRec                             *header;        
158
 
 
159
 
        
160
 
        if ((btreePtr->flags & kBTHeaderDirty) == 0)                    // btree info already flushed
161
 
        return  noErr;
162
 
        
163
 
        
164
 
        err = GetNode (btreePtr, kHeaderNodeNum, &node );
165
 
        if (err != noErr)
166
 
                return  err;
167
 
        
168
 
        header = (BTHeaderRec*) (node.buffer + sizeof(BTNodeDescriptor));
169
 
        
170
 
        header->treeDepth               = btreePtr->treeDepth;
171
 
        header->rootNode                = btreePtr->rootNode;
172
 
        header->leafRecords             = btreePtr->leafRecords;
173
 
        header->firstLeafNode   = btreePtr->firstLeafNode;
174
 
        header->lastLeafNode    = btreePtr->lastLeafNode;
175
 
        header->nodeSize                = btreePtr->nodeSize;                   //�� this shouldn't change
176
 
        header->maxKeyLength    = btreePtr->maxKeyLength;               //�� neither should this
177
 
        header->totalNodes              = btreePtr->totalNodes;
178
 
        header->freeNodes               = btreePtr->freeNodes;
179
 
        header->btreeType               = btreePtr->btreeType;
180
 
 
181
 
        // ignore       header->clumpSize;                                                      //�� rename this field?
182
 
 
183
 
        err = UpdateNode (btreePtr, &node);
184
 
 
185
 
        btreePtr->flags &= (~kBTHeaderDirty);
186
 
 
187
 
        return  err;
188
 
}
189
 
 
190
 
 
191
 
 
192
 
/*-------------------------------------------------------------------------------
193
 
Routine:        FindIteratorPosition    -       One_line_description.
194
 
 
195
 
Function:       Brief_description_of_the_function_and_any_side_effects
196
 
 
197
 
Algorithm:      see FSC.BT.BTIterateRecord.PICT
198
 
 
199
 
Note:           //�� document side-effects of bad node hints
200
 
 
201
 
Input:          btreePtr                - description
202
 
                        iterator                - description
203
 
                        
204
 
 
205
 
Output:         iterator                - description
206
 
                        left                    - description
207
 
                        middle                  - description
208
 
                        right                   - description
209
 
                        nodeNum                 - description
210
 
                        returnIndex             - description
211
 
                        foundRecord             - description
212
 
                        
213
 
                        
214
 
Result:         noErr           - success
215
 
                        != noErr        - failure
216
 
-------------------------------------------------------------------------------*/
217
 
 
218
 
OSStatus        FindIteratorPosition    (BTreeControlBlockPtr    btreePtr,
219
 
                                                                         BTreeIteratorPtr                iterator,
220
 
                                                                         BlockDescriptor                *left,
221
 
                                                                         BlockDescriptor                *middle,
222
 
                                                                         BlockDescriptor                *right,
223
 
                                                                         UInt32                                 *returnNodeNum,
224
 
                                                                         UInt16                                 *returnIndex,
225
 
                                                                         Boolean                                *foundRecord )
226
 
{
227
 
        OSStatus                err;
228
 
        Boolean                 foundIt;
229
 
        UInt32                  nodeNum;
230
 
        UInt16                  leftIndex,      index,  rightIndex;
231
 
        Boolean                 validHint;
232
 
 
233
 
        // assume btreePtr valid
234
 
        // assume left, middle, right point to BlockDescriptors
235
 
        // assume nodeNum points to UInt32
236
 
        // assume index points to UInt16
237
 
        // assume foundRecord points to Boolean
238
 
        
239
 
        left->buffer            = nil;
240
 
        middle->buffer          = nil;
241
 
        right->buffer           = nil;
242
 
        
243
 
        foundIt                         = false;
244
 
        
245
 
        if (iterator == nil)                                            // do we have an iterator?
246
 
        {
247
 
                err = fsBTInvalidIteratorErr;
248
 
                goto ErrorExit;
249
 
        }
250
 
 
251
 
#if SupportsKeyDescriptors
252
 
        //�� verify iterator key (change CheckKey to take btreePtr instead of keyDescPtr?)
253
 
        if (btreePtr->keyDescPtr != nil)
254
 
        {
255
 
                err = CheckKey (&iterator->key, btreePtr->keyDescPtr, btreePtr->maxKeyLength );
256
 
                M_ExitOnError (err);
257
 
        }
258
 
#endif
259
 
 
260
 
        err = IsItAHint (btreePtr, iterator, &validHint);
261
 
        M_ExitOnError (err);
262
 
 
263
 
        nodeNum = iterator->hint.nodeNum;
264
 
        if (! validHint)                                                        // does the hint appear to be valid?
265
 
        {
266
 
                goto SearchTheTree;
267
 
        }
268
 
        
269
 
        err = GetNode (btreePtr, nodeNum, middle);
270
 
        if( err == fsBTInvalidNodeErr ) // returned if nodeNum is out of range
271
 
                goto SearchTheTree;
272
 
                
273
 
        M_ExitOnError (err);
274
 
        
275
 
        if ( ((NodeDescPtr) middle->buffer)->kind               !=      kBTLeafNode ||
276
 
                 ((NodeDescPtr) middle->buffer)->numRecords     <=  0 )
277
 
        {       
278
 
                goto SearchTheTree;
279
 
        }
280
 
                
281
 
        ++btreePtr->numValidHints;
282
 
        
283
 
        foundIt = SearchNode (btreePtr, middle->buffer, &iterator->key, &index);
284
 
        if (foundIt == true)
285
 
        {
286
 
                goto SuccessfulExit;
287
 
        }
288
 
        
289
 
        if (index == 0)
290
 
        {
291
 
                if (((NodeDescPtr) middle->buffer)->bLink == 0)         // before 1st btree record
292
 
                {
293
 
                        goto SuccessfulExit;
294
 
                }
295
 
                
296
 
                nodeNum = ((NodeDescPtr) middle->buffer)->bLink;
297
 
                
298
 
                err = GetLeftSiblingNode (btreePtr, middle->buffer, left);
299
 
                M_ExitOnError (err);
300
 
                
301
 
                if ( ((NodeDescPtr) left->buffer)->kind                 !=      kBTLeafNode ||
302
 
                         ((NodeDescPtr) left->buffer)->numRecords       <=  0 )
303
 
                {       
304
 
                        goto SearchTheTree;
305
 
                }
306
 
                
307
 
                foundIt = SearchNode (btreePtr, left->buffer, &iterator->key, &leftIndex);
308
 
                if (foundIt == true)
309
 
                {
310
 
                        *right                  = *middle;
311
 
                        *middle                 = *left;
312
 
                        left->buffer    = nil;
313
 
                        index                   = leftIndex;
314
 
                        
315
 
                        goto SuccessfulExit;
316
 
                }
317
 
                
318
 
                if (leftIndex == 0)                                                                     // we're lost!
319
 
                {
320
 
                        goto SearchTheTree;
321
 
                }
322
 
                else if (leftIndex >= ((NodeDescPtr) left->buffer)->numRecords)
323
 
                {
324
 
                        nodeNum = ((NodeDescPtr) left->buffer)->fLink;
325
 
                        
326
 
                        PanicIf (index != 0, "\pFindIteratorPosition: index != 0");     //�� just checking...
327
 
                        goto SuccessfulExit;
328
 
                }
329
 
                else
330
 
                {
331
 
                        *right                  = *middle;
332
 
                        *middle                 = *left;
333
 
                        left->buffer    = nil;
334
 
                        index                   = leftIndex;
335
 
                        
336
 
                        goto SuccessfulExit;
337
 
                }
338
 
        }
339
 
        else if (index >= ((NodeDescPtr) middle->buffer)->numRecords)
340
 
        {
341
 
                if (((NodeDescPtr) middle->buffer)->fLink == 0) // beyond last record
342
 
                {
343
 
                        goto SuccessfulExit;
344
 
                }
345
 
                
346
 
                nodeNum = ((NodeDescPtr) middle->buffer)->fLink;
347
 
                
348
 
                err = GetRightSiblingNode (btreePtr, middle->buffer, right);
349
 
                M_ExitOnError (err);
350
 
                
351
 
                if ( ((NodeDescPtr) right->buffer)->kind                != kBTLeafNode ||
352
 
                         ((NodeDescPtr) right->buffer)->numRecords      <=  0 )
353
 
                {       
354
 
                        goto SearchTheTree;
355
 
                }
356
 
 
357
 
                foundIt = SearchNode (btreePtr, right->buffer, &iterator->key, &rightIndex);
358
 
                if (rightIndex >= ((NodeDescPtr) right->buffer)->numRecords)            // we're lost
359
 
                {
360
 
                        goto SearchTheTree;
361
 
                }
362
 
                else    // we found it, or rightIndex==0, or rightIndex<numRecs
363
 
                {
364
 
                        *left                   = *middle;
365
 
                        *middle                 = *right;
366
 
                        right->buffer   = nil;
367
 
                        index                   = rightIndex;
368
 
                        
369
 
                        goto SuccessfulExit;
370
 
                }
371
 
        }
372
 
 
373
 
        
374
 
        //////////////////////////// Search The Tree ////////////////////////////////   
375
 
 
376
 
SearchTheTree:
377
 
        {
378
 
                TreePathTable   treePathTable;          // so we only use stack space if we need to
379
 
 
380
 
                err = ReleaseNode (btreePtr, left);                     M_ExitOnError (err);
381
 
                err = ReleaseNode (btreePtr, middle);           M_ExitOnError (err);
382
 
                err = ReleaseNode (btreePtr, right);            M_ExitOnError (err);
383
 
        
384
 
                err = SearchTree ( btreePtr, &iterator->key, treePathTable, &nodeNum, middle, &index);
385
 
                switch (err)                            //�� separate find condition from exceptions
386
 
                {
387
 
                        case noErr:                     foundIt = true;                         break;
388
 
                        case fsBTRecordNotFoundErr:                                             break;
389
 
                        default:                                goto ErrorExit;
390
 
                }
391
 
        }
392
 
 
393
 
        /////////////////////////////// Success! ////////////////////////////////////
394
 
 
395
 
SuccessfulExit:
396
 
        
397
 
        *returnNodeNum  = nodeNum;
398
 
        *returnIndex    = index;
399
 
        *foundRecord    = foundIt;
400
 
        
401
 
        return  noErr;
402
 
        
403
 
        
404
 
        ////////////////////////////// Error Exit ///////////////////////////////////
405
 
 
406
 
ErrorExit:
407
 
 
408
 
        (void)  ReleaseNode (btreePtr, left);
409
 
        (void)  ReleaseNode (btreePtr, middle);
410
 
        (void)  ReleaseNode (btreePtr, right);
411
 
 
412
 
        *returnNodeNum  = 0;
413
 
        *returnIndex    = 0;
414
 
        *foundRecord    = false;
415
 
 
416
 
        return  err;
417
 
}
418
 
 
419
 
 
420
 
 
421
 
/////////////////////////////// CheckInsertParams ///////////////////////////////
422
 
 
423
 
OSStatus        CheckInsertParams               (SFCB                                           *filePtr,
424
 
                                                                         BTreeIterator                          *iterator,
425
 
                                                                         FSBufferDescriptor                     *record,
426
 
                                                                         UInt16                                          recordLen )
427
 
{
428
 
        BTreeControlBlockPtr    btreePtr;
429
 
        
430
 
        if (filePtr == nil)                                                                     return  paramErr;
431
 
 
432
 
        btreePtr = (BTreeControlBlockPtr) filePtr->fcbBtree;
433
 
        if (btreePtr == nil)                                                            return  fsBTInvalidFileErr;
434
 
        if (iterator == nil)                                                            return  paramErr;
435
 
        if (record       == nil)                                                                return  paramErr;
436
 
        
437
 
#if SupportsKeyDescriptors
438
 
        if (btreePtr->keyDescPtr != nil)
439
 
        {
440
 
                OSStatus        err;
441
 
 
442
 
                err = CheckKey (&iterator->key, btreePtr->keyDescPtr, btreePtr->maxKeyLength);
443
 
                if (err != noErr)
444
 
                        return  err;
445
 
        }
446
 
#endif
447
 
 
448
 
        //      check total key/record size limit
449
 
        if ( CalcKeyRecordSize (CalcKeySize(btreePtr, &iterator->key), recordLen) > (btreePtr->nodeSize >> 1))
450
 
                return  fsBTRecordTooLargeErr;
451
 
        
452
 
        return  noErr;
453
 
}
454
 
 
455
 
 
456
 
 
457
 
/*-------------------------------------------------------------------------------
458
 
Routine:        TrySimpleReplace        -       Attempts a simple insert, set, or replace.
459
 
 
460
 
Function:       If a hint exitst for the iterator, attempt to find the key in the hint
461
 
                        node. If the key is found, an insert operation fails. If the is not
462
 
                        found, a replace operation fails. If the key was not found, and the
463
 
                        insert position is greater than 0 and less than numRecords, the record
464
 
                        is inserted, provided there is enough freeSpace.  If the key was found,
465
 
                        and there is more freeSpace than the difference between the new record
466
 
                        and the old record, the old record is deleted and the new record is
467
 
                        inserted.
468
 
 
469
 
Assumptions:    iterator key has already been checked by CheckKey
470
 
 
471
 
 
472
 
Input:          btreePtr                - description
473
 
                        iterator                - description
474
 
                        record                  - description
475
 
                        recordLen               - description
476
 
                        operation               - description
477
 
                        
478
 
 
479
 
Output:         recordInserted          - description
480
 
                        
481
 
                                                
482
 
Result:         noErr                   - success
483
 
                        E_RecordExits           - insert operation failure
484
 
                        != noErr                - GetNode, ReleaseNode, UpdateNode returned an error
485
 
-------------------------------------------------------------------------------*/
486
 
 
487
 
OSStatus        TrySimpleReplace                (BTreeControlBlockPtr    btreePtr,
488
 
                                                                         NodeDescPtr                     nodePtr,
489
 
                                                                         BTreeIterator                  *iterator,
490
 
                                                                         FSBufferDescriptor             *record,
491
 
                                                                         UInt16                                  recordLen,
492
 
                                                                         Boolean                                *recordInserted )
493
 
{
494
 
        UInt32                          oldSpace;
495
 
        UInt32                          spaceNeeded;
496
 
        UInt16                          index;
497
 
        UInt16                          keySize;
498
 
        Boolean                         foundIt;
499
 
        Boolean                         didItFit;
500
 
        
501
 
        
502
 
        *recordInserted = false;                                                                // we'll assume this won't work...
503
 
        
504
 
        if ( nodePtr->kind != kBTLeafNode )
505
 
                return  noErr;  // we're in the weeds!
506
 
 
507
 
        foundIt = SearchNode (btreePtr, nodePtr, &iterator->key, &index);       
508
 
 
509
 
        if ( foundIt == false )
510
 
                return  noErr;  // we might be lost...
511
 
                
512
 
        keySize = CalcKeySize(btreePtr, &iterator->key);        // includes length field
513
 
        
514
 
        spaceNeeded     = CalcKeyRecordSize (keySize, recordLen);
515
 
        
516
 
        oldSpace = GetRecordSize (btreePtr, nodePtr, index);
517
 
        
518
 
        if ( spaceNeeded == oldSpace )
519
 
        {
520
 
                UInt8 *         dst;
521
 
 
522
 
                dst = GetRecordAddress (btreePtr, nodePtr, index);
523
 
 
524
 
                if ( M_IsOdd (keySize) )
525
 
                        ++keySize;                      // add pad byte
526
 
                
527
 
                dst += keySize;         // skip over key to point at record
528
 
 
529
 
                CopyMemory(record->bufferAddress, dst, recordLen);      // blast away...
530
 
 
531
 
                *recordInserted = true;
532
 
        }
533
 
        else if ( (GetNodeFreeSize(btreePtr, nodePtr) + oldSpace) >= spaceNeeded)
534
 
        {
535
 
                DeleteRecord (btreePtr, nodePtr, index);
536
 
        
537
 
                didItFit = InsertKeyRecord (btreePtr, nodePtr, index,
538
 
                                                                                &iterator->key, KeyLength(btreePtr, &iterator->key),
539
 
                                                                                record->bufferAddress, recordLen);
540
 
                PanicIf (didItFit == false, "\pTrySimpleInsert: InsertKeyRecord returned false!");
541
 
 
542
 
                *recordInserted = true;
543
 
        }
544
 
        // else not enough space...
545
 
 
546
 
        return  noErr;
547
 
}
548
 
 
549
 
 
550
 
/*-------------------------------------------------------------------------------
551
 
Routine:        IsItAHint       -       checks the hint within a BTreeInterator.
552
 
 
553
 
Function:       checks the hint within a BTreeInterator.  If it is non-zero, it may 
554
 
                        possibly be valid. 
555
 
 
556
 
Input:          btreePtr        - pointer to control block for BTree file
557
 
                        iterator        - pointer to BTreeIterator
558
 
                        
559
 
Output:         answer          - true if the hint looks reasonable
560
 
                                                - false if the hint is 0
561
 
                        
562
 
Result:         noErr                   - success
563
 
-------------------------------------------------------------------------------*/
564
 
 
565
 
 
566
 
OSStatus        IsItAHint       (BTreeControlBlockPtr btreePtr, BTreeIterator *iterator, Boolean *answer)
567
 
{
568
 
        ++btreePtr->numHintChecks;
569
 
        
570
 
        //�� shouldn't we do a range check?
571
 
        if (iterator->hint.nodeNum == 0)
572
 
        {
573
 
                *answer = false;
574
 
        }
575
 
        else
576
 
        {
577
 
                *answer = true;
578
 
                ++btreePtr->numPossibleHints;
579
 
        }
580
 
        
581
 
        return noErr;
582
 
}