26 var _builtInCharacterSets = {};
58 _inverted = !_inverted;
66 - (BOOL)hasMemberInPlane:(
int)aPlane
71 + (id)characterSetWithCharactersInString:(
CPString)aString
73 return [[_CPStringContentCharacterSet alloc] initWithString:aString];
76 + (id)characterSetWithRange:(CPRange)aRange
78 return [[_CPRangeCharacterSet alloc] initWithRange:aRange];
142 + (id)_sharedCharacterSetWithName:(
id)csname
144 var cs = _builtInCharacterSets[csname];
149 rangeArray = eval(csname);
151 for (; i < rangeArray.length; i+= 2)
153 var loc = rangeArray[i],
154 length = rangeArray[i + 1],
156 [ranges addObject:range];
158 cs = [[_CPRangeCharacterSet alloc] initWithRanges:ranges];
159 _builtInCharacterSets[csname] = cs;
165 - (void)_setInverted:flag
178 if (
self = [super init])
180 _inverted = [aCoder decodeBoolForKey:CPCharacterSetInvertedKey];
188 [aCoder encodeBool:_inverted forKey:CPCharacterSetInvertedKey];
201 - (id)initWithRange:(CPRange)r
207 - (id)initWithRanges:(
CPArray)ranges
221 var
set = [[_CPRangeCharacterSet alloc] initWithRanges:_ranges];
222 [set _setInverted:_inverted];
228 var
set = [[_CPRangeCharacterSet alloc] initWithRanges:_ranges];
233 - (BOOL)characterIsMember:(
CPString)aCharacter
235 c = aCharacter.charCodeAt(0);
236 var enu = [_ranges objectEnumerator],
239 while ((range = [enu nextObject]) !== nil)
241 if (CPLocationInRange(c, range))
248 - (BOOL)hasMemberInPlane:(
int)plane
253 var maxPlane = FLOOR((range.start + range.length - 1) / 65536);
255 return (plane <= maxPlane);
258 - (void)addCharactersInRange:(CPRange)aRange
260 [_ranges addObject:aRange];
263 - (void)addCharactersInString:(
CPString)aString
267 for (; i < aString.
length; i++)
269 var code = aString.charCodeAt(i),
272 [_ranges addObject:range];
299 var
set = [[_CPStringContentCharacterSet alloc] initWithString:_string];
300 [set _setInverted:_inverted];
307 var
set = [[_CPStringContentCharacterSet alloc] initWithString:_string];
313 - (BOOL)characterIsMember:(
CPString)c
315 return (_string.indexOf(c.charAt(0)) != -1) == !_inverted;
320 return [
super description] + " {
string =
'" + _string + "'}
";
323 - (BOOL)hasMemberInPlane:(int)plane
325 // JavaScript strings can only return char codes
326 // up to 0xFFFF (per the ECMA standard), so
327 // they all live in the Basic Multilingual Plane
329 // TODO if the above is wrong, this must be changed!
334 - (void)addCharactersInRange:(CPRange)aRange // Needs _inverted support
336 var i = aRange.location,
337 count = aRange.location + aRange.length;
339 for (; i < count; i++)
341 var s = String.fromCharCode(i);
343 if (![self characterIsMember:s])
344 _string = [_string stringByAppendingString:s];
348 - (void)addCharactersInString:(CPString)aString // Needs _inverted support
352 for (; i < aString.length; i++)
354 var s = aString.charAt(i);
356 if (![self characterIsMember:s])
357 _string = [_string stringByAppendingString:s];
361 - (BOOL)isEqual:(CPCharacterSet)aCharacterSet
363 if (self === aCharacterSet)
366 if (!aCharacterSet || ![aCharacterSet isKindOfClass:[self class]])
369 return [self _isEqualToStringContentCharacterSet:aCharacterSet];
372 - (BOOL)_isEqualToStringContentCharacterSet:(_CPStringContentCharacterSet)aCharacterSet
377 return _string == aCharacterSet._string && _inverted == aCharacterSet._inverted;
382 var _CPStringContentCharacterSetStringKey = @"_CPStringContentCharacterSetStringKey
";
384 @implementation _CPStringContentCharacterSet (CPCoding)
386 - (id)initWithCoder:(CPCoder)aCoder
388 if (self = [super initWithCoder:aCoder])
390 _string = [aCoder decodeObjectForKey:_CPStringContentCharacterSetStringKey]
396 - (void)encodeWithCoder:(CPCoder)aCoder
398 [super encodeWithCoder:aCoder];
400 [aCoder encodeObject:_string forKey:_CPStringContentCharacterSetStringKey];
405 _CPCharacterSetTrimAtBeginning = 1 << 1;
406 _CPCharacterSetTrimAtEnd = 1 << 2;
408 @implementation CPString (CPCharacterSetAdditions)
422 - (CPArray)componentsSeparatedByCharactersInSet:(CPCharacterSet)separator
425 [CPException raise:CPInvalidArgumentException
426 reason:"componentsSeparatedByCharactersInSet: the separator can
't be 'nil
'"];
428 var components = [CPMutableArray array],
429 componentRange = CPMakeRange(0, 0),
432 for (; i < self.length; i++)
434 if ([separator characterIsMember:self.charAt(i)])
436 componentRange.length = i - componentRange.location;
437 [components addObject:[self substringWithRange:componentRange]];
438 componentRange.location += componentRange.length + 1;
442 componentRange.length = self.length - componentRange.location;
443 [components addObject:[self substringWithRange:componentRange]];
448 // As per the Cocoa method.
449 - (id)stringByTrimmingCharactersInSet:(CPCharacterSet)set
451 return [self _stringByTrimmingCharactersInSet:set options:_CPCharacterSetTrimAtBeginning | _CPCharacterSetTrimAtEnd];
454 // private method evilness!
455 // CPScanner's scanUpToString:... methods rely on
this
457 - (id)_stringByTrimmingCharactersInSet:(
CPCharacterSet)set options:(
int)options
461 if (options & _CPCharacterSetTrimAtBeginning)
463 var cutEdgeBeginning = 0;
465 while (cutEdgeBeginning <
self.length && [
set characterIsMember:
self.charAt(cutEdgeBeginning)])
468 str = str.substr(cutEdgeBeginning);
471 if (options & _CPCharacterSetTrimAtEnd)
473 var cutEdgeEnd = str.length;
475 while (cutEdgeEnd > 0 && [
set characterIsMember:
self.charAt(cutEdgeEnd)])
478 str = str.substr(0, cutEdgeEnd + 1);