I need NSRange objects for the position of each uppercase letter in a given NSString for input into a method for a custom attributed string class.
There are of course q
It somewhat depends on the size of the string, but the absolute fastest way I can think of (note: internationalization safety not guaranteed, or even expected! Does the concept of uppercase even apply in say, Japanese?) is:
1) Get a pointer to a raw C string of the string, preferably in a stack buffer if it's small enough. CFString has functions for this. Read the comments in CFString.h.
2) malloc() a buffer big enough to hold one NSRange per character in the string.
3) Something like this (completely untested, written into this text field, pardon mistakes and typos)
NSRange *bufferCursor = rangeBuffer;
NSRange range = {NSNotFound, 0};
for (int idx = 0; idx < numBytes; ++idx) {
if (isupper(buffer[idx])) {
if (range.length > 0) { //extend a range, we found more than one uppercase letter in a row
range.length++;
} else { //begin a range
range.location = idx;
range.length = 1;
}
}
else if (range.location != NSNotFound) { //end a range, we hit a lowercase letter
*bufferCursor = range;
bufferCursor++;
range.location = NSNotFound;
}
}
4) realloc() the range buffer back down to the size you actually used (might need to keep a count of ranges begun to do that)