#import "YapDatabaseViewPage.h" #include @implementation YapDatabaseViewPage { std::vector *vector; } - (id)init { return [self initWithCapacity:0]; } - (id)initWithCapacity:(NSUInteger)capacity { if ((self = [super init])) { vector = new std::vector(); if (capacity > 0) vector->reserve(capacity); } return self; } - (id)copyWithZone:(NSZone *)zone { YapDatabaseViewPage *copy = [[YapDatabaseViewPage alloc] initWithCapacity:[self count]]; copy->vector->insert(copy->vector->begin(), vector->begin(), vector->end()); return copy; } - (void)dealloc { if (vector) delete vector; } - (NSData *)serialize { NSUInteger count = vector->size(); NSUInteger numBytes = count * sizeof(int64_t); int64_t *buffer = (int64_t *)malloc(numBytes); memcpy(buffer, vector->data(), numBytes); if (CFByteOrderGetCurrent() == CFByteOrderBigEndian) { for (NSUInteger i = 0; i < count; i++) { buffer[i] = CFSwapInt64HostToLittle(buffer[i]); } } return [NSData dataWithBytesNoCopy:buffer length:numBytes freeWhenDone:YES]; } - (void)deserialize:(NSData *)data { vector->clear(); NSUInteger count = [data length] / sizeof(int64_t); int64_t *bytes = (int64_t *)[data bytes]; if (vector->capacity() < count) vector->reserve(count); for (NSUInteger i = 0; i < count; i++) { int64_t rowid = bytes[i]; if (CFByteOrderGetCurrent() == CFByteOrderBigEndian) vector->push_back(CFSwapInt64LittleToHost(rowid)); else vector->push_back(rowid); } } - (NSUInteger)count { return (NSUInteger)(vector->size()); } - (int64_t)rowidAtIndex:(NSUInteger)index { return vector->at(index); } - (void)addRowid:(int64_t)rowid { vector->push_back(rowid); } - (void)insertRowid:(int64_t)rowid atIndex:(NSUInteger)index { vector->insert(vector->begin() + index, rowid); } - (void)removeRowidAtIndex:(NSUInteger)index { vector->erase(vector->begin() + index); } - (void)removeRange:(NSRange)range { std::vector::iterator it = vector->begin(); vector->erase(it+range.location, it+range.location+range.length); } - (void)appendRange:(NSRange)range ofPage:(YapDatabaseViewPage *)page { std::vector::iterator rangeBegin = page->vector->begin(); std::vector::iterator rangeEnd; rangeBegin += range.location; rangeEnd = rangeBegin + range.length; vector->insert(vector->end(), rangeBegin, rangeEnd); } - (void)prependRange:(NSRange)range ofPage:(YapDatabaseViewPage *)page { std::vector::iterator rangeBegin = page->vector->begin(); std::vector::iterator rangeEnd; rangeBegin += range.location; rangeEnd = rangeBegin + range.length; vector->insert(vector->begin(), rangeBegin, rangeEnd); } - (BOOL)getIndex:(NSUInteger *)indexPtr ofRowid:(int64_t)rowid { std::vector::iterator iterator = vector->begin(); std::vector::iterator end = vector->end(); NSUInteger index = 0; while (iterator != end) { if (*iterator == rowid) { if (indexPtr) *indexPtr = index; return YES; } iterator++; index++; } if (indexPtr) *indexPtr = 0; return NO; } - (void)enumerateRowidsUsingBlock:(void (^)(int64_t rowid, NSUInteger idx, BOOL *stop))block { [self enumerateRowidsWithOptions:0 usingBlock:block]; } - (void)enumerateRowidsWithOptions:(NSEnumerationOptions)options usingBlock:(void (^)(int64_t rowid, NSUInteger index, BOOL *stop))block { if (block == NULL) return; if ((options & NSEnumerationReverse) == 0) { // Forward enumeration std::vector::iterator iterator = vector->begin(); std::vector::iterator end = vector->end(); NSUInteger index = 0; BOOL stop = NO; while (iterator != end) { int64_t rowid = *iterator; block(rowid, index, &stop); if (stop) break; iterator++; index++; } } else { // Reverse enumeration std::vector::reverse_iterator iterator = vector->rbegin(); std::vector::reverse_iterator end = vector->rend(); NSUInteger index = vector->size() - 1; BOOL stop = NO; while (iterator != end) { int64_t rowid = *iterator; block(rowid, index, &stop); if (stop) break; iterator++; index--; } } } - (void)enumerateRowidsWithOptions:(NSEnumerationOptions)options range:(NSRange)range usingBlock:(void (^)(int64_t rowid, NSUInteger index, BOOL *stop))block { if (block == NULL) return; if ((options & NSEnumerationReverse) == 0) { // Forward enumeration std::vector::iterator iterator = vector->begin(); std::vector::iterator end; iterator += range.location; end = iterator + range.length; NSUInteger index = range.location; BOOL stop = NO; while (iterator != end) { int64_t rowid = *iterator; block(rowid, index, &stop); if (stop) break; iterator++; index++; } } else { // Reverse enumeration std::vector::reverse_iterator iterator = vector->rbegin(); std::vector::reverse_iterator end; iterator += (vector->size() - (range.location + range.length)); end = iterator + range.length; NSUInteger index = range.location + range.length - 1; BOOL stop = NO; while (iterator != end) { int64_t rowid = *iterator; block(rowid, index, &stop); if (stop) break; iterator++; index--; } } } - (NSString *)debugDescription { NSMutableString *string = [NSMutableString stringWithCapacity:100]; [string appendFormat:@"::iterator iterator = vector->begin(); std::vector::iterator end = vector->end(); NSUInteger index = 0; while (iterator != end) { [string appendFormat:@" %lu: %lld\n", (unsigned long)index, *iterator]; iterator++; index++; } [string appendFormat:@"}>"]; return string; } @end