2010-12-16 10:59:50 +00:00
|
|
|
/** Implementation of GSICUString for GNUStep
|
|
|
|
|
|
|
|
Copyright (C) 2010 Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
This file is part of the GNUstep Base Library.
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Lesser General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2019-12-09 23:36:00 +00:00
|
|
|
Lesser General Public License for more details.
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
2019-12-09 23:36:00 +00:00
|
|
|
Boston, MA 02110 USA.
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
$Date: 2010-09-18 16:09:58 +0100 (Sat, 18 Sep 2010) $ $Revision: 31371 $
|
|
|
|
*/
|
|
|
|
|
2010-12-16 10:09:43 +00:00
|
|
|
#import "common.h"
|
|
|
|
#if GS_USE_ICU == 1
|
2010-11-18 22:52:36 +00:00
|
|
|
#import "GSICUString.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The number of characters that we use per chunk when fetching a block of
|
|
|
|
* characters at once for iteration. Making this value larger will make UText
|
|
|
|
* iteration faster, at the cost of more memory. Making it larger than the
|
|
|
|
* size of a typical string will make it no faster but will still cost memory.
|
|
|
|
*/
|
|
|
|
static const NSUInteger chunkSize = 32;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the number of UTF16 characters in a UText backed by an NSString.
|
|
|
|
*/
|
2010-12-16 10:59:50 +00:00
|
|
|
static int64_t
|
|
|
|
UTextNSStringNativeLength(UText *ut)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2016-07-01 15:22:02 +00:00
|
|
|
/* For constant strings the length is stored in ut->c, but for mutable
|
|
|
|
* strings this is set to -1 and we must check the length every time.
|
|
|
|
*/
|
|
|
|
return (-1 == ut->c) ? [(NSString*)ut->p length] : ut->c;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Loads a group of characters into the buffer that can be directly accessed by
|
|
|
|
* users of the UText. This is used for iteration but UText users.
|
|
|
|
*/
|
2010-12-16 10:59:50 +00:00
|
|
|
UBool
|
|
|
|
UTextNSStringAccess(UText *ut, int64_t nativeIndex, UBool forward)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
NSString *str = (NSString*)ut->p;
|
2016-07-12 08:18:35 +00:00
|
|
|
NSInteger length = (-1 == ut->c) ? (NSInteger)[str length] : ut->c;
|
|
|
|
NSInteger nativeStart = ut->chunkNativeStart;
|
|
|
|
NSInteger nativeLimit = ut->chunkNativeLimit;
|
2010-12-16 10:59:50 +00:00
|
|
|
NSRange r;
|
|
|
|
|
|
|
|
if (forward)
|
|
|
|
{
|
2016-07-01 12:33:11 +00:00
|
|
|
if (nativeIndex < nativeLimit && nativeIndex >= nativeStart)
|
2016-06-30 14:21:32 +00:00
|
|
|
{
|
|
|
|
/* The chunk already contains the index, set the offset
|
|
|
|
* to match it.
|
|
|
|
*/
|
2016-07-01 12:33:11 +00:00
|
|
|
ut->chunkOffset = nativeIndex - nativeStart;
|
2016-06-30 14:21:32 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nativeIndex >= length && nativeLimit >= length)
|
|
|
|
{
|
|
|
|
/* Asking for a position beyond the end of the string;
|
|
|
|
* Limit it to point just after the last character.
|
|
|
|
*/
|
|
|
|
ut->chunkOffset = ut->chunkLength;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set up to fill the chunk with characters from the string
|
|
|
|
* and to start at the beginning of that buffer.
|
|
|
|
*/
|
|
|
|
nativeStart = nativeIndex;
|
|
|
|
nativeLimit = nativeIndex + chunkSize;
|
|
|
|
if (nativeLimit > length)
|
|
|
|
{
|
|
|
|
nativeLimit = length;
|
|
|
|
}
|
|
|
|
r.location = nativeIndex;
|
|
|
|
r.length = nativeLimit - nativeIndex;
|
|
|
|
ut->chunkOffset = 0;
|
2010-12-16 10:59:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-07-01 12:33:11 +00:00
|
|
|
if (nativeIndex <= nativeLimit && nativeIndex > nativeStart)
|
2016-06-30 14:21:32 +00:00
|
|
|
{
|
|
|
|
/* The chunk already contains the index, set the offset
|
|
|
|
* to match it.
|
|
|
|
*/
|
2016-07-01 12:33:11 +00:00
|
|
|
ut->chunkOffset = nativeIndex - nativeStart;
|
2016-06-30 14:21:32 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nativeIndex <= 0 && nativeStart <= 0)
|
|
|
|
{
|
|
|
|
/* Asking for a position beyond the start of the string;
|
|
|
|
* Limit it to position of the first character.
|
|
|
|
*/
|
|
|
|
ut->chunkOffset = 0;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nativeLimit = nativeIndex;
|
|
|
|
if (nativeLimit > length)
|
|
|
|
{
|
|
|
|
nativeLimit = length;
|
|
|
|
}
|
2016-07-12 08:18:35 +00:00
|
|
|
nativeStart = nativeLimit - chunkSize;
|
|
|
|
if (nativeStart < 0)
|
2016-06-30 14:21:32 +00:00
|
|
|
{
|
|
|
|
nativeStart = 0;
|
|
|
|
}
|
|
|
|
r.location = nativeStart;
|
|
|
|
r.length = nativeLimit - nativeStart;
|
|
|
|
ut->chunkOffset = r.length;
|
2010-12-16 10:59:50 +00:00
|
|
|
}
|
|
|
|
[str getCharacters: ut->pExtra range: r];
|
2016-06-30 14:21:32 +00:00
|
|
|
ut->chunkNativeLimit = nativeLimit;
|
|
|
|
ut->chunkNativeStart = nativeStart;
|
2017-02-11 14:24:58 +00:00
|
|
|
ut->nativeIndexingLimit = r.length;
|
2010-12-16 10:59:50 +00:00
|
|
|
ut->chunkLength = r.length;
|
|
|
|
return TRUE;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
Added implementation of NSRegularExpression, from iOS 4 Foundation.
This class is a thin wrapper around libicu regular expressions, so if we don't
have libicu we simply don't compile it at all. This will give people a linker
failure, rather than a nonfunctional class if they try to use GNUstep without
ICU with code that requires it.
The Apple documentation says that this class has a primitive method that takes
a block as an argument and that this method is called by others, so subclasses
can replace that block method without touching the convenience methods. We
mimic this behaviour when compiling with block, but when compiling without them
it's a problem. The current code contains some ugly hacks that will work in
normal usage but break with subclassing when not compiling with blocks.
This commit also includes a partial implementation of NSTextCheckingResult,
implementing the subset of its functionality required for NSRegularExpression
to work.
It also includes numerous fixes to GSICUString. This is heavily used by
NSRegularExpression, to avoid copying strings when mapping between UText for
libicu and NSString for GNUstep.
Note: I don't have a copy of iOS anywhere to test this against, so it's
entirely possible that there are significant discrepancies between this
implementation of NSRegularExpression and the iOS version. This version should
function exactly as the iOS one is described as functioning, but I think we've
all seen that Apple documentation refers more to hopes than facts. Any testing
that someone who does have an ip{hone,od,ad} can do is very welcome.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31635 72102866-910b-0410-8b05-ffd578937521
2010-11-19 22:06:18 +00:00
|
|
|
/**
|
|
|
|
* Replaces characters in an NSString-backed UText.
|
|
|
|
*/
|
2010-12-16 10:59:50 +00:00
|
|
|
static int32_t
|
|
|
|
UTextNSMutableStringReplace(UText *ut,
|
|
|
|
int64_t nativeStart,
|
|
|
|
int64_t nativeLimit,
|
|
|
|
const UChar *replacementText,
|
|
|
|
int32_t replacmentLength,
|
|
|
|
UErrorCode *status)
|
Added implementation of NSRegularExpression, from iOS 4 Foundation.
This class is a thin wrapper around libicu regular expressions, so if we don't
have libicu we simply don't compile it at all. This will give people a linker
failure, rather than a nonfunctional class if they try to use GNUstep without
ICU with code that requires it.
The Apple documentation says that this class has a primitive method that takes
a block as an argument and that this method is called by others, so subclasses
can replace that block method without touching the convenience methods. We
mimic this behaviour when compiling with block, but when compiling without them
it's a problem. The current code contains some ugly hacks that will work in
normal usage but break with subclassing when not compiling with blocks.
This commit also includes a partial implementation of NSTextCheckingResult,
implementing the subset of its functionality required for NSRegularExpression
to work.
It also includes numerous fixes to GSICUString. This is heavily used by
NSRegularExpression, to avoid copying strings when mapping between UText for
libicu and NSString for GNUstep.
Note: I don't have a copy of iOS anywhere to test this against, so it's
entirely possible that there are significant discrepancies between this
implementation of NSRegularExpression and the iOS version. This version should
function exactly as the iOS one is described as functioning, but I think we've
all seen that Apple documentation refers more to hopes than facts. Any testing
that someone who does have an ip{hone,od,ad} can do is very welcome.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31635 72102866-910b-0410-8b05-ffd578937521
2010-11-19 22:06:18 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
NSMutableString *str = (NSMutableString*)ut->p;
|
|
|
|
NSRange r = NSMakeRange(nativeStart, nativeLimit-nativeStart);
|
|
|
|
NSString *replacement = [NSString alloc];
|
|
|
|
|
|
|
|
if (replacmentLength < 0)
|
|
|
|
{
|
|
|
|
replacement = [replacement initWithCString: (const char*)replacementText
|
|
|
|
encoding: NSUTF16StringEncoding];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-07-01 15:22:02 +00:00
|
|
|
replacement = [replacement
|
|
|
|
initWithCharactersNoCopy: (unichar*)replacementText
|
|
|
|
length: replacmentLength
|
|
|
|
freeWhenDone: NO];
|
2010-12-16 10:59:50 +00:00
|
|
|
}
|
|
|
|
[str replaceCharactersInRange: r withString: replacement];
|
|
|
|
|
|
|
|
// Setting the chunk length to 0 here forces UTextNSStringAccess to fetch
|
|
|
|
// the data from the string object.
|
|
|
|
ut->chunkLength = 0;
|
|
|
|
UTextNSStringAccess(ut, r.location + [replacement length] + 1, TRUE);
|
|
|
|
ut->chunkOffset++;
|
|
|
|
|
|
|
|
[replacement release];
|
|
|
|
if (NULL != status)
|
|
|
|
{
|
|
|
|
*status = 0;
|
|
|
|
}
|
|
|
|
return 0;
|
Added implementation of NSRegularExpression, from iOS 4 Foundation.
This class is a thin wrapper around libicu regular expressions, so if we don't
have libicu we simply don't compile it at all. This will give people a linker
failure, rather than a nonfunctional class if they try to use GNUstep without
ICU with code that requires it.
The Apple documentation says that this class has a primitive method that takes
a block as an argument and that this method is called by others, so subclasses
can replace that block method without touching the convenience methods. We
mimic this behaviour when compiling with block, but when compiling without them
it's a problem. The current code contains some ugly hacks that will work in
normal usage but break with subclassing when not compiling with blocks.
This commit also includes a partial implementation of NSTextCheckingResult,
implementing the subset of its functionality required for NSRegularExpression
to work.
It also includes numerous fixes to GSICUString. This is heavily used by
NSRegularExpression, to avoid copying strings when mapping between UText for
libicu and NSString for GNUstep.
Note: I don't have a copy of iOS anywhere to test this against, so it's
entirely possible that there are significant discrepancies between this
implementation of NSRegularExpression and the iOS version. This version should
function exactly as the iOS one is described as functioning, but I think we've
all seen that Apple documentation refers more to hopes than facts. Any testing
that someone who does have an ip{hone,od,ad} can do is very welcome.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31635 72102866-910b-0410-8b05-ffd578937521
2010-11-19 22:06:18 +00:00
|
|
|
}
|
|
|
|
|
2010-11-18 22:52:36 +00:00
|
|
|
/**
|
|
|
|
* Reads some characters. This is roughly analogous to NSString's
|
|
|
|
* -getCharacters:range:.
|
|
|
|
*/
|
2010-12-16 10:59:50 +00:00
|
|
|
static int32_t
|
|
|
|
UTextNSStringExtract(UText *ut,
|
|
|
|
int64_t nativeStart,
|
|
|
|
int64_t nativeLimit,
|
|
|
|
UChar *dest,
|
|
|
|
int32_t destCapacity,
|
|
|
|
UErrorCode *status)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
/* If we're loading no characters, we are expected to return the number of
|
|
|
|
* characters that we could load if requested.
|
|
|
|
*/
|
2016-07-01 15:22:02 +00:00
|
|
|
if (destCapacity <= 0)
|
2010-12-16 10:59:50 +00:00
|
|
|
{
|
|
|
|
return nativeLimit - nativeStart;
|
|
|
|
}
|
2016-07-01 15:22:02 +00:00
|
|
|
else
|
2010-12-16 10:59:50 +00:00
|
|
|
{
|
2016-07-01 15:22:02 +00:00
|
|
|
NSString *str = (NSString*)ut->p;
|
|
|
|
NSUInteger length = (-1 == ut->c) ? [str length] : ut->c;
|
|
|
|
NSRange r;
|
|
|
|
|
|
|
|
if (nativeLimit > length)
|
|
|
|
{
|
|
|
|
nativeLimit = length;
|
|
|
|
}
|
|
|
|
r = NSMakeRange(nativeStart, nativeLimit - nativeStart );
|
|
|
|
if (destCapacity < r.length)
|
|
|
|
{
|
|
|
|
r.length = destCapacity;
|
|
|
|
}
|
|
|
|
[str getCharacters: dest range: r];
|
|
|
|
if (destCapacity > r.length)
|
|
|
|
{
|
|
|
|
dest[r.length] = 0;
|
|
|
|
}
|
|
|
|
return r.length;
|
2010-12-16 10:59:50 +00:00
|
|
|
}
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy or move some characters within a UText.
|
|
|
|
*/
|
|
|
|
void UTextNSStringCopy(UText *ut,
|
2010-12-16 10:59:50 +00:00
|
|
|
int64_t nativeStart,
|
|
|
|
int64_t nativeLimit,
|
|
|
|
int64_t nativeDest,
|
|
|
|
UBool move,
|
|
|
|
UErrorCode *status)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
NSMutableString *str = (NSMutableString*)ut->p;
|
2016-07-01 15:22:02 +00:00
|
|
|
NSUInteger length = (-1 == ut->c) ? [str length] : ut->c;
|
2010-12-16 10:59:50 +00:00
|
|
|
NSRange r;
|
|
|
|
NSString *substr;
|
|
|
|
|
|
|
|
if (nativeLimit > length)
|
|
|
|
{
|
|
|
|
nativeLimit = length;
|
|
|
|
}
|
|
|
|
r = NSMakeRange(nativeStart, nativeLimit - nativeStart);
|
|
|
|
substr = [str substringWithRange: r];
|
|
|
|
[str insertString: substr atIndex: nativeDest];
|
|
|
|
if (move)
|
|
|
|
{
|
|
|
|
if (nativeDest < r.location)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
r.location += r.length;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
2010-12-16 10:59:50 +00:00
|
|
|
[str deleteCharactersInRange: r];
|
|
|
|
}
|
|
|
|
if (NULL != status)
|
|
|
|
{
|
|
|
|
*status = 0;
|
|
|
|
}
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructor for the NSString-specific parts of the UText. Because UTexts can
|
|
|
|
* be allocated on the stack, or reused by different storage implementations,
|
|
|
|
* this does not destroy the UText itself.
|
|
|
|
*/
|
2010-12-16 10:59:50 +00:00
|
|
|
static void
|
|
|
|
UTextNStringClose(UText *ut)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
ut->chunkContents = NULL;
|
|
|
|
[(NSString*)ut->p release];
|
|
|
|
ut->p = NULL;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copies the UText object, optionally copying the NSString. This version is
|
|
|
|
* for NSString-backed UTexts, so uses -copy to copy the string if required.
|
|
|
|
* Typically, this should not actually copy the underlying storage, because it
|
|
|
|
* is immutable.
|
|
|
|
*/
|
2010-12-16 10:59:50 +00:00
|
|
|
UText*
|
|
|
|
UTextNSStringClone(UText *dest,
|
|
|
|
const UText *src,
|
|
|
|
UBool deep,
|
|
|
|
UErrorCode *status)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
NSString *str = (NSString*)src->p;
|
|
|
|
|
|
|
|
if (deep)
|
|
|
|
{
|
|
|
|
str = [[str copy] autorelease];
|
|
|
|
}
|
|
|
|
return UTextInitWithNSString(dest, str);
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copies the UText object, optionally copying the NSMutableString.
|
|
|
|
*/
|
2010-12-16 10:59:50 +00:00
|
|
|
UText*
|
|
|
|
UTextNSMutableStringClone(UText *dest,
|
|
|
|
const UText *src,
|
|
|
|
UBool deep,
|
|
|
|
UErrorCode *status)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
NSMutableString *str = (NSMutableString*)src->p;
|
2011-02-11 14:31:25 +00:00
|
|
|
UText *txt;
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
if (deep)
|
|
|
|
{
|
|
|
|
str = [str mutableCopy];
|
2011-02-11 14:31:25 +00:00
|
|
|
txt = UTextInitWithNSMutableString(dest, str);
|
|
|
|
[str release];
|
2010-12-16 10:59:50 +00:00
|
|
|
}
|
2011-02-11 14:31:25 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
txt = UTextInitWithNSMutableString(dest, str);
|
|
|
|
}
|
|
|
|
return txt;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the index of the current character in the temporary buffer.
|
|
|
|
*/
|
2010-12-16 10:59:50 +00:00
|
|
|
int64_t
|
|
|
|
UTextNSStringMapOffsetToNative(const UText *ut)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
return ut->chunkNativeStart + ut->chunkOffset;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Vtable for NSString-backed UTexts.
|
|
|
|
*/
|
|
|
|
static const UTextFuncs NSStringFuncs =
|
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
sizeof(UTextFuncs), // Table size
|
|
|
|
0, 0, 0, // Reserved
|
|
|
|
UTextNSStringClone,
|
|
|
|
UTextNSStringNativeLength,
|
|
|
|
UTextNSStringAccess,
|
|
|
|
UTextNSStringExtract,
|
|
|
|
0, // Replace
|
|
|
|
UTextNSStringCopy,
|
|
|
|
UTextNSStringMapOffsetToNative,
|
|
|
|
0, // Map to UTF16
|
|
|
|
UTextNStringClose,
|
|
|
|
0, 0, 0 // Spare
|
2010-11-18 22:52:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Vtable for NSMutableString-backed UTexts.
|
|
|
|
*/
|
|
|
|
static const UTextFuncs NSMutableStringFuncs =
|
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
sizeof(UTextFuncs), // Table size
|
|
|
|
0, 0, 0, // Reserved
|
|
|
|
UTextNSMutableStringClone,
|
|
|
|
UTextNSStringNativeLength,
|
|
|
|
UTextNSStringAccess,
|
|
|
|
UTextNSStringExtract,
|
|
|
|
UTextNSMutableStringReplace,
|
|
|
|
UTextNSStringCopy,
|
|
|
|
UTextNSStringMapOffsetToNative,
|
|
|
|
0, // Map to UTF16
|
|
|
|
UTextNStringClose,
|
|
|
|
0, 0, 0 // Spare
|
2010-11-18 22:52:36 +00:00
|
|
|
};
|
|
|
|
|
2010-12-16 10:59:50 +00:00
|
|
|
UText*
|
|
|
|
UTextInitWithNSMutableString(UText *txt, NSMutableString *str)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
UErrorCode status = 0;
|
|
|
|
|
|
|
|
txt = utext_setup(txt, chunkSize * sizeof(unichar), &status);
|
2010-11-18 22:52:36 +00:00
|
|
|
|
2010-12-16 10:59:50 +00:00
|
|
|
if (U_FAILURE(status))
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-11-18 22:52:36 +00:00
|
|
|
|
2010-12-16 10:59:50 +00:00
|
|
|
txt->p = [str retain];
|
|
|
|
txt->pFuncs = &NSMutableStringFuncs;
|
|
|
|
txt->chunkContents = txt->pExtra;
|
2016-07-01 15:22:02 +00:00
|
|
|
txt->c = -1; // Need to fetch length every time
|
2010-12-16 10:59:50 +00:00
|
|
|
txt->providerProperties = 1<<UTEXT_PROVIDER_WRITABLE;
|
2010-11-18 22:52:36 +00:00
|
|
|
|
2010-12-16 10:59:50 +00:00
|
|
|
return txt;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
2010-12-16 10:59:50 +00:00
|
|
|
UText*
|
|
|
|
UTextInitWithNSString(UText *txt, NSString *str)
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
UErrorCode status = 0;
|
|
|
|
txt = utext_setup(txt, 64, &status);
|
2010-11-18 22:52:36 +00:00
|
|
|
|
2010-12-16 10:59:50 +00:00
|
|
|
if (U_FAILURE(status))
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-11-18 22:52:36 +00:00
|
|
|
|
2010-12-16 10:59:50 +00:00
|
|
|
txt->p = [str retain];
|
|
|
|
txt->pFuncs = &NSStringFuncs;
|
|
|
|
txt->chunkContents = txt->pExtra;
|
2016-07-01 15:22:02 +00:00
|
|
|
txt->c = [str length];
|
2010-11-18 22:52:36 +00:00
|
|
|
|
2010-12-16 10:59:50 +00:00
|
|
|
return txt;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@implementation GSUTextString
|
2010-12-16 10:59:50 +00:00
|
|
|
- (id) init
|
Added implementation of NSRegularExpression, from iOS 4 Foundation.
This class is a thin wrapper around libicu regular expressions, so if we don't
have libicu we simply don't compile it at all. This will give people a linker
failure, rather than a nonfunctional class if they try to use GNUstep without
ICU with code that requires it.
The Apple documentation says that this class has a primitive method that takes
a block as an argument and that this method is called by others, so subclasses
can replace that block method without touching the convenience methods. We
mimic this behaviour when compiling with block, but when compiling without them
it's a problem. The current code contains some ugly hacks that will work in
normal usage but break with subclassing when not compiling with blocks.
This commit also includes a partial implementation of NSTextCheckingResult,
implementing the subset of its functionality required for NSRegularExpression
to work.
It also includes numerous fixes to GSICUString. This is heavily used by
NSRegularExpression, to avoid copying strings when mapping between UText for
libicu and NSString for GNUstep.
Note: I don't have a copy of iOS anywhere to test this against, so it's
entirely possible that there are significant discrepancies between this
implementation of NSRegularExpression and the iOS version. This version should
function exactly as the iOS one is described as functioning, but I think we've
all seen that Apple documentation refers more to hopes than facts. Any testing
that someone who does have an ip{hone,od,ad} can do is very welcome.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31635 72102866-910b-0410-8b05-ffd578937521
2010-11-19 22:06:18 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
if (nil != (self = [super init]))
|
|
|
|
{
|
|
|
|
UText t = UTEXT_INITIALIZER;
|
|
|
|
|
|
|
|
memcpy(&txt, &t, sizeof(t));
|
|
|
|
}
|
|
|
|
return self;
|
Added implementation of NSRegularExpression, from iOS 4 Foundation.
This class is a thin wrapper around libicu regular expressions, so if we don't
have libicu we simply don't compile it at all. This will give people a linker
failure, rather than a nonfunctional class if they try to use GNUstep without
ICU with code that requires it.
The Apple documentation says that this class has a primitive method that takes
a block as an argument and that this method is called by others, so subclasses
can replace that block method without touching the convenience methods. We
mimic this behaviour when compiling with block, but when compiling without them
it's a problem. The current code contains some ugly hacks that will work in
normal usage but break with subclassing when not compiling with blocks.
This commit also includes a partial implementation of NSTextCheckingResult,
implementing the subset of its functionality required for NSRegularExpression
to work.
It also includes numerous fixes to GSICUString. This is heavily used by
NSRegularExpression, to avoid copying strings when mapping between UText for
libicu and NSString for GNUstep.
Note: I don't have a copy of iOS anywhere to test this against, so it's
entirely possible that there are significant discrepancies between this
implementation of NSRegularExpression and the iOS version. This version should
function exactly as the iOS one is described as functioning, but I think we've
all seen that Apple documentation refers more to hopes than facts. Any testing
that someone who does have an ip{hone,od,ad} can do is very welcome.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31635 72102866-910b-0410-8b05-ffd578937521
2010-11-19 22:06:18 +00:00
|
|
|
}
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
- (NSUInteger) length
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
return utext_nativeLength(&txt);
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
- (unichar) characterAtIndex: (NSUInteger)idx
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
unichar c;
|
|
|
|
|
|
|
|
[self getCharacters: &c range: NSMakeRange(idx, 1)];
|
|
|
|
return c;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
- (void) getCharacters: (unichar*)buffer range: (NSRange)r
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
UErrorCode status = 0;
|
|
|
|
|
|
|
|
utext_extract(&txt, r.location, r.location+r.length, buffer, r.length,
|
|
|
|
&status);
|
|
|
|
if (U_FAILURE(status))
|
|
|
|
{
|
|
|
|
_NSRangeExceptionRaise();
|
|
|
|
}
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
- (void) dealloc
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
utext_close(&txt);
|
|
|
|
[super dealloc];
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation GSUTextMutableString
|
2010-12-16 10:59:50 +00:00
|
|
|
- (id) init
|
Added implementation of NSRegularExpression, from iOS 4 Foundation.
This class is a thin wrapper around libicu regular expressions, so if we don't
have libicu we simply don't compile it at all. This will give people a linker
failure, rather than a nonfunctional class if they try to use GNUstep without
ICU with code that requires it.
The Apple documentation says that this class has a primitive method that takes
a block as an argument and that this method is called by others, so subclasses
can replace that block method without touching the convenience methods. We
mimic this behaviour when compiling with block, but when compiling without them
it's a problem. The current code contains some ugly hacks that will work in
normal usage but break with subclassing when not compiling with blocks.
This commit also includes a partial implementation of NSTextCheckingResult,
implementing the subset of its functionality required for NSRegularExpression
to work.
It also includes numerous fixes to GSICUString. This is heavily used by
NSRegularExpression, to avoid copying strings when mapping between UText for
libicu and NSString for GNUstep.
Note: I don't have a copy of iOS anywhere to test this against, so it's
entirely possible that there are significant discrepancies between this
implementation of NSRegularExpression and the iOS version. This version should
function exactly as the iOS one is described as functioning, but I think we've
all seen that Apple documentation refers more to hopes than facts. Any testing
that someone who does have an ip{hone,od,ad} can do is very welcome.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31635 72102866-910b-0410-8b05-ffd578937521
2010-11-19 22:06:18 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
if (nil != (self = [super init]))
|
|
|
|
{
|
|
|
|
UText t = UTEXT_INITIALIZER;
|
|
|
|
|
|
|
|
memcpy(&txt, &t, sizeof(t));
|
|
|
|
}
|
|
|
|
return self;
|
Added implementation of NSRegularExpression, from iOS 4 Foundation.
This class is a thin wrapper around libicu regular expressions, so if we don't
have libicu we simply don't compile it at all. This will give people a linker
failure, rather than a nonfunctional class if they try to use GNUstep without
ICU with code that requires it.
The Apple documentation says that this class has a primitive method that takes
a block as an argument and that this method is called by others, so subclasses
can replace that block method without touching the convenience methods. We
mimic this behaviour when compiling with block, but when compiling without them
it's a problem. The current code contains some ugly hacks that will work in
normal usage but break with subclassing when not compiling with blocks.
This commit also includes a partial implementation of NSTextCheckingResult,
implementing the subset of its functionality required for NSRegularExpression
to work.
It also includes numerous fixes to GSICUString. This is heavily used by
NSRegularExpression, to avoid copying strings when mapping between UText for
libicu and NSString for GNUstep.
Note: I don't have a copy of iOS anywhere to test this against, so it's
entirely possible that there are significant discrepancies between this
implementation of NSRegularExpression and the iOS version. This version should
function exactly as the iOS one is described as functioning, but I think we've
all seen that Apple documentation refers more to hopes than facts. Any testing
that someone who does have an ip{hone,od,ad} can do is very welcome.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31635 72102866-910b-0410-8b05-ffd578937521
2010-11-19 22:06:18 +00:00
|
|
|
}
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
- (NSUInteger) length
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
return utext_nativeLength(&txt);
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
- (unichar) characterAtIndex: (NSUInteger)idx
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
unichar c;
|
|
|
|
[self getCharacters: &c range: NSMakeRange(idx, 1)];
|
|
|
|
return c;
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
- (void) getCharacters: (unichar*)buffer range: (NSRange)r
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
UErrorCode status = 0;
|
|
|
|
|
|
|
|
utext_extract(&txt, r.location, r.location+r.length, buffer, r.length,
|
|
|
|
&status);
|
|
|
|
if (U_FAILURE(status))
|
|
|
|
{
|
|
|
|
_NSRangeExceptionRaise();
|
|
|
|
}
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
2010-12-16 10:59:50 +00:00
|
|
|
|
|
|
|
- (void) replaceCharactersInRange: (NSRange)r
|
|
|
|
withString: (NSString*)aString
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2021-07-16 11:43:07 +00:00
|
|
|
NSUInteger length = [aString length];
|
2010-12-16 10:59:50 +00:00
|
|
|
UErrorCode status = 0;
|
|
|
|
|
2021-07-16 11:43:07 +00:00
|
|
|
TEMP_BUFFER(buffer, length);
|
|
|
|
[aString getCharacters: buffer range: NSMakeRange(0, length)];
|
2010-11-18 22:52:36 +00:00
|
|
|
|
2021-07-16 11:43:07 +00:00
|
|
|
utext_replace(&txt, r.location, r.location + r.length, buffer, length, &status);
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
|
2010-12-16 10:59:50 +00:00
|
|
|
- (void) dealloc
|
2010-11-18 22:52:36 +00:00
|
|
|
{
|
2010-12-16 10:59:50 +00:00
|
|
|
utext_close(&txt);
|
|
|
|
[super dealloc];
|
2010-11-18 22:52:36 +00:00
|
|
|
}
|
|
|
|
@end
|
Added implementation of NSRegularExpression, from iOS 4 Foundation.
This class is a thin wrapper around libicu regular expressions, so if we don't
have libicu we simply don't compile it at all. This will give people a linker
failure, rather than a nonfunctional class if they try to use GNUstep without
ICU with code that requires it.
The Apple documentation says that this class has a primitive method that takes
a block as an argument and that this method is called by others, so subclasses
can replace that block method without touching the convenience methods. We
mimic this behaviour when compiling with block, but when compiling without them
it's a problem. The current code contains some ugly hacks that will work in
normal usage but break with subclassing when not compiling with blocks.
This commit also includes a partial implementation of NSTextCheckingResult,
implementing the subset of its functionality required for NSRegularExpression
to work.
It also includes numerous fixes to GSICUString. This is heavily used by
NSRegularExpression, to avoid copying strings when mapping between UText for
libicu and NSString for GNUstep.
Note: I don't have a copy of iOS anywhere to test this against, so it's
entirely possible that there are significant discrepancies between this
implementation of NSRegularExpression and the iOS version. This version should
function exactly as the iOS one is described as functioning, but I think we've
all seen that Apple documentation refers more to hopes than facts. Any testing
that someone who does have an ip{hone,od,ad} can do is very welcome.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31635 72102866-910b-0410-8b05-ffd578937521
2010-11-19 22:06:18 +00:00
|
|
|
#endif // HAV_ICU
|