mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 07:39:16 +00:00
ICU-4699 add Freeze to UText
X-SVN-Rev: 19197
This commit is contained in:
parent
449af4ef8f
commit
cfd5650611
6 changed files with 139 additions and 23 deletions
icu4c/source
|
@ -1413,7 +1413,7 @@ CharacterIteratorUT::CharacterIteratorUT(UText *ut) {
|
|||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
fUText = utext_clone(NULL, ut, FALSE, &status);
|
||||
fUText = utext_clone(NULL, ut, FALSE, TRUE, &status); // Shallow, Read-only clone.
|
||||
if (fUText != NULL) {
|
||||
// Set the inherited CharacterItertor fields
|
||||
textLength = (int32_t)utext_nativeLength(ut);
|
||||
|
@ -1541,7 +1541,7 @@ default:
|
|||
|
||||
void CharacterIteratorUT::resetTo(const UText *ut, UErrorCode *status) {
|
||||
// Reset this CharacterIteratorUT to use a new UText.
|
||||
fUText = utext_clone(fUText, ut, FALSE, status);
|
||||
fUText = utext_clone(fUText, ut, FALSE, TRUE, status);
|
||||
utext_setNativeIndex(fUText, 0);
|
||||
textLength = (int32_t)utext_nativeLength(fUText);
|
||||
pos = 0;
|
||||
|
@ -1574,7 +1574,8 @@ UText *RuleBasedBreakIterator::getUText(UText *fillIn, UErrorCode &status) const
|
|||
fText->getDynamicClassID() == CharacterIteratorUT::getStaticClassID())
|
||||
{
|
||||
CharacterIteratorUT *utcr = (CharacterIteratorUT *)fText;
|
||||
result = utext_clone(fillIn, utcr->fUText, FALSE, &status);
|
||||
// Shallow, Readonly clone.
|
||||
result = utext_clone(fillIn, utcr->fUText, FALSE, TRUE, &status);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -298,11 +298,16 @@ utext_openReplaceable(UText *ut, Replaceable *rep, UErrorCode *status);
|
|||
* A shallow clone operation will not fail, barring truly exceptional conditions such
|
||||
* as memory allocation failures.
|
||||
*
|
||||
* A shallow clone will preserve the utext_isWritable() state of the source object.
|
||||
* Note, however, that any writing (modification) to the text is while more than one
|
||||
* UText is referring to the same underlying text storage is an error with unpredictable
|
||||
* results, much like modifying the underlying text directly, bypassing a
|
||||
* UText wrapper.
|
||||
* Shallow UText clones should be avoided if the UText functions that modify the
|
||||
* text are expected to be used, either on the original or the cloned UText.
|
||||
* Any such modifications can cause unpredictable behavior. Read Only
|
||||
* shallow clones provide some protection against errors of this type by
|
||||
* disabling text modification via the cloned UText.
|
||||
*
|
||||
* A shallow clone made with the readOnly parameter == FALSE will preserve the
|
||||
* utext_isWritable() state of the source object. Use with caution, however.
|
||||
* Write operations must be avoided while more than one UTexts exist that refer
|
||||
* to the same underlying text.
|
||||
*
|
||||
* A UText and its clone may be safely concurrently accessed by separate threads.
|
||||
* This is true for read access only with shallow clones, and for both read and
|
||||
|
@ -316,6 +321,9 @@ utext_openReplaceable(UText *ut, Replaceable *rep, UErrorCode *status);
|
|||
* be reset to become the clone.
|
||||
* @param src The UText to be cloned.
|
||||
* @param deep TRUE to request a deep clone, FALSE for a shallow clone.
|
||||
* @param readOnly TRUE to request that the cloned UText have read only access to the
|
||||
* underlying text.
|
||||
|
||||
* @param status Errors are returned here. For deep clones, U_UNSUPPORTED_ERROR
|
||||
* will be returned if the text provider is unable to clone the
|
||||
* original text.
|
||||
|
@ -323,7 +331,7 @@ utext_openReplaceable(UText *ut, Replaceable *rep, UErrorCode *status);
|
|||
* @draft ICU 3.4
|
||||
*/
|
||||
U_DRAFT UText * U_EXPORT2
|
||||
utext_clone(UText *dest, const UText *src, UBool deep, UErrorCode *status);
|
||||
utext_clone(UText *dest, const UText *src, UBool deep, UBool readOnly, UErrorCode *status);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -757,9 +765,9 @@ utext_copy(UText *ut,
|
|||
* Freeze a UText. This prevents any modification to the underlying text itself
|
||||
* by means of functions operating on this UText.
|
||||
* <p/>
|
||||
* Once frozen, a UText can not be unfrozen. The intent is to provide some
|
||||
* assurance that a the text underlying a frozen UText wrapper will not
|
||||
* be unexpectedly changing.
|
||||
* Once frozen, a UText can not be unfrozen. The intent is to ensure
|
||||
* that a the text underlying a frozen UText wrapper cannot be modified via that UText.
|
||||
*
|
||||
* <p/>
|
||||
* Caution: freezing a UText will disable changes made via the specific
|
||||
* frozen UText wrapper only; it will not have any effect on the ability to
|
||||
|
@ -769,6 +777,7 @@ utext_copy(UText *ut,
|
|||
*
|
||||
* @param ut The UText to be frozen.
|
||||
* @see utext_isWritable()
|
||||
* @draft ICU 3.6
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
utext_freeze(UText *ut);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005, International Business Machines
|
||||
* Copyright (C) 2005-2006, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -259,6 +259,13 @@ utext_isWritable(const UText *ut)
|
|||
}
|
||||
|
||||
|
||||
U_DRAFT void U_EXPORT2
|
||||
utext_freeze(UText *ut) {
|
||||
// Zero out the WRITABLE flag.
|
||||
ut->providerProperties &= ~(I32_FLAG(UTEXT_PROVIDER_WRITABLE));
|
||||
}
|
||||
|
||||
|
||||
U_DRAFT UBool U_EXPORT2
|
||||
utext_hasMetaData(const UText *ut)
|
||||
{
|
||||
|
@ -305,8 +312,13 @@ utext_copy(UText *ut,
|
|||
|
||||
|
||||
U_DRAFT UText * U_EXPORT2
|
||||
utext_clone(UText *dest, const UText *src, UBool deep, UErrorCode *status) {
|
||||
return src->clone(dest, src, deep, status);
|
||||
utext_clone(UText *dest, const UText *src, UBool deep, UBool readOnly, UErrorCode *status) {
|
||||
UText *result;
|
||||
result = src->clone(dest, src, deep, status);
|
||||
if (readOnly) {
|
||||
utext_freeze(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1026,6 +1038,8 @@ repTextClone(UText *dest, const UText *src, UBool deep, UErrorCode *status) {
|
|||
const Replaceable *replSrc = (const Replaceable *)src->context;
|
||||
dest->context = replSrc->clone();
|
||||
dest->p = dest->context;
|
||||
// with deep clone, the copy is writable, even when the source is not.
|
||||
dest->providerProperties |= I32_FLAG(UTEXT_PROVIDER_WRITABLE);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
@ -1398,6 +1412,9 @@ unistrTextClone(UText *dest, const UText *src, UBool deep, UErrorCode *status) {
|
|||
const UnicodeString *srcString = (const UnicodeString *)src->context;
|
||||
dest->context = new UnicodeString(*srcString);
|
||||
dest->p = dest->context;
|
||||
|
||||
// with deep clone, the copy is writable, even when the source is not.
|
||||
dest->providerProperties |= I32_FLAG(UTEXT_PROVIDER_WRITABLE);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 2005, International Business Machines Corporation and
|
||||
* Copyright (c) 2005-2006, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
/*
|
||||
|
@ -93,7 +93,7 @@ static void TestAPI(void) {
|
|||
status = U_ZERO_ERROR;
|
||||
uta = utext_openUChars(NULL, uString, -1, &status);
|
||||
TEST_SUCCESS(status);
|
||||
utb = utext_clone(NULL, uta, FALSE, &status);
|
||||
utb = utext_clone(NULL, uta, FALSE, FALSE, &status);
|
||||
TEST_SUCCESS(status);
|
||||
TEST_ASSERT(utb != NULL);
|
||||
TEST_ASSERT(utb != uta);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 2005, International Business Machines Corporation and
|
||||
* Copyright (c) 2005-2006, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
/************************************************************************
|
||||
|
@ -49,6 +49,8 @@ UTextTest::runIndexedTest(int32_t index, UBool exec,
|
|||
if (exec) TextTest(); break;
|
||||
case 1: name = "ErrorTest";
|
||||
if (exec) ErrorTest(); break;
|
||||
case 2: name = "FreezeTest";
|
||||
if (exec) FreezeTest(); break;
|
||||
default: name = ""; break;
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +387,7 @@ void UTextTest::TestCopyMove(const UnicodeString &us, UText *ut, UBool move,
|
|||
// clone the UText. The test will be run in the cloned copy
|
||||
// so that we don't alter the original.
|
||||
//
|
||||
targetUT = utext_clone(NULL, ut, TRUE, &status);
|
||||
targetUT = utext_clone(NULL, ut, TRUE, FALSE, &status);
|
||||
TEST_SUCCESS(status);
|
||||
UnicodeString targetUS(us); // And copy the reference string.
|
||||
|
||||
|
@ -463,7 +465,7 @@ void UTextTest::TestReplace(
|
|||
// clone the target UText. The test will be run in the cloned copy
|
||||
// so that we don't alter the original.
|
||||
//
|
||||
targetUT = utext_clone(NULL, ut, TRUE, &status);
|
||||
targetUT = utext_clone(NULL, ut, TRUE, FALSE, &status);
|
||||
TEST_SUCCESS(status);
|
||||
UnicodeString targetUS(us); // And copy the reference string.
|
||||
|
||||
|
@ -1091,8 +1093,94 @@ void UTextTest::ErrorTest()
|
|||
|
||||
utext_close(ut);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void UTextTest::FreezeTest() {
|
||||
// Check isWritable() and freeze() behavior.
|
||||
//
|
||||
|
||||
UnicodeString ustr("Hello, World.");
|
||||
const char u8str[] = {char(0x31), (char)0x32, (char)0x33, 0};
|
||||
const UChar u16str[] = {(UChar)0x31, (UChar)0x32, (UChar)0x44, 0};
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UText *ut = NULL;
|
||||
UText *ut2 = NULL;
|
||||
|
||||
ut = utext_openUTF8(ut, u8str, -1, &status);
|
||||
TEST_SUCCESS(status);
|
||||
UBool writable = utext_isWritable(ut);
|
||||
TEST_ASSERT(writable == FALSE);
|
||||
utext_copy(ut, 1, 2, 0, TRUE, &status);
|
||||
TEST_ASSERT(status == U_NO_WRITE_PERMISSION);
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ut = utext_openUChars(ut, u16str, -1, &status);
|
||||
TEST_SUCCESS(status);
|
||||
writable = utext_isWritable(ut);
|
||||
TEST_ASSERT(writable == FALSE);
|
||||
utext_copy(ut, 1, 2, 0, TRUE, &status);
|
||||
TEST_ASSERT(status == U_NO_WRITE_PERMISSION);
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ut = utext_openUnicodeString(ut, &ustr, &status);
|
||||
TEST_SUCCESS(status);
|
||||
writable = utext_isWritable(ut);
|
||||
TEST_ASSERT(writable == TRUE);
|
||||
utext_freeze(ut);
|
||||
writable = utext_isWritable(ut);
|
||||
TEST_ASSERT(writable == FALSE);
|
||||
utext_copy(ut, 1, 2, 0, TRUE, &status);
|
||||
TEST_ASSERT(status == U_NO_WRITE_PERMISSION);
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ut = utext_openUnicodeString(ut, &ustr, &status);
|
||||
TEST_SUCCESS(status);
|
||||
ut2 = utext_clone(ut2, ut, FALSE, FALSE, &status); // clone with readonly = false
|
||||
TEST_SUCCESS(status);
|
||||
writable = utext_isWritable(ut2);
|
||||
TEST_ASSERT(writable == TRUE);
|
||||
ut2 = utext_clone(ut2, ut, FALSE, TRUE, &status); // clone with readonly = true
|
||||
TEST_SUCCESS(status);
|
||||
writable = utext_isWritable(ut2);
|
||||
TEST_ASSERT(writable == FALSE);
|
||||
utext_copy(ut2, 1, 2, 0, TRUE, &status);
|
||||
TEST_ASSERT(status == U_NO_WRITE_PERMISSION);
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ut = utext_openConstUnicodeString(ut, (const UnicodeString *)&ustr, &status);
|
||||
TEST_SUCCESS(status);
|
||||
writable = utext_isWritable(ut);
|
||||
TEST_ASSERT(writable == FALSE);
|
||||
utext_copy(ut, 1, 2, 0, TRUE, &status);
|
||||
TEST_ASSERT(status == U_NO_WRITE_PERMISSION);
|
||||
|
||||
// Deep Clone of a frozen UText should re-enable writing in the copy.
|
||||
status = U_ZERO_ERROR;
|
||||
ut = utext_openUnicodeString(ut, &ustr, &status);
|
||||
TEST_SUCCESS(status);
|
||||
utext_freeze(ut);
|
||||
ut2 = utext_clone(ut2, ut, TRUE, FALSE, &status); // deep clone
|
||||
TEST_SUCCESS(status);
|
||||
writable = utext_isWritable(ut2);
|
||||
TEST_ASSERT(writable == TRUE);
|
||||
|
||||
|
||||
// Deep clone of a frozen UText, where the base type is intrinsically non-writable,
|
||||
// should NOT enable writing in the copy.
|
||||
status = U_ZERO_ERROR;
|
||||
ut = utext_openUChars(ut, u16str, -1, &status);
|
||||
TEST_SUCCESS(status);
|
||||
utext_freeze(ut);
|
||||
ut2 = utext_clone(ut2, ut, TRUE, FALSE, &status); // deep clone
|
||||
TEST_SUCCESS(status);
|
||||
writable = utext_isWritable(ut2);
|
||||
TEST_ASSERT(writable == FALSE);
|
||||
|
||||
// cleanup
|
||||
utext_close(ut);
|
||||
utext_close(ut2);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 2005, International Business Machines Corporation and
|
||||
* Copyright (c) 2005-2006, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
/************************************************************************
|
||||
|
@ -30,6 +30,7 @@ public:
|
|||
void runIndexedTest(int32_t index, UBool exec, const char* &name, char* par=NULL);
|
||||
void TextTest();
|
||||
void ErrorTest();
|
||||
void FreezeTest();
|
||||
|
||||
private:
|
||||
struct m { // Map between native indices & code points.
|
||||
|
|
Loading…
Add table
Reference in a new issue