nicklockwood/FastCoding — pull request #5 by marcuswestin (2014-07-31 14:10:20+00:00)
Title: Add support for NSIndexSet and NSMutableIndexSet

Hi Nick,

I required support for NSIndexSet in FastCoder. This is my suggested implementation.

Three quick notes:

1) `NSIndexSet`'s internal representation is as a list of NSRanges. I chose to serialize it this same way.

2) In `NSSet -FC_writeToOutput`, we loop over the collection of ranges twice since there isn't a `NSIndexSet -countRanges` method. This is unfortunate but seems the most appropriate solution to me. I'm open to other suggestions (https://github.com/marcuswestin/FastCoding/compare/nicklockwood:master...master#diff-1c065108cf07958bcc795ab95e3e7aebR965)

3) Ideally we would be able to deserialize by using e.g `[NSIndexSet indexSetWithRangesInArray:]`, but there is no such method. There is not even a `[NSMutableIndexSet indexSetWithCapacity:]`. So we're left with having to loop over the ranges and add them one by one.

Both 2) and 3) could be addressed by touching the internal representation of `NSSet` directly:

```
@interface NSIndexSet : NSObject {
@protected // all instance variables are private
struct {
NSUInteger _isEmpty:1;
NSUInteger _hasSingleRange:1;
NSUInteger _cacheValid:1;
NSUInteger _reservedArrayBinderController:29;
} _indexSetFlags;
union {
struct {
NSRange _range;
} _singleRange;
struct {
void * __strong _data;
void *_reserved;
} _multipleRanges;
} _internal;
}
```

However, I was more concerned with a correct implementation for now, and could see one of us implementing the more efficient version if the need rises in the future (with appropriate test coverage).

Another alternative would be to serialize the sets by enumerating every index, but that seems awefully wasteful.

I hope you find the patch appropriate!

Cheers,
Marcus