Changeset 5

Show
Ignore:
Timestamp:
12/10/06 7:35:46 PM (2 years ago)
Author:
aaron
Message:

- added Matcher methods
- modified Matcher/Pattern API

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/CocoaICU.xcodeproj/project.pbxproj

    r3 r5  
    2020                93E2C5320B1A59FC001193AC /* CocoaICU.m in Sources */ = {isa = PBXBuildFile; fileRef = 93E2C0CE0B18D142001193AC /* CocoaICU.m */; }; 
    2121/* End PBXBuildFile section */ 
    22  
    23 /* Begin PBXContainerItemProxy section */ 
    24                 93E2C57C0B1A6A77001193AC /* PBXContainerItemProxy */ = { 
    25                         isa = PBXContainerItemProxy; 
    26                         containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; 
    27                         proxyType = 1; 
    28                         remoteGlobalIDString = 93E2BFE40B18BEC4001193AC; 
    29                         remoteInfo = "CocoaICU Unit Tests"; 
    30                 }; 
    31 /* End PBXContainerItemProxy section */ 
    3222 
    3323/* Begin PBXFileReference section */ 
     
    164154                        ); 
    165155                        dependencies = ( 
    166                                 93E2C57D0B1A6A77001193AC /* PBXTargetDependency */, 
    167156                        ); 
    168157                        name = CocoaICU; 
     
    236225                }; 
    237226/* End PBXSourcesBuildPhase section */ 
    238  
    239 /* Begin PBXTargetDependency section */ 
    240                 93E2C57D0B1A6A77001193AC /* PBXTargetDependency */ = { 
    241                         isa = PBXTargetDependency; 
    242                         target = 93E2BFE40B18BEC4001193AC /* CocoaICU Unit Tests */; 
    243                         targetProxy = 93E2C57C0B1A6A77001193AC /* PBXContainerItemProxy */; 
    244                 }; 
    245 /* End PBXTargetDependency section */ 
    246227 
    247228/* Begin XCBuildConfiguration section */ 
  • trunk/source/CocoaICU.m

    r2 r5  
    1414        NSString *searchString = @"bbdfdbbababababaklsdjfababababab"; 
    1515        NSString *patternString = @"([ab]+)"; 
    16         NSArray *results = [searchString findPatternString:patternString]; 
    1716         
    18         NSLog(@"%@", results); 
    1917         
    2018        [pool release]; 
    2119    return 0; 
    2220} 
    23  
    24 void doUnicodeCharSearch() { 
    25         NSString *searchString = [NSString stringWithUTF8String:"∂ƒŽ®¢ßç32£™£¢™£¢"]; 
    26         NSString *pattern = [NSString stringWithUTF8String:"[[:digit:]]+"]; 
    27         NSLog(@"components = %@", [searchString componentsSeparatedByPattern:[ICUPattern patternWithString:pattern]]); 
    28 } 
    29  
    30 void doSplitTest() { 
    31         NSString *searchString = @"this is a test to see how splitting works or doesn't work"; 
    32         NSString *regex = @" "; 
    33         NSLog(@"split = %@", [searchString componentsSeparatedByPattern:[ICUPattern patternWithString:regex]]); 
    34 } 
    35  
    36 void doGroupTest() { 
    37         NSString *searchString = @"this is a test to see how grouping works or doesn't work."; 
    38         NSString *regex = @"(this is a test to see how grouping) works or (doesn't work)."; 
    39         NSLog(@"groups = %@", [searchString findPatternString:regex]);           
    40 } 
    41  
    42 void doSpeedComparison() { 
    43         NSString *pathToSomeFile = [@"~/Sandbox/CocoaICU/trunk/resources/cocoa.mbox" stringByExpandingTildeInPath]; 
    44         NSData *stringData = [NSData dataWithContentsOfMappedFile:pathToSomeFile]; 
    45         NSString *fileContents = [[NSString alloc] initWithData:stringData encoding:NSASCIIStringEncoding]; 
    46 //      NSAssert(fileContents != nil, @"Cannot create string from file at path: %@", pathToSomeFile); 
    47  
    48         NSString *searchTerm = @"cocoa"; 
    49         NSString *replacementTerm = @"replacementText"; 
    50  
    51 //      /* do foundation find and replace */ 
    52         NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init]; 
    53         NSCalendarDate *preCocoaFindAndReplaceTime = [NSCalendarDate date]; 
    54         NSMutableString *stringToSearch = [NSMutableString stringWithString:fileContents]; 
    55         [stringToSearch replaceOccurrencesOfString:searchTerm withString:replacementTerm options:0 range:NSMakeRange(0, [stringToSearch length])]; 
    56         NSString *resultingStringUsingFoundation = [[NSString stringWithString:stringToSearch] retain]; 
    57         NSLog(@"Foundation find/replace took %.3f seconds", [[NSDate date] timeIntervalSinceDate:preCocoaFindAndReplaceTime]); 
    58         [innerPool release]; 
    59  
    60         innerPool = [[NSAutoreleasePool alloc] init]; 
    61         /* do icu find and replace */ 
    62         NSCalendarDate *preICUFindAndReplaceTime = [NSCalendarDate date]; 
    63         NSString *resultingStringUsingIcu  = [fileContents findPattern:[ICUPattern patternWithString:searchTerm flags:0] replaceAllWith:replacementTerm]; 
    64         NSLog(@"ICU find/replace took %.3f seconds", [[NSDate date] timeIntervalSinceDate:preICUFindAndReplaceTime]); 
    65         NSLog(@"done"); 
    66          
    67         if([resultingStringUsingFoundation isEqualToString:resultingStringUsingIcu]) { 
    68                 NSLog(@"replacement resulted in the same string"); 
    69         } else 
    70                 NSLog(@"replacement resulted in a different string"); 
    71          
    72         [innerPool release]; 
    73 } 
  • trunk/source/ICUMatcher.h

    r3 r5  
    1111 
    1212@interface ICUMatcher : NSObject { 
    13  
     13        ICUPattern *pattern; 
    1414} 
    1515 
    16 -(BOOL)find; 
     16+(ICUMatcher *)matcherWithPattern:(ICUPattern *)p overString:(NSString *)stringToSearchOver; 
     17-(ICUMatcher *)initWithPattern:(ICUPattern *)p overString:(NSString *)stringToSearchOver; 
     18 
     19-(BOOL)findNext; 
    1720-(BOOL)findFromIndex:(unsigned)index; 
    1821-(NSString *)group; 
    1922-(NSString *)groupAtIndex:(unsigned)groupIndex; 
    2023-(unsigned)numberOfGroups; 
    21 -(BOOL)isAtEnd; 
    22 -(BOOL)patternMatchesPrefix; 
    23 -(BOOL)patternMatchesRegion; 
     24-(BOOL)lookingAt:(unsigned)index; 
    2425-(ICUPattern *)pattern; 
    25 -(BOOL)setMatchRegion:(NSRange)r
     26-(void)setPattern:(ICUPattern *)p
    2627-(NSString *)replaceAllWithString:(NSString *)aReplacementString; 
    2728-(NSString *)replaceFirstWithString:(NSString *)aReplacementString; 
  • trunk/source/ICUMatcher.m

    r3 r5  
    88 
    99#import "ICUMatcher.h" 
    10  
     10#import "NSStringICUAdditions.h" 
     11#import "ICUPattern.h" 
     12 
     13size_t InitialGroupSize = 128; 
     14 
     15struct URegularExpression; 
     16/** 
     17* Structure represeting a compiled regular rexpression, plus the results 
     18 *    of a match operation. 
     19 * @draft ICU 3.0 
     20 */ 
     21typedef struct URegularExpression URegularExpression; 
     22 
     23#define U_HIDE_DRAFT_API 1 
     24#define U_DISABLE_RENAMING 1 
     25 
     26#import <unicode/uregex.h> 
     27#import <unicode/ustring.h> 
     28 
     29#define CheckStatus(status)     if(U_FAILURE(status)) { [NSException raise:@"Find Exception" format:@"%s", u_errorName(status)]; } 
     30 
     31 
     32@interface ICUMatcher (Private) 
     33-(NSString *)performReplacementWithString:(NSString *)aReplacementString replaceAll:(BOOL)replacingAll; 
     34@end 
    1135 
    1236@implementation ICUMatcher 
    1337 
    14  
    15 -(BOOL)find 
    16 
     38+(ICUMatcher *)matcherWithPattern:(ICUPattern *)p overString:(NSString *)stringToSearchOver { 
     39        return [[[[ICUMatcher class] alloc] initWithPattern:p overString:stringToSearchOver] autorelease]; 
     40
     41 
     42-(ICUMatcher *)initWithPattern:(ICUPattern *)p overString:(NSString *)aStringToSearch; 
     43
     44        if(![super init]) 
     45                return nil; 
     46 
     47        [self setPattern:p]; 
     48        [[self pattern] setStringToSearch:aStringToSearch]; 
     49 
     50        return self; 
     51
     52 
     53-(void)dealloc 
     54
     55        [[self pattern] release]; 
     56 
     57        [super dealloc]; 
     58
     59 
     60-(void)setPattern:(ICUPattern *)p { 
     61        if([self pattern] != nil) 
     62                [[self pattern] release]; 
     63 
     64        pattern = [p retain]; 
     65
     66 
     67/* 
     68 Find the first matching substring of the input string that matches the pattern. 
     69  
     70 The search for a match begins at the specified index. If a match is found, uregex_start(), uregex_end(), and uregex_group() will provide more information regarding the match. 
     71 */ 
     72-(BOOL)findNext { 
     73        URegularExpression *re = [[self pattern] re]; 
     74        UErrorCode status = 0; 
     75        UBool r = uregex_findNext(re, &status); 
     76        CheckStatus(status); 
     77 
     78        return r; 
    1779} 
    1880 
    1981-(BOOL)findFromIndex:(unsigned)index 
    2082{ 
     83        URegularExpression *re = [[self pattern] re]; 
     84        [self reset]; 
     85 
     86        UErrorCode status = 0; 
     87        UBool r = uregex_find(re, index, &status); 
     88        CheckStatus(status); 
     89 
     90        return r; 
    2191} 
    2292 
    2393-(NSString *)group 
    2494{ 
     95        NSString *stringToMatch = [[self pattern] stringToSearch]; 
     96        return [stringToMatch substringWithRange:[self rangeOfMatch]]; 
    2597} 
    2698 
    2799-(NSString *)groupAtIndex:(unsigned)groupIndex 
    28100{ 
    29          
     101        size_t groupSize = InitialGroupSize; 
     102        URegularExpression *re = [[self pattern] re]; 
     103 
     104        while(YES) {  
     105                UErrorCode status = 0; 
     106                UChar *dest = calloc(groupSize, sizeof(UChar)); 
     107                int32_t buffSize = uregex_group(re, groupIndex, dest, groupSize, &status); 
     108 
     109                if(U_BUFFER_OVERFLOW_ERROR == status) { 
     110                        groupSize *= 2; 
     111                        free(dest); 
     112                        continue; 
     113                } 
     114 
     115                CheckStatus(status); 
     116 
     117                groupSize = InitialGroupSize; // reset to default 
     118                NSString *result = [[[NSString alloc] initWithBytes:dest length:buffSize*sizeof(UChar) encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]; 
     119                free(dest); 
     120                return result; 
     121        } 
    30122} 
    31123 
    32124-(unsigned)numberOfGroups 
    33125{ 
    34 
    35  
    36 -(BOOL)isAtEnd 
    37 
    38 
    39  
    40 -(BOOL)patternMatchesPrefix 
    41 
    42 
    43  
    44 -(BOOL)patternMatchesRegion 
    45 
    46 
    47  
    48 -(ICUPattern *)pattern 
    49 
    50 
    51  
    52 -(BOOL)setMatchRegion:(NSRange)r 
    53 
    54 
    55  
    56 -(NSString *)replaceAllWithString:(NSString *)aReplacementString 
    57 
    58 
    59  
    60 -(NSString *)replaceFirstWithString:(NSString *)aReplacementString 
    61 
    62 
    63  
    64 -(void)reset 
    65 
     126        URegularExpression *re = [[self pattern] re]; 
     127        UErrorCode status = 0; 
     128        int numberOfGroups = uregex_groupCount(re, &status); 
     129        CheckStatus(status); 
     130         
     131        return numberOfGroups; 
     132
     133 
     134-(BOOL)lookingAt:(unsigned)index { 
     135        UErrorCode status = 0; 
     136        URegularExpression *re = [[self pattern] re]; 
     137        BOOL matches = uregex_lookingAt(re, 0, &status); 
     138        CheckStatus(status); 
     139        return matches; 
     140
     141 
     142-(ICUPattern *)pattern { 
     143        return pattern; 
     144
     145 
     146-(NSString *)performReplacementWithString:(NSString *)aReplacementString replaceAll:(BOOL)replacingAll { 
     147        UErrorCode status = 0; 
     148        UChar *replacementText = [aReplacementString UTF16String]; 
     149        URegularExpression *re = [[self pattern] re]; 
     150        int searchTextLength = [[[self pattern] stringToSearch] length]; 
     151         
     152        BOOL replacementCompleted = NO; 
     153        int resultLength = 0; 
     154        size_t destStringBufferSize = searchTextLength * 2; 
     155        UChar *destString = NULL; 
     156        while(!replacementCompleted) { 
     157                 
     158                destString = calloc(destStringBufferSize, sizeof(UChar)); 
     159                if(replacingAll) 
     160                        resultLength = uregex_replaceAll(re, replacementText, -1, destString, destStringBufferSize, &status); 
     161                else 
     162                        resultLength = uregex_replaceFirst(re, replacementText, -1, destString, destStringBufferSize, &status); 
     163 
     164                if(status == U_BUFFER_OVERFLOW_ERROR) { 
     165                        status = 0; 
     166                        free(destString); 
     167                        destStringBufferSize *= 2; 
     168                } 
     169                else if(U_FAILURE(status)) { 
     170                        free(destString); 
     171                        [NSException raise:@"Find Exception" 
     172                                                format:@"Could not perform find and replace: %s", u_errorName(status)]; 
     173                } else { 
     174                        replacementCompleted = YES; 
     175                } 
     176        } 
     177         
     178        NSString *result = [[[NSString alloc] initWithBytes:destString 
     179                                                                                                 length:resultLength * sizeof(UChar) 
     180                                                                                           encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]; 
     181        free(destString); 
     182        return result;   
     183
     184 
     185 
     186-(NSString *)replaceAllWithString:(NSString *)aReplacementString { 
     187        return [self performReplacementWithString:aReplacementString replaceAll:YES]; 
     188
     189 
     190-(NSString *)replaceFirstWithString:(NSString *)aReplacementString { 
     191        return [self performReplacementWithString:aReplacementString replaceAll:NO]; 
     192
     193 
     194-(void)reset { 
     195        [[self pattern] reset]; 
    66196} 
    67197 
    68198-(NSRange)rangeOfMatch 
    69199{ 
     200        return [self rangeOfMatchGroup:0]; 
    70201} 
    71202 
    72203-(NSRange)rangeOfMatchGroup:(unsigned)groupNumber 
    73204{ 
    74 
    75  
    76  
     205        UErrorCode status = 0; 
     206        URegularExpression *re = [[self pattern] re]; 
     207        int start = uregex_start(re, groupNumber, &status); 
     208        CheckStatus(status); 
     209         
     210        int end = uregex_end(re, groupNumber, &status); 
     211        CheckStatus(status); 
     212        return NSMakeRange(start, end-start); 
     213
    77214 
    78215@end 
  • trunk/source/ICUPattern.h

    r2 r5  
    2121 
    2222@interface ICUPattern: NSObject <NSCopying> { 
    23         void *pattern
     23        void *re
    2424        void *textToSearch; 
    2525        unsigned flags; 
     
    3232-(id)initWithString:(NSString *)aPattern flags:(unsigned)flags; 
    3333 
    34 +(ICUMatcher *)matcherForString:(NSString *)stringToSearchOver; 
    35  
    36 -(void *)pattern; 
    37  
    38 /* no retain done.  the life of the text is given by the caller */ 
    39 -(void)setTextToSearch:(NSString *)s; 
    40 -(void *)textToSearch; 
    41  
    42  
     34-(NSArray *)componentsSplitFromString:(NSString *)stringToSplit; 
     35-(BOOL)matchesString:(NSString *)stringToMatchAgainst; 
     36-(NSString *)pattern; 
     37-(void)setStringToSearch:(NSString *)aStringToSearchOver; 
     38-(NSString *)stringToSearch; 
    4339-(void)reset; 
    4440 
     41-(void *)re; 
    4542@end 
  • trunk/source/ICUPattern.m

    r2 r5  
    77// 
    88// more info: http://icu.sourceforge.net/apiref/icu4c/uregex_8h.html 
     9// 
     10// inspiration: http://java.sun.com/j2se/1.5.0/docs/api/index.html?java/util/regex/Pattern.html 
     11// 
    912 
    1013#import "ICUPattern.h" 
     
    3235 
    3336@interface ICUPattern (Private) 
    34 -(void)setPattern:(void *)p; 
     37-(void)setRe:(URegularExpression *)p; 
    3538-(unsigned)flags; 
    3639-(UChar *)textToSearch; 
     40//-(URegularExpression *)re; 
     41-(void)setTextToSearch:(UChar *)utf16String; 
     42 
    3743@end 
    3844 
     
    5460        textToSearch = NULL; 
    5561        flags = f; 
    56          
     62 
    5763        UParseError err; 
    5864        UErrorCode status = 0; 
     
    6571        } 
    6672 
    67         [self setPattern:e]; 
     73        [self setRe:e]; 
    6874 
    6975        return self;     
     
    7682-(void)dealloc { 
    7783 
    78         if(pattern != NULL) 
    79                 free(pattern); 
     84        if(re != NULL) 
     85                free(re); 
    8086 
    8187        [super dealloc]; 
    8288} 
    8389 
     90-(NSString *)stringToSearch 
     91{ 
     92        return [NSString stringWithUTF16String:[self textToSearch]]; 
     93} 
     94 
     95-(void)setStringToSearch:(NSString *)aStringToSearchOver 
     96{ 
     97        [self setTextToSearch:[aStringToSearchOver UTF16String]]; 
     98} 
     99 
     100-(void)setTextToSearch:(UChar *)utf16String { 
     101        UErrorCode status = 0; 
     102 
     103        uregex_setText([self re], utf16String, -1, &status); 
     104         
     105        textToSearch = utf16String; 
     106         
     107        if(U_FAILURE(status)) { 
     108                textToSearch = NULL; 
     109                [NSException raise:@"Invalid String Exception" 
     110                                        format:@"Could not set text to match against: %s", u_errorName(status)]; 
     111        } 
     112} 
     113 
     114-(UChar *)textToSearch { 
     115        return (UChar *)textToSearch; 
     116} 
     117 
    84118- (id)copyWithZone:(NSZone *)zone { 
    85119 
     
    87121 
    88122        UErrorCode status = 0; 
    89         URegularExpression *r = uregex_clone([self pattern], &status); 
     123        URegularExpression *r = uregex_clone([self re], &status); 
    90124        if(U_FAILURE(status)) 
    91125                [NSException raise:@"Copy Exception" 
    92126                                        format:@"Could not copy pattern: %s", u_errorName(status)]; 
    93127 
    94         [p setTextToSearch:[self textToSearch]]; // no copy! 
    95         [p setPattern:r]; 
     128        [p setRe:r]; 
    96129 
    97130        return p; 
    98131} 
    99132 
    100  
    101133-(void)reset { 
    102134        UErrorCode status = 0; 
    103         uregex_reset([self pattern], 0, &status); 
     135        uregex_reset([self re], 0, &status); 
    104136 
    105137        if(U_FAILURE(status)) { 
     
    113145} 
    114146 
    115 -(void)setTextToSearch:(NSString *)s { 
    116         UErrorCode status = 0; 
    117         URegularExpression *re = [self pattern]; 
    118  
    119         UChar *aString = [s UTF16String]; 
    120          
    121         uregex_setText(re, aString, -1, &status); 
    122  
    123         textToSearch = aString; 
    124  
    125         if(U_FAILURE(status)) { 
    126                 [NSException raise:@"Invalid String Exception" 
    127                                         format:@"Could not set text to match against: %s", u_errorName(status)]; 
    128         } 
    129 
    130  
    131 -(void *)textToSearch { 
    132         return textToSearch; 
    133 
    134  
    135 -(void *)pattern { 
    136         return pattern; 
    137 
    138  
    139 -(void)setPattern:(void *)p { 
    140         if(pattern != NULL) 
    141                 free(pattern); 
    142  
    143         pattern = p; 
     147-(NSString *)pattern { 
     148        return [self description]; 
     149
     150 
     151-(void)setRe:(URegularExpression *)p { 
     152        if(re != NULL) 
     153                free(re); 
     154 
     155        re = p; 
     156
     157 
     158-(void *)re 
     159
     160        return re; 
    144161} 
    145162 
    146163-(NSString *)description { 
    147164 
    148         if([self pattern] != NULL) { 
     165        if([self re] != NULL) { 
    149166                UChar *p = NULL; 
    150167                UErrorCode status = 0; 
    151168                int len = 0; 
    152                 p = (UChar *)uregex_pattern([self pattern], &len, &status); 
     169                p = (UChar *)uregex_pattern([self re], &len, &status); 
    153170 
    154171                if(U_FAILURE(status)) { 
     
    163180} 
    164181 
     182-(NSArray *)componentsSplitFromString:(NSString *)stringToSplit 
     183{ 
     184        [self setTextToSearch:[stringToSplit UTF16String]]; 
     185        BOOL isDone = NO; 
     186        UErrorCode status = 0; 
     187 
     188        NSMutableArray *results = [NSMutableArray array]; 
     189        int destFieldsCapacity = 2; 
     190        size_t destCapacity = u_strlen([self textToSearch]); 
     191 
     192        while(!isDone) { 
     193                UChar *destBuf = calloc(destCapacity, sizeof(UChar)); 
     194                int requiredCapacity = 0; 
     195                UChar *destFields[destFieldsCapacity]; 
     196                int numberOfComponents = uregex_split([self re], 
     197                                                                                          destBuf, 
     198                                                                                          destCapacity, 
     199                                                                                          &requiredCapacity, 
     200                                                                                          destFields, 
     201                                                                                          destFieldsCapacity, 
     202                                                                                          &status); 
     203 
     204                if(status == U_BUFFER_OVERFLOW_ERROR) { // buffer was too small, grow it 
     205                        free(destBuf); 
     206                        NSAssert(destCapacity * 2 < INT_MAX, @"Overflow occurred splitting string."); 
     207                        destCapacity = (destCapacity < requiredCapacity) ? requiredCapacity : destCapacity * 2; 
     208                        status = 0; 
     209                } else if(destFieldsCapacity == numberOfComponents) { 
     210                        destFieldsCapacity *= 2; 
     211                        NSAssert(destFieldsCapacity *2 < INT_MAX, @"Overflow occurred splitting string."); 
     212                        free(destBuf); 
     213                        status = 0; 
     214                } else if(U_FAILURE(status)) { 
     215                        free(destBuf); 
     216                        isDone = YES; 
     217                } else { 
     218                        int i; 
     219                         
     220                        for(i=0; i<numberOfComponents; i++) { 
     221                                NSAssert(i < destFieldsCapacity, @"Unexpected number of components found in split."); 
     222                                UChar *offsetStart = destFields[i];                                      
     223                                [results addObject:[NSString stringWithUTF16String:offsetStart]]; 
     224                        } 
     225                        isDone = YES; 
     226                } 
     227        } 
     228 
     229        if(U_FAILURE(status)) 
     230                [NSException raise:@"Split Exception" 
     231                                        format:@"Unable to split string: %@", u_errorName(status)]; 
     232 
     233        return [NSArray arrayWithArray:results];         
     234} 
     235 
     236-(BOOL)matchesString:(NSString *)stringToMatchAgainst 
     237{ 
     238        [self setTextToSearch:[stringToMatchAgainst UTF16String]]; 
     239 
     240        UErrorCode status = 0; 
     241        BOOL matches = uregex_matches([self re], 0, &status); 
     242        if(U_FAILURE(status)) { 
     243                [NSException raise:@"Match Exception" 
     244                                        format:@"Could not perform match: %s", u_errorName(status)]; 
     245        } 
     246 
     247        return matches;  
     248} 
     249 
    165250@end 
  • trunk/source/NSStringICUAdditions.h

    r2 r5  
    1212@interface NSString (NSStringICUAdditions) 
    1313 
    14 -(NSArray *)findPatternString:(NSString *)p; 
    15 -(NSArray *)findPattern:(ICUPattern *)p; 
    16  
    17 -(NSString *)findPattern:(ICUPattern *)p replaceAllWith:(NSString *)replacementString; 
    18  
    19 -(BOOL)matchesPattern:(ICUPattern *)p; 
    20 -(BOOL)matchesPatternString:(NSString *)anExpression; 
    21  
    22 -(BOOL)findNext; 
    23 -(NSRange *)rangeOfCurrentMatch; 
    24  
    25 -(NSArray *)componentsSeparatedByPattern:(ICUPattern *)p; 
    26 -(NSArray *)componentsSeparatedByPatternString:(NSString *)s; 
    27  
     14+(NSString *)stringWithUTF16String:(void *)utf16EncodedString; 
    2815-(void *)UTF16String; 
    2916 
  • trunk/source/NSStringICUAdditions.m

    r3 r5  
    2222#import <unicode/uregex.h> 
    2323 
    24 size_t InitialGroupSize = 128; 
     24 
    2525 
    2626@interface NSString (NSStringICUPrivateAdditions) 
    2727@end 
    2828 
    29 @implementation NSString (NSStringICUAdditions) 
     29@implementation NSString (NSStringICUAdditions)// 
     30// 
     31//-(NSArray *)findPattern:(ICUPattern *)p { 
     32//      [p setStringToSearch:self]; 
     33// 
     34//      UErrorCode status = 0; 
     35//      int32_t numberOfGroups = uregex_groupCount((URegularExpression *)[p pattern], &status); 
     36//       
     37//      if(U_FAILURE(status)) { 
     38//              [NSException raise:@"Find Exception" 
     39//                                      format:@"%s", u_errorName(status)]; 
     40//      } 
     41// 
     42//      BOOL match = uregex_matches([p pattern], 0, &status); 
     43//      if(U_FAILURE(status)) { 
     44//              [NSException raise:@"Find Exception" 
     45//                                      format:@"%s", u_errorName(status)]; 
     46//      } 
     47// 
     48//      if(!match) 
     49//              return [NSArray array]; 
     50// 
     51//      NSMutableArray *results = [NSMutableArray array]; 
     52//      int i; 
     53// 
     54//      size_t groupSize = InitialGroupSize; 
     55//      for(i=0; i<numberOfGroups+1; i++) { 
     56//              status = 0; 
     57//              UChar *dest = calloc(groupSize, sizeof(UChar)); 
     58//              int32_t buffSize = uregex_group([p pattern], i, dest, groupSize, &status); 
     59//               
     60//              if(U_BUFFER_OVERFLOW_ERROR == status) { 
     61//                      groupSize *= 2; 
     62//                      free(dest); 
     63//                      i--; 
     64//                      continue; 
     65//              } 
     66//              else if(U_FAILURE(status)) { 
     67//                      [NSException raise:@"Find Exception" 
     68//                                              format:@"%s", u_errorName(status)]; 
     69//              } 
     70// 
     71//              groupSize = InitialGroupSize; // reset to default 
     72//              [results addObject:[[[NSString alloc] initWithBytes:dest length:buffSize*sizeof(UChar) encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]]; 
     73//              free(dest); 
     74//      } 
     75// 
     76//      return [NSArray arrayWithArray:results]; 
     77//} 
    3078 
    31 -(NSString *)findPatternString:(NSString *)p replaceAllWith:(NSString *)replacementString { 
    32         ICUPattern *pattern = [ICUPattern patternWithString:p]; 
    33         return [self findPattern:pattern replaceAllWith:replacementString]; 
    34 } 
    3579 
    36 -(NSArray *)findPatternString:(NSString *)p { 
    37         ICUPattern *pattern = [ICUPattern patternWithString:p]; 
    38         return [self findPattern:pattern]; 
    39 
    40  
    41 -(NSArray *)findPattern:(ICUPattern *)p { 
    42         [p setTextToSearch:self]; 
    43  
    44         UErrorCode status = 0; 
    45         int32_t numberOfGroups = uregex_groupCount((URegularExpression *)[p pattern], &status); 
    46          
    47         if(U_FAILURE(status)) { 
    48                 [NSException raise:@"Find Exception" 
    49                                         format:@"%s", u_errorName(status)]; 
    50         } 
    51  
    52         BOOL match = uregex_matches([p pattern], 0, &status); 
    53         if(U_FAILURE(status)) { 
    54                 [NSException raise:@"Find Exception" 
    55                                         format:@"%s", u_errorName(status)]; 
    56         } 
    57  
    58         if(!match) 
    59                 return [NSArray array]; 
    60  
    61         NSMutableArray *results = [NSMutableArray array]; 
    62         int i; 
    63  
    64         size_t groupSize = InitialGroupSize; 
    65         for(i=0; i<numberOfGroups+1; i++) { 
    66                 status = 0; 
    67                 UChar *dest = calloc(groupSize, sizeof(UChar)); 
    68                 int32_t buffSize = uregex_group([p pattern], i, dest, groupSize, &status); 
    69                  
    70                 if(U_BUFFER_OVERFLOW_ERROR == status) { 
    71                         groupSize *= 2; 
    72                         free(dest); 
    73                         i--; 
    74                         continue; 
    75                 } 
    76                 else if(U_FAILURE(status)) { 
    77                         [NSException raise:@"Find Exception" 
    78                                                 format:@"%s", u_errorName(status)]; 
    79                 } 
    80  
    81                 groupSize = InitialGroupSize; // reset to default 
    82                 [results addObject:[[[NSString alloc] initWithBytes:dest length:buffSize*sizeof(UChar) encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]]; 
    83                 free(dest); 
    84         } 
    85  
    86         return [NSArray arrayWithArray:results]; 
    87 
    88  
    89 -(NSString *)findPattern:(ICUPattern *)p replaceAllWith:(NSString *)replacementString { 
    90         [p setTextToSearch:self]; 
    91          
    92         UErrorCode status = 0; 
    93         UChar *replacementText = [replacementString UTF16String]; 
    94  
    95         BOOL replacementCompleted = NO; 
    96         int32_t resultLength = 0; 
    97         size_t destStringBufferSize = [self length] * 2; 
    98         UChar *destString = NULL; 
    99         while(!replacementCompleted) { 
    100  
    101                 destString = calloc(destStringBufferSize, sizeof(UChar)); 
    102                 resultLength = uregex_replaceAll([p pattern], replacementText, -1, destString, destStringBufferSize, &status); 
    103  
    104                 if(status == U_BUFFER_OVERFLOW_ERROR) { 
    105                         status = 0; 
    106                         free(destString); 
    107                         destStringBufferSize *= 2; 
    108                 } 
    109                 else if(U_FAILURE(status)) { 
    110                         free(destString); 
    111                         [NSException raise:@"Find and Replace All Exception" 
    112                                                 format:@"Could not perform find and replace: %s", u_errorName(status)]; 
    113                 } else { 
    114                         replacementCompleted = YES; 
    115                 } 
    116         } 
    117  
    118         NSString *result = [[[NSString alloc] initWithBytes:destString 
    119                                                                                                  length:resultLength * sizeof(UChar) 
    120                                                                                            encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]; 
    121         free(destString); 
    122         return result; 
    123 
    124  
    125 -(BOOL)findNext 
     80+(NSString *)stringWithUTF16String:(void *)utf16EncodedString 
    12681{ 
    127         UErrorCode status = 0; 
    128 //      BOOL r = uregex_findNext([ 
    129 
    130  
    131 -(NSRange *)rangeOfCurrentMatch 
    132 
    133          
    134 
    135  
    136 -(NSArray *)componentsSeparatedByPatternString:(NSString *)s 
    137 
    138         return [self componentsSeparatedByPattern:[ICUPattern patternWithString:s]]; 
    139 
    140  
    141 -(NSArray *)componentsSeparatedByPattern:(ICUPattern *)p { 
    142         [p setTextToSearch:self]; 
    143         BOOL isDone = NO; 
    144         UErrorCode status = 0; 
    145  
    146         NSMutableArray *results = [NSMutableArray array]; 
    147         int destFieldsCapacity = 2; 
    148         size_t destCapacity = u_strlen([p textToSearch]); 
    149  
    150         while(!isDone) { 
    151                 UChar *destBuf = calloc(destCapacity, sizeof(UChar)); 
    152                 int requiredCapacity = 0; 
    153                 UChar *destFields[destFieldsCapacity]; 
    154                 int numberOfComponents = uregex_split([p pattern], 
    155                                                                                           destBuf, 
    156                                                                                           destCapacity, 
    157                                                                                           &requiredCapacity, 
    158                                                                                           destFields, 
    159                                                                                           destFieldsCapacity, 
    160                                                                                           &status); 
    161  
    162                 if(status == U_BUFFER_OVERFLOW_ERROR) { // buffer was too small, grow it 
    163                         free(destBuf); 
    164                         NSAssert(destCapacity * 2 < INT_MAX, @"Overflow occurred splitting string."); 
    165                         destCapacity = (destCapacity < requiredCapacity) ? requiredCapacity : destCapacity * 2; 
    166                         status = 0; 
    167                 } else if(destFieldsCapacity == numberOfComponents) { 
    168                         destFieldsCapacity *= 2; 
    169                         NSAssert(destFieldsCapacity *2 < INT_MAX, @"Overflow occurred splitting string."); 
    170                         free(destBuf); 
    171                         status = 0; 
    172                 } else if(U_FAILURE(status)) { 
    173                         free(destBuf); 
    174                         isDone = YES; 
    175                 } else { 
    176                         int i; 
    177  
    178                         for(i=0; i<numberOfComponents; i++) { 
    179                                 NSAssert(i < destFieldsCapacity, @"Unexpected number of components found in split."); 
    180                                 UChar *offsetStart = destFields[i];                                      
    181  
    182                                 NSString *component = [[[NSString alloc] initWithBytes:offsetStart  
    183                                                                                                                                 length:u_strlen(offsetStart)*sizeof(UChar)  
    184                                                                                                                           encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]; 
    185                                 [results addObject:component]; 
    186                         } 
    187                         isDone = YES; 
    188                 } 
    189         } 
    190  
    191         if(U_FAILURE(status)) 
    192                 [NSException raise:@"Split Exception" 
    193                                         format:@"Unable to split string: %@", u_errorName(status)]; 
    194  
    195         return [NSArray arrayWithArray:results]; 
     82        return [[[NSString alloc] initWithBytes:utf16EncodedString  
     83                                                                         length:u_strlen(utf16EncodedString)*sizeof(UChar)  
     84                                                                   encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease];     
    19685} 
    19786 
     
    20594} 
    20695 
    207 -(BOOL)matchesPattern:(ICUPattern *)p { 
    208         [p setTextToSearch:self]; 
    209  
    210         UErrorCode status = 0; 
    211         BOOL matches = uregex_matches([p pattern], 0, &status); 
    212         if(U_FAILURE(status)) { 
    213                 [NSException raise:@"Match Exception" 
    214                                         format:@"Could not perform match: %s", u_errorName(status)]; 
    215         } 
    216  
    217         return matches;  
    218 } 
    219  
    220 -(BOOL)matchesPatternString:(NSString *)anExpression { 
    221         return [self matchesPattern:[ICUPattern patternWithString:anExpression]]; 
    222 } 
    223  
    22496@end