4 Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
7 Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
9 This file is part of libFoundation.
11 Permission to use, copy, modify, and distribute this software and its
12 documentation for any purpose and without fee is hereby granted, provided
13 that the above copyright notice appear in all copies and that both that
14 copyright notice and this permission notice appear in supporting
17 We disclaim all warranties with regard to this software, including all
18 implied warranties of merchantability and fitness, in no event shall
19 we be liable for any special, indirect or consequential damages or any
20 damages whatsoever resulting from loss of use, data or profits, whether in
21 an action of contract, negligence or other tortious action, arising out of
22 or in connection with the use or performance of this software.
25 #include <Foundation/common.h>
26 #include <Foundation/NSCharacterSet.h>
27 #include <Foundation/NSDictionary.h>
28 #include <Foundation/NSString.h>
29 #include <Foundation/NSData.h>
30 #include <Foundation/NSCoder.h>
31 #include <Foundation/NSException.h>
32 #include <Foundation/NSLock.h>
33 #include <Foundation/NSBundle.h>
35 #include <Foundation/exceptions/GeneralExceptions.h>
37 #include "NSConcreteCharacterSet.h"
39 @implementation NSCharacterSet
43 + (id)allocWithZone:(NSZone*)zone
45 return NSAllocateObject( (self == [NSCharacterSet class]) ?
46 [NSBitmapCharacterSet class] : self, 0, zone);
49 // Creating a shared Character Set from a standard file
50 // We should mmap only ONE file and have a the sets initialized
51 // with range subdata of the main file (range subdata of NSData must
52 // not copy its data but retain its master data ...
53 // In this case we need a dictionary to know the offset of each charset
54 // in the BIG data; this approach should be very efficient on systems
55 // that support mmap (in paged virtual memory systems)
57 static NSMutableDictionary* predefinedCharacterSets = nil;
59 extern NSRecursiveLock* libFoundationLock;
61 + (NSCharacterSet *)characterSetWithContentsOfFile:(NSString *)fileName
64 Note: we need to be careful here, this has potential for
72 [libFoundationLock lock];
74 if (predefinedCharacterSets == nil) {
75 predefinedCharacterSets =
76 [[NSMutableDictionary alloc] initWithCapacity:12];
78 aSet = [predefinedCharacterSets objectForKey:fileName];
80 [libFoundationLock unlock];
83 NSString *fullFilenamePath;
86 fullFilenamePath = [NSBundle _fileResourceNamed:fileName
88 inDirectory:@"CharacterSets"];
90 if (fullFilenamePath != nil)
91 data = [NSData dataWithContentsOfMappedFile:fullFilenamePath];
94 /* Note: yes, this is weird, but matches Panther! */
98 aSet = AUTORELEASE([[NSBitmapCharacterSet alloc]
99 initWithBitmapRepresentation:data]);
102 "ERROR(%s): could not create character set for "
103 "data (0x%08X,len=%d) from file %s (%s)\n",
105 (unsigned int)data, [data length], [fileName cString],
106 [fullFilenamePath cString]);
109 [libFoundationLock lock];
110 [predefinedCharacterSets setObject:aSet forKey:fileName];
111 [libFoundationLock unlock];
117 // Creating a Standard Character Set
119 + (NSCharacterSet*)alphanumericCharacterSet
121 return [self characterSetWithContentsOfFile:@"alphanumericCharacterSet"];
124 + (NSCharacterSet*)controlCharacterSet
126 return [self characterSetWithContentsOfFile:@"controlCharacterSet"];
129 + (NSCharacterSet*)decimalDigitCharacterSet
131 return [self characterSetWithContentsOfFile:@"decimalDigitCharacterSet"];
134 + (NSCharacterSet*)decomposableCharacterSet
136 return [self characterSetWithContentsOfFile:@"decomposableCharacterSet"];
139 + (NSCharacterSet*)illegalCharacterSet
141 return [self characterSetWithContentsOfFile:@"illegalCharacterSet"];
144 + (NSCharacterSet*)letterCharacterSet
146 return [self characterSetWithContentsOfFile:@"letterCharacterSet"];
149 + (NSCharacterSet*)lowercaseLetterCharacterSet
151 return [self characterSetWithContentsOfFile:@"lowercaseLetterCharacterSet"];
154 + (NSCharacterSet*)nonBaseCharacterSet
156 return [self characterSetWithContentsOfFile:@"nonBaseCharacterSet"];
159 + (NSCharacterSet*)uppercaseLetterCharacterSet
161 return [self characterSetWithContentsOfFile:@"uppercaseLetterCharacterSet"];
164 + (NSCharacterSet*)whitespaceAndNewlineCharacterSet
166 return [self characterSetWithContentsOfFile:@"whitespaceAndNewlineCharacterSet"];
169 + (NSCharacterSet*)whitespaceCharacterSet
171 return [self characterSetWithContentsOfFile:@"whitespaceCharacterSet"];
174 + (NSCharacterSet*)punctuationCharacterSet
176 return [self characterSetWithContentsOfFile:@"punctuationCharacterSet"];
179 + (NSCharacterSet*)emptyCharacterSet
181 return [self characterSetWithContentsOfFile:@"emptyCharacterSet"];
184 // Creating a Custom Character Set
186 + (NSCharacterSet*)characterSetWithBitmapRepresentation:(NSData*)data
188 return AUTORELEASE([[NSBitmapCharacterSet alloc]
189 initWithBitmapRepresentation:data]);
192 + (NSCharacterSet*)characterSetWithCharactersInString:(NSString*)aString
194 char* bytes = CallocAtomic(1, BITMAPDATABYTES);
196 int i, count = [aString length];
199 for (i = 0; i < count; i++) {
200 c = [aString characterAtIndex:i];
204 data = [NSData dataWithBytesNoCopy:bytes
205 length:BITMAPDATABYTES];
206 return [self isKindOfClass:[NSMutableCharacterSet class]]
207 ? AUTORELEASE([[NSMutableBitmapCharacterSet alloc]
208 initWithBitmapRepresentation:data])
209 : AUTORELEASE([[NSBitmapCharacterSet alloc]
210 initWithBitmapRepresentation:data]);
213 + (NSCharacterSet*)characterSetWithRange:(NSRange)aRange
215 return AUTORELEASE([[NSRangeCharacterSet alloc] initWithRange:aRange]);
218 // Getting a Binary Representation
220 - (NSData*)bitmapRepresentation
222 [self subclassResponsibility:_cmd];
226 // Testing Set Membership
228 - (BOOL)characterIsMember:(unichar)aCharacter
230 [self subclassResponsibility:_cmd];
234 // Inverting a Character Set
236 - (NSCharacterSet*)invertedSet
238 [self subclassResponsibility:_cmd];
244 - copyWithZone:(NSZone*)zone
246 if (NSShouldRetainWithZone(self, zone))
249 id data = [self bitmapRepresentation];
250 return [[NSCharacterSet alloc] initWithBitmapRepresentation:data];
254 - mutableCopyWithZone:(NSZone*)zone
256 id data = [self bitmapRepresentation];
257 return RETAIN([NSMutableCharacterSet
258 characterSetWithBitmapRepresentation:data]);
263 - (Class)classForCoder
265 return [NSCharacterSet class];
268 - (id)replacementObjectForCoder:(NSCoder*)coder
270 if ([[self class] isKindOfClass:[NSMutableCharacterSet class]])
271 return [super replacementObjectForCoder:coder];
275 - initWithCoder:(NSCoder*)coder
280 [coder decodeValueOfObjCType:@encode(id) at:&data];
281 new = [[[self class] alloc] initWithBitmapRepresentation:data];
286 - (void)encodeWithCoder:(NSCoder*)coder
288 id data = [self bitmapRepresentation];
289 [coder encodeValueOfObjCType:@encode(id) at:&data];
292 @end /* NSCharacterSet */
294 @implementation NSMutableCharacterSet
296 // Cluster allocation
298 + (id)allocWithZone:(NSZone*)zone
300 return NSAllocateObject( (self == [NSMutableCharacterSet class]) ?
301 [NSMutableBitmapCharacterSet class] : self, 0, zone);
304 // Creating a Custom Character Set
306 + (NSCharacterSet*)characterSetWithBitmapRepresentation:(NSData*)data
308 return AUTORELEASE([[self alloc] initWithBitmapRepresentation:data]);
311 + (NSCharacterSet*)characterSetWithContentsOfFile:(NSString*)fileName
313 NSCharacterSet *set = [super characterSetWithContentsOfFile:fileName];
314 return AUTORELEASE([set mutableCopy]);
316 + (NSCharacterSet*)characterSetWithCharactersInString:(NSString*)aString
318 NSCharacterSet *set = [super characterSetWithCharactersInString:aString];
319 return AUTORELEASE([set mutableCopy]);
321 + (NSCharacterSet*)characterSetWithRange:(NSRange)aRange
323 NSCharacterSet *set = [super characterSetWithRange:aRange];
324 return AUTORELEASE([set mutableCopy]);
327 // Adding and Removing Characters
329 - (void)addCharactersInRange:(NSRange)aRange
331 [self subclassResponsibility:_cmd];
334 - (void)addCharactersInString:(NSString*)aString
336 [self subclassResponsibility:_cmd];
339 - (void)removeCharactersInRange:(NSRange)aRange
341 [self subclassResponsibility:_cmd];
344 - (void)removeCharactersInString:(NSString*)aString
346 [self subclassResponsibility:_cmd];
349 // Combining Character Sets
351 - (void)formIntersectionWithCharacterSet:(NSCharacterSet*)otherSet
353 [self subclassResponsibility:_cmd];
356 - (void)formUnionWithCharacterSet:(NSCharacterSet*)otherSet
358 [self subclassResponsibility:_cmd];
361 // Inverting a Character Set
365 [self subclassResponsibility:_cmd];
370 - copyWithZone:(NSZone*)zone
372 id data = [self bitmapRepresentation];
373 return RETAIN([NSCharacterSet characterSetWithBitmapRepresentation:data]);
378 - (Class)classForCoder
380 return [NSMutableCharacterSet class];
383 @end /* NSMutableCharacterSet */