/*
 * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
 *
 * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
 * the terms of the APSL version 2.0 (see below).
 *
 * For information about changes from the original Apple source release can be found by reviewing the
 * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
 *
 * The original license information is as follows:
 * 
 * Copyright (c) 2008 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*	CFBitVector.c
	Copyright 1998-2002, Apple, Inc. All rights reserved.
	Responsibility: Christopher Kane
*/

#include <CoreFoundation/CFBitVector.h>
#include "CFInternal.h"
#include <string.h>

/* The bucket type must be unsigned, at least one byte in size, and
   a power of 2 in number of bits; bits are numbered from 0 from left
   to right (bit 0 is the most significant) */
typedef uint8_t __CFBitVectorBucket;

enum {
    __CF_BITS_PER_BYTE = 8
};

enum {
    __CF_BITS_PER_BUCKET = (__CF_BITS_PER_BYTE * sizeof(__CFBitVectorBucket))
};

CF_INLINE CFIndex __CFBitVectorRoundUpCapacity(CFIndex capacity) {
    return ((capacity + 63) / 64) * 64;
}

CF_INLINE CFIndex __CFBitVectorNumBucketsForCapacity(CFIndex capacity) {
    return (capacity + __CF_BITS_PER_BUCKET - 1) / __CF_BITS_PER_BUCKET;
}

struct __CFBitVector {
    CFRuntimeBase _base;
    CFIndex _count;	/* number of bits */
    CFIndex _capacity;	/* maximum number of bits */
    __CFBitVectorBucket *_buckets;
};

CF_INLINE UInt32 __CFBitVectorMutableVariety(const void *cf) {
    return __CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2);
}

CF_INLINE void __CFBitVectorSetMutableVariety(void *cf, UInt32 v) {
    __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2, v);
}

CF_INLINE UInt32 __CFBitVectorMutableVarietyFromFlags(UInt32 flags) {
    return __CFBitfieldGetValue(flags, 1, 0);
}

// ensure that uses of these inlines are correct, bytes vs. buckets vs. bits
CF_INLINE CFIndex __CFBitVectorCount(CFBitVectorRef bv) {
    return bv->_count;
}

CF_INLINE void __CFBitVectorSetCount(CFMutableBitVectorRef bv, CFIndex v) {
    bv->_count = v;
}

CF_INLINE CFIndex __CFBitVectorCapacity(CFBitVectorRef bv) {
    return bv->_capacity;
}

CF_INLINE void __CFBitVectorSetCapacity(CFMutableBitVectorRef bv, CFIndex v) {
    bv->_capacity = v;
}

CF_INLINE CFIndex __CFBitVectorNumBucketsUsed(CFBitVectorRef bv) {
    return bv->_count / __CF_BITS_PER_BUCKET + 1;
}

CF_INLINE void __CFBitVectorSetNumBucketsUsed(CFMutableBitVectorRef bv, CFIndex v) {
    /* for a CFBitVector, _bucketsUsed == _count / __CF_BITS_PER_BUCKET + 1 */
}

CF_INLINE CFIndex __CFBitVectorNumBuckets(CFBitVectorRef bv) {
    return bv->_capacity / __CF_BITS_PER_BUCKET + 1;
}

CF_INLINE void __CFBitVectorSetNumBuckets(CFMutableBitVectorRef bv, CFIndex v) {
    /* for a CFBitVector, _bucketsNum == _capacity / __CF_BITS_PER_BUCKET + 1 */
}

static __CFBitVectorBucket __CFBitBucketMask(CFIndex bottomBit, CFIndex topBit) {
    CFIndex shiftL = __CF_BITS_PER_BUCKET - topBit + bottomBit - 1;
    __CFBitVectorBucket result = ~(__CFBitVectorBucket)0;
    result = (result << shiftL);
    result = (result >> bottomBit);
    return result;
}

CF_INLINE CFBit __CFBitVectorBit(__CFBitVectorBucket *buckets, CFIndex idx) {
    CFIndex bucketIdx = idx / __CF_BITS_PER_BUCKET;
    CFIndex bitOfBucket = idx & (__CF_BITS_PER_BUCKET - 1);
    return (buckets[bucketIdx] >> (__CF_BITS_PER_BUCKET - 1 - bitOfBucket)) & 0x1;
}

CF_INLINE void __CFSetBitVectorBit(__CFBitVectorBucket *buckets, CFIndex idx, CFBit value) {
    CFIndex bucketIdx = idx / __CF_BITS_PER_BUCKET;
    CFIndex bitOfBucket = idx & (__CF_BITS_PER_BUCKET - 1);
    if (value) {
	buckets[bucketIdx] |= (1 << (__CF_BITS_PER_BUCKET - 1 - bitOfBucket));
    } else {
	buckets[bucketIdx] &= ~(1 << (__CF_BITS_PER_BUCKET - 1 - bitOfBucket));
    }
}

CF_INLINE void __CFFlipBitVectorBit(__CFBitVectorBucket *buckets, CFIndex idx) {
    CFIndex bucketIdx = idx / __CF_BITS_PER_BUCKET;
    CFIndex bitOfBucket = idx & (__CF_BITS_PER_BUCKET - 1);
    buckets[bucketIdx] ^= (1 << (__CF_BITS_PER_BUCKET - 1 - bitOfBucket));
}

#if defined(DEBUG)
CF_INLINE void __CFBitVectorValidateRange(CFBitVectorRef bv, CFRange range, const char *func) {
    CFAssert2(0 <= range.location && range.location < __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): range.location index (%d) out of bounds", func, range.location);
    CFAssert2(0 <= range.length, __kCFLogAssertion, "%s(): range.length (%d) cannot be less than zero", func, range.length);
    CFAssert2(range.location + range.length <= __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): ending index (%d) out of bounds", func, range.location + range.length);
}
#else
#define __CFBitVectorValidateRange(bf,r,f)
#endif

static Boolean __CFBitVectorEqual(CFTypeRef cf1, CFTypeRef cf2) {
    CFBitVectorRef bv1 = (CFBitVectorRef)cf1;
    CFBitVectorRef bv2 = (CFBitVectorRef)cf2;
    CFIndex idx, cnt;
    cnt = __CFBitVectorCount(bv1);
    if (cnt != __CFBitVectorCount(bv2)) return false;
    if (0 == cnt) return true;
    for (idx = 0; idx < (cnt / __CF_BITS_PER_BUCKET) + 1; idx++) {
	__CFBitVectorBucket val1 = bv1->_buckets[idx];
	__CFBitVectorBucket val2 = bv2->_buckets[idx];
	if (val1 != val2) return false;
    }
    return true;
}

static CFHashCode __CFBitVectorHash(CFTypeRef cf) {
    CFBitVectorRef bv = (CFBitVectorRef)cf;
    return __CFBitVectorCount(bv);
}

static CFStringRef __CFBitVectorCopyDescription(CFTypeRef cf) {
    CFBitVectorRef bv = (CFBitVectorRef)cf;
    CFMutableStringRef result;
    CFIndex idx, cnt;
    __CFBitVectorBucket *buckets;
    cnt = __CFBitVectorCount(bv);
    buckets = bv->_buckets;
    result = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
    CFStringAppendFormat(result, NULL, CFSTR("<CFBitVector %p [%p]>{count = %u, capacity = %u, objects = (\n"), cf, CFGetAllocator(bv), cnt, __CFBitVectorCapacity(bv));
    for (idx = 0; idx < (cnt / 64); idx++) {	/* Print groups of 64 */
	CFIndex idx2;
	CFStringAppendFormat(result, NULL, CFSTR("\t%u : "), (idx * 64));
	for (idx2 = 0; idx2 < 64; idx2 += 4) {
	    CFIndex bucketIdx = (idx << 6) + idx2;
	    CFStringAppendFormat(result, NULL, CFSTR("%d%d%d%d"),
		__CFBitVectorBit(buckets, bucketIdx + 0),
		__CFBitVectorBit(buckets, bucketIdx + 1),
		__CFBitVectorBit(buckets, bucketIdx + 2),
		__CFBitVectorBit(buckets, bucketIdx + 3));
	}
	CFStringAppend(result, CFSTR("\n"));
    }
    if (idx * 64 < cnt) {
	CFStringAppendFormat(result, NULL, CFSTR("\t%u : "), (idx * 64));
	for (idx = (idx * 64); idx < cnt; idx++) {	/* Print remainder */
	    CFStringAppendFormat(result, NULL, CFSTR("%d"), __CFBitVectorBit(buckets, idx));
	}
    }
    CFStringAppend(result, CFSTR("\n)}"));
    return result;
}

enum {
    kCFBitVectorImmutable = 0x0,		/* unchangable and fixed capacity; default */
    kCFBitVectorMutable = 0x1,		/* changeable and variable capacity */
    kCFBitVectorFixedMutable = 0x3	/* changeable and fixed capacity */
};

static void __CFBitVectorDeallocate(CFTypeRef cf) {
    CFMutableBitVectorRef bv = (CFMutableBitVectorRef)cf;
    CFAllocatorRef allocator = CFGetAllocator(bv);
    if (__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable) {
	_CFAllocatorDeallocateGC(allocator, bv->_buckets);
    }
}

static CFTypeID __kCFBitVectorTypeID = _kCFRuntimeNotATypeID;

static const CFRuntimeClass __CFBitVectorClass = {
    _kCFRuntimeScannedObject,
    "CFBitVector",
    NULL,	// init
    NULL,	// copy
    __CFBitVectorDeallocate,
    __CFBitVectorEqual,
    __CFBitVectorHash,
    NULL,	// 
    __CFBitVectorCopyDescription
};

__private_extern__ void __CFBitVectorInitialize(void) {
    __kCFBitVectorTypeID = _CFRuntimeRegisterClass(&__CFBitVectorClass);
}

CFTypeID CFBitVectorGetTypeID(void) {
    return __kCFBitVectorTypeID;
}

static CFMutableBitVectorRef __CFBitVectorInit(CFAllocatorRef allocator, CFOptionFlags flags, CFIndex capacity, const uint8_t *bytes, CFIndex numBits) {
    CFMutableBitVectorRef memory;
    CFIndex size;
    CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%d) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
    CFAssert3(kCFBitVectorFixedMutable != __CFBitVectorMutableVarietyFromFlags(flags) || numBits <= capacity, __kCFLogAssertion, "%s(): for fixed mutable bit vectors, capacity (%d) must be greater than or equal to number of initial elements (%d)", __PRETTY_FUNCTION__, capacity, numBits);
    CFAssert2(0 <= numBits, __kCFLogAssertion, "%s(): numValues (%d) cannot be less than zero", __PRETTY_FUNCTION__, numBits);
    size = sizeof(struct __CFBitVector) - sizeof(CFRuntimeBase);
    if (__CFBitVectorMutableVarietyFromFlags(flags) != kCFBitVectorMutable)
	size += sizeof(__CFBitVectorBucket) * __CFBitVectorNumBucketsForCapacity(capacity);
    memory = (CFMutableBitVectorRef)_CFRuntimeCreateInstance(allocator, __kCFBitVectorTypeID, size, NULL);
    if (NULL == memory) {
	return NULL;
    }
    switch (__CFBitVectorMutableVarietyFromFlags(flags)) {
    case kCFBitVectorMutable:
	__CFBitVectorSetCapacity(memory, __CFBitVectorRoundUpCapacity(1));
	__CFBitVectorSetNumBuckets(memory, __CFBitVectorNumBucketsForCapacity(__CFBitVectorRoundUpCapacity(1)));
	CF_WRITE_BARRIER_BASE_ASSIGN(allocator, memory, memory->_buckets, _CFAllocatorAllocateGC(allocator, __CFBitVectorNumBuckets(memory) * sizeof(__CFBitVectorBucket), 0));
	if (__CFOASafe) __CFSetLastAllocationEventName(memory->_buckets, "CFBitVector (store)");
	if (NULL == memory->_buckets) {
	    CFRelease(memory);
	    return NULL;
	}
	break;
    case kCFBitVectorFixedMutable:
    case kCFBitVectorImmutable:
	/* Don't round up capacity */
	__CFBitVectorSetCapacity(memory, capacity);
	__CFBitVectorSetNumBuckets(memory, __CFBitVectorNumBucketsForCapacity(capacity));
	memory->_buckets = (__CFBitVectorBucket *)((int8_t *)memory + sizeof(struct __CFBitVector));
	break;
    }
    __CFBitVectorSetNumBucketsUsed(memory, numBits / __CF_BITS_PER_BUCKET + 1);
    __CFBitVectorSetCount(memory, numBits);
    if (bytes) {
	/* This move is possible because bits are numbered from 0 on the left */
	memmove(memory->_buckets, bytes, (numBits + __CF_BITS_PER_BYTE - 1) / __CF_BITS_PER_BYTE);
    }
    __CFBitVectorSetMutableVariety(memory, __CFBitVectorMutableVarietyFromFlags(flags));
    return memory;
}

CFBitVectorRef CFBitVectorCreate(CFAllocatorRef allocator, const uint8_t *bytes, CFIndex numBits) {
   return __CFBitVectorInit(allocator, kCFBitVectorImmutable, numBits, bytes, numBits);
}

CFMutableBitVectorRef CFBitVectorCreateMutable(CFAllocatorRef allocator, CFIndex capacity) {
   return __CFBitVectorInit(allocator, (0 == capacity) ? kCFBitVectorMutable : kCFBitVectorFixedMutable, capacity, NULL, 0);
}

CFBitVectorRef CFBitVectorCreateCopy(CFAllocatorRef allocator, CFBitVectorRef bv) {
   __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    return __CFBitVectorInit(allocator, kCFBitVectorImmutable, __CFBitVectorCount(bv), (const uint8_t *)bv->_buckets, __CFBitVectorCount(bv));
}

CFMutableBitVectorRef CFBitVectorCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFBitVectorRef bv) {
   __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    return __CFBitVectorInit(allocator, (0 == capacity) ? kCFBitVectorMutable : kCFBitVectorFixedMutable, capacity, (const uint8_t *)bv->_buckets, __CFBitVectorCount(bv));
}

CFIndex CFBitVectorGetCount(CFBitVectorRef bv) {
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    return __CFBitVectorCount(bv);
}

typedef __CFBitVectorBucket (*__CFInternalMapper)(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *context);

static void __CFBitVectorInternalMap(CFMutableBitVectorRef bv, CFRange range, __CFInternalMapper mapper, void *context) {
    CFIndex bucketIdx, bitOfBucket;
    CFIndex nBuckets;
    __CFBitVectorBucket bucketValMask, newBucketVal;
    if (0 == range.length) return;
    bucketIdx = range.location / __CF_BITS_PER_BUCKET;
    bitOfBucket = range.location & (__CF_BITS_PER_BUCKET - 1);
    /* Follow usual pattern of ramping up to a bit bucket boundary ...*/
    if (bitOfBucket + range.length < __CF_BITS_PER_BUCKET) {
	bucketValMask = __CFBitBucketMask(bitOfBucket, bitOfBucket + range.length - 1);
	range.length = 0;
    } else {
	bucketValMask = __CFBitBucketMask(bitOfBucket, __CF_BITS_PER_BUCKET - 1);
	range.length -= __CF_BITS_PER_BUCKET - bitOfBucket;
    }
    newBucketVal = mapper(bv->_buckets[bucketIdx], bucketValMask, context);
    bv->_buckets[bucketIdx] = (bv->_buckets[bucketIdx] & ~bucketValMask) | (newBucketVal & bucketValMask);
    bucketIdx++;
    /* ... clipping along with entire bit buckets ... */
    nBuckets = range.length / __CF_BITS_PER_BUCKET;
    range.length -= nBuckets * __CF_BITS_PER_BUCKET;
    while (nBuckets--) {
	newBucketVal = mapper(bv->_buckets[bucketIdx], ~0, context);
	bv->_buckets[bucketIdx] = newBucketVal;
	bucketIdx++;
    }
    /* ... and ramping down with the last fragmentary bit bucket. */
    if (0 != range.length) {
	bucketValMask = __CFBitBucketMask(0, range.length - 1);
	newBucketVal = mapper(bv->_buckets[bucketIdx], bucketValMask, context);
	bv->_buckets[bucketIdx] = (bv->_buckets[bucketIdx] & ~bucketValMask) | (newBucketVal & bucketValMask);
    }
}

struct _occursContext {
    CFBit value;
    CFIndex count;
};

static __CFBitVectorBucket __CFBitVectorCountBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, struct _occursContext *context) {
    static const __CFBitVectorBucket __CFNibbleBitCount[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
    __CFBitVectorBucket val;
    CFIndex idx;
    val = (context->value) ? (bucketValue & bucketValueMask) : (~bucketValue & bucketValueMask);
    for (idx = 0; idx < (CFIndex)sizeof(__CFBitVectorBucket) * 2; idx++) {
	context->count += __CFNibbleBitCount[val & 0xF];
	val = val >> 4;
    }
    return bucketValue;
}

CFIndex CFBitVectorGetCountOfBit(CFBitVectorRef bv, CFRange range, CFBit value) {
    struct _occursContext context;
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
    if (0 == range.length) return 0;
    context.value = value;
    context.count = 0;
    __CFBitVectorInternalMap((CFMutableBitVectorRef)bv, range, (__CFInternalMapper)__CFBitVectorCountBits, &context);
    return context.count;
}

Boolean CFBitVectorContainsBit(CFBitVectorRef bv, CFRange range, CFBit value) {
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
    return (CFBitVectorGetCountOfBit(bv, range, value) != 0) ? true : false;
}

CFBit CFBitVectorGetBitAtIndex(CFBitVectorRef bv, CFIndex idx) {
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    CFAssert2(0 <= idx && idx < __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
    return __CFBitVectorBit(bv->_buckets, idx);
}

struct _getBitsContext {
    uint8_t *curByte;
    CFIndex initBits;	/* Bits to extract off the front for the prev. byte */
    CFIndex totalBits;	/* This is for stopping at the end */
    bool ignoreFirstInitBits;
};

static __CFBitVectorBucket __CFBitVectorGetBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *ctx) {
    struct _getBitsContext *context = (struct _getBitsContext *)ctx;
    __CFBitVectorBucket val;
    CFIndex nBits;
    val = bucketValue & bucketValueMask;
    nBits = __CFMin(__CF_BITS_PER_BUCKET - context->initBits, context->totalBits);
    /* First initBits bits go in *curByte ... */
    if (0 < context->initBits) {
	if (!context->ignoreFirstInitBits) {
	    *context->curByte |= (uint8_t)(val >> (__CF_BITS_PER_BUCKET - context->initBits));
	    context->curByte++;
	    context->totalBits -= context->initBits;
	    context->ignoreFirstInitBits = false;
	}
	val <<= context->initBits;
    }
    /* ... then next groups of __CF_BITS_PER_BYTE go in *curByte ... */
    while (__CF_BITS_PER_BYTE <= nBits) {
	*context->curByte = (uint8_t)(val >> (__CF_BITS_PER_BUCKET - __CF_BITS_PER_BYTE));
	context->curByte++;
	context->totalBits -= context->initBits;
	nBits -= __CF_BITS_PER_BYTE;
	val <<= __CF_BITS_PER_BYTE;
    }
    /* ... then remaining bits go in *curByte */
    if (0 < nBits) {
	*context->curByte = (uint8_t)(val >> (__CF_BITS_PER_BUCKET - __CF_BITS_PER_BYTE));
	context->totalBits -= nBits;
    }
    return bucketValue;
}

void CFBitVectorGetBits(CFBitVectorRef bv, CFRange range, uint8_t *bytes) {
    struct _getBitsContext context;
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
    if (0 == range.length) return;
    context.curByte = bytes;
    context.initBits = range.location & (__CF_BITS_PER_BUCKET - 1);
    context.totalBits = range.length;
    context.ignoreFirstInitBits = true;
    __CFBitVectorInternalMap((CFMutableBitVectorRef)bv, range, __CFBitVectorGetBits, &context);
}

CFIndex CFBitVectorGetFirstIndexOfBit(CFBitVectorRef bv, CFRange range, CFBit value) {
    CFIndex idx;
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
    for (idx = 0; idx < range.length; idx++) {
	if (value == CFBitVectorGetBitAtIndex(bv, range.location + idx)) {
	    return range.location + idx;
	}
    }
    return kCFNotFound;
}

CFIndex CFBitVectorGetLastIndexOfBit(CFBitVectorRef bv, CFRange range, CFBit value) {
    CFIndex idx;
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
    for (idx = range.length; idx--;) {
	if (value == CFBitVectorGetBitAtIndex(bv, range.location + idx)) {
	    return range.location + idx;
	}
    }
    return kCFNotFound;
}

static void __CFBitVectorGrow(CFMutableBitVectorRef bv, CFIndex numNewValues) {
    CFIndex oldCount = __CFBitVectorCount(bv);
    CFIndex capacity = __CFBitVectorRoundUpCapacity(oldCount + numNewValues);
    CFAllocatorRef allocator = CFGetAllocator(bv);
    __CFBitVectorSetCapacity(bv, capacity);
    __CFBitVectorSetNumBuckets(bv, __CFBitVectorNumBucketsForCapacity(capacity));
    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, bv, bv->_buckets, CFAllocatorReallocate(allocator, bv->_buckets, __CFBitVectorNumBuckets(bv) * sizeof(__CFBitVectorBucket), 0));
    if (__CFOASafe) __CFSetLastAllocationEventName(bv->_buckets, "CFBitVector (store)");
    if (NULL == bv->_buckets) HALT;
}

static __CFBitVectorBucket __CFBitVectorZeroBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *context) {
    return 0;
}

static __CFBitVectorBucket __CFBitVectorOneBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *context) {
    return ~(__CFBitVectorBucket)0;
}

void CFBitVectorSetCount(CFMutableBitVectorRef bv, CFIndex count) {
    CFIndex cnt;
    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
    cnt = __CFBitVectorCount(bv);
    switch (__CFBitVectorMutableVariety(bv)) {
    case kCFBitVectorMutable:
	if (cnt < count) {
	    __CFBitVectorGrow(bv, count - cnt);
	}
	break;
    case kCFBitVectorFixedMutable:
	CFAssert1(count <= __CFBitVectorCapacity(bv), __kCFLogAssertion, "%s(): fixed-capacity bit vector is full", __PRETTY_FUNCTION__);
	break;
    }
    if (cnt < count) {
	CFRange range = CFRangeMake(cnt, count - cnt);
        __CFBitVectorInternalMap(bv, range, __CFBitVectorZeroBits, NULL);
    }
    __CFBitVectorSetNumBucketsUsed(bv, count / __CF_BITS_PER_BUCKET + 1);
    __CFBitVectorSetCount(bv, count);
}

void CFBitVectorFlipBitAtIndex(CFMutableBitVectorRef bv, CFIndex idx) {
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    CFAssert2(0 <= idx && idx < __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
    __CFFlipBitVectorBit(bv->_buckets, idx);
}

static __CFBitVectorBucket __CFBitVectorFlipBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *context) {
    return (~(__CFBitVectorBucket)0) ^ bucketValue;
}

void CFBitVectorFlipBits(CFMutableBitVectorRef bv, CFRange range) {
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
    if (0 == range.length) return;
    __CFBitVectorInternalMap(bv, range, __CFBitVectorFlipBits, NULL);
}

void CFBitVectorSetBitAtIndex(CFMutableBitVectorRef bv, CFIndex idx, CFBit value) {
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    CFAssert2(0 <= idx && idx < __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
    __CFSetBitVectorBit(bv->_buckets, idx, value);
}

void CFBitVectorSetBits(CFMutableBitVectorRef bv, CFRange range, CFBit value) {
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
    if (0 == range.length) return;
    if (value) {
	__CFBitVectorInternalMap(bv, range, __CFBitVectorOneBits, NULL);
    } else {
	__CFBitVectorInternalMap(bv, range, __CFBitVectorZeroBits, NULL);
    }
}

void CFBitVectorSetAllBits(CFMutableBitVectorRef bv, CFBit value) {
    CFIndex nBuckets, leftover;
    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
    nBuckets = __CFBitVectorCount(bv) / __CF_BITS_PER_BUCKET;
    leftover = __CFBitVectorCount(bv) - nBuckets * __CF_BITS_PER_BUCKET;
    if (0 < leftover) {
	CFRange range = CFRangeMake(nBuckets * __CF_BITS_PER_BUCKET, leftover);
	if (value) {
	    __CFBitVectorInternalMap(bv, range, __CFBitVectorOneBits, NULL);
	} else {
	    __CFBitVectorInternalMap(bv, range, __CFBitVectorZeroBits, NULL);
	}
    }
    memset(bv->_buckets, (value ? ~0 : 0), nBuckets);
}

#undef __CFBitVectorValidateRange

