ICU-1730 add Replaceable::clone()

X-SVN-Rev: 11741
This commit is contained in:
Markus Scherer 2003-04-30 22:08:57 +00:00
parent 65c6f66b2e
commit ece6fe9eca
7 changed files with 123 additions and 44 deletions

View File

@ -1,6 +1,6 @@
/*
**************************************************************************
* Copyright (C) 1999-2001, International Business Machines Corporation and
* Copyright (C) 1999-2003, International Business Machines Corporation and
* others. All Rights Reserved.
**************************************************************************
* Date Name Description
@ -178,6 +178,23 @@ public:
*/
virtual UBool hasMetaData() const;
/**
* Clone this object, an instance of a subclass of Replaceable.
* Clones can be used concurrently in multiple threads.
* If a subclass does not implement clone(), or if an error occurs,
* then NULL is returned.
* The clone functions in all subclasses return a pointer to a Replaceable
* because some compilers do not support covariant (same-as-this)
* return types; cast to the appropriate subclass if necessary.
* The caller must delete the clone.
*
* @return a clone of this object
*
* @see getDynamicClassID
* @draft ICU 2.6
*/
virtual Replaceable *clone() const;
protected:
/**
@ -224,7 +241,7 @@ Replaceable::char32At(int32_t offset) const {
return getChar32At(offset);
}
// See unistr.cpp for Replaceable::hasMetaData()
// There is no rep.cpp, see unistr.cpp for Replaceable function implementations.
U_NAMESPACE_END

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (C) 1998-2002, International Business Machines
* Copyright (C) 1998-2003, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*
@ -2718,9 +2718,27 @@ public:
*/
UnicodeString(const UnicodeString& src, int32_t srcStart, int32_t srcLength);
/**
* Clone this object, an instance of a subclass of Replaceable.
* Clones can be used concurrently in multiple threads.
* If a subclass does not implement clone(), or if an error occurs,
* then NULL is returned.
* The clone functions in all subclasses return a pointer to a Replaceable
* because some compilers do not support covariant (same-as-this)
* return types; cast to the appropriate subclass if necessary.
* The caller must delete the clone.
*
* @return a clone of this object
*
* @see Replaceable::clone
* @see getDynamicClassID
* @draft ICU 2.6
*/
virtual Replaceable *clone() const;
/** Destructor.
* @stable ICU 2.0
*/
*/
~UnicodeString();

View File

@ -1,6 +1,6 @@
/*
******************************************************************************
* Copyright (C) 1997-2001, International Business Machines
* Copyright (C) 1997-2003, International Business Machines
* Corporation and others. All Rights Reserved.
******************************************************************************
* Date Name Description
@ -33,6 +33,7 @@ U_CDECL_BEGIN
* An opaque replaceable text object. This will be manipulated only
* through the caller-supplied UReplaceableFunctor struct. Related
* to the C++ class Replaceable.
* This is currently only used in the Transliterator C API, see utrans.h .
* @stable ICU 2.0
*/
typedef void* UReplaceable;
@ -49,6 +50,9 @@ typedef struct UReplaceableCallbacks {
/**
* Function pointer that returns the number of UChar code units in
* this text.
*
* @param rep A pointer to "this" UReplaceable object.
* @return The length of the text.
* @stable ICU 2.0
*/
int32_t (*length)(const UReplaceable* rep);
@ -58,6 +62,10 @@ typedef struct UReplaceableCallbacks {
* offset into this text; 0 <= offset < n, where n is the value
* returned by (*length)(rep). See unistr.h for a description of
* charAt() vs. char32At().
*
* @param rep A pointer to "this" UReplaceable object.
* @param offset The index at which to fetch the UChar (code unit).
* @return The UChar (code unit) at offset, or U+FFFF if the offset is out of bounds.
* @stable ICU 2.0
*/
UChar (*charAt)(const UReplaceable* rep,
@ -67,6 +75,10 @@ typedef struct UReplaceableCallbacks {
* Function pointer that returns a UChar32 code point at the given
* offset into this text. See unistr.h for a description of
* charAt() vs. char32At().
*
* @param rep A pointer to "this" UReplaceable object.
* @param offset The index at which to fetch the UChar32 (code point).
* @return The UChar32 (code point) at offset, or U+FFFF if the offset is out of bounds.
* @stable ICU 2.0
*/
UChar32 (*char32At)(const UReplaceable* rep,
@ -76,6 +88,8 @@ typedef struct UReplaceableCallbacks {
* Function pointer that replaces text between start and limit in
* this text with the given text. Attributes (out of band info)
* should be retained.
*
* @param rep A pointer to "this" UReplaceable object.
* @param start the starting index of the text to be replaced,
* inclusive.
* @param limit the ending index of the text to be replaced,
@ -95,6 +109,8 @@ typedef struct UReplaceableCallbacks {
/**
* Function pointer that copies the characters in the range
* [<tt>start</tt>, <tt>limit</tt>) into the array <tt>dst</tt>.
*
* @param rep A pointer to "this" UReplaceable object.
* @param start offset of first character which will be copied
* into the array
* @param limit offset immediately following the last character to
@ -114,6 +130,8 @@ typedef struct UReplaceableCallbacks {
* band info) should be retained. After this call, there will be
* (at least) two copies of the characters originally located at
* start..limit-1.
*
* @param rep A pointer to "this" UReplaceable object.
* @param start the starting index of the text to be copied,
* inclusive.
* @param limit the ending index of the text to be copied,

View File

@ -1,6 +1,6 @@
/*
******************************************************************************
* Copyright (C) 1999-2001, International Business Machines Corporation and *
* Copyright (C) 1999-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
******************************************************************************
*
@ -381,6 +381,18 @@ UnicodeString::UnicodeString(const UnicodeString& that,
setTo(that, srcStart, srcLength);
}
// Replaceable base class clone() default implementation, does not clone
Replaceable *
Replaceable::clone() const {
return NULL;
}
// UnicodeString overrides clone() with a real implementation
Replaceable *
UnicodeString::clone() const {
return new UnicodeString(*this);
}
//========================================
// array allocation
//========================================

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1997-2001, International Business Machines
* Copyright (C) 1997-2003, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
* Date Name Description
@ -35,13 +35,9 @@
U_NAMESPACE_BEGIN
class ReplaceableGlue : public Replaceable {
UChar *buf;
int32_t bufLen;
UReplaceable *rep;
UReplaceableCallbacks *func;
enum { BUF_PAD = 8 };
/**
* The address of this static class variable serves as this class's ID
* for ICU "poor man's RTTI".
@ -65,6 +61,8 @@ public:
virtual void copy(int32_t start, int32_t limit, int32_t dest);
// virtual Replaceable *clone() const { return NULL; } same as default
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
@ -97,13 +95,9 @@ ReplaceableGlue::ReplaceableGlue(UReplaceable *replaceable,
{
this->rep = replaceable;
this->func = funcCallback;
buf = 0;
bufLen = 0;
}
ReplaceableGlue::~ReplaceableGlue() {
uprv_free(buf);
}
ReplaceableGlue::~ReplaceableGlue() {}
int32_t ReplaceableGlue::getLength() const {
return (*func->length)(rep);
@ -120,14 +114,7 @@ UChar32 ReplaceableGlue::getChar32At(int32_t offset) const {
void ReplaceableGlue::handleReplaceBetween(int32_t start,
int32_t limit,
const UnicodeString& text) {
int32_t len = text.length();
if (buf == 0 || bufLen < len) {
uprv_free(buf);
bufLen = len + BUF_PAD;
buf = (UChar*) uprv_malloc(sizeof(UChar) * bufLen);
}
text.extract(0, len, buf);
(*func->replace)(rep, start, limit, buf, len);
(*func->replace)(rep, start, limit, text.getBuffer(), text.length());
}
void ReplaceableGlue::extractBetween(int32_t start,

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 2001, International Business Machines Corporation and
* Copyright (c) 2001-2003, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/************************************************************************
@ -59,16 +59,20 @@ public:
if (i < newStyles.length()) {
s.append(newStyles.charAt(i));
} else {
if (text.charAt(i) == NO_STYLE_MARK) {
s.append(NO_STYLE);
} else {
s.append((UChar)(i + 0x0031));
}
if (text.charAt(i) == NO_STYLE_MARK) {
s.append(NO_STYLE);
} else {
s.append((UChar)(i + 0x0031));
}
}
}
this->styles = s;
}
virtual Replaceable *clone() const {
return new TestReplaceable(chars, styles);
}
~TestReplaceable(void) {}
UnicodeString getStyles() {
@ -135,14 +139,14 @@ protected:
// dumb implementation for now.
UnicodeString s;
for (int i = 0; i < newLen; ++i) {
// this doesn't really handle an embedded NO_STYLE_MARK
// in the middle of a long run of characters right -- but
// that case shouldn't happen anyway
if (getCharAt(start+i) == NO_STYLE_MARK) {
s.append(NO_STYLE);
} else {
s.append(newStyle);
}
// this doesn't really handle an embedded NO_STYLE_MARK
// in the middle of a long run of characters right -- but
// that case shouldn't happen anyway
if (getCharAt(start+i) == NO_STYLE_MARK) {
s.append(NO_STYLE);
} else {
s.append(newStyle);
}
}
styles.replaceBetween(start, limit, s);
}
@ -179,10 +183,10 @@ void ReplaceableTest::TestReplaceableClass(void) {
{0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
{0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000}, /* "wxyz" */
{0x0077, 0x0078, 0x0079, 0x007A, 0x0075, 0x0000}, /* "wxyzu" */
{0x0078, 0x0079, 0x007A, 0x0000, 0x0000, 0x0000}, /* "xyz" */
{0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
{0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
{0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
{0x0078, 0x0079, 0x007A, 0x0000, 0x0000, 0x0000}, /* "xyz" */
{0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
{0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
{0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
};
check("Lower", rawTestArray[0], "1234");
check("Upper", rawTestArray[1], "123455"); // must map 00DF to SS
@ -215,6 +219,13 @@ void ReplaceableTest::check(const UnicodeString& transliteratorName,
UParseError pe;
t = Transliterator::createFromRules("test", rules, UTRANS_FORWARD,
pe, status);
// test clone()
TestReplaceable *tr2 = (TestReplaceable *)tr->clone();
if(tr2 != NULL) {
delete tr;
tr = tr2;
}
} else {
t = Transliterator::createInstance(transliteratorName, UTRANS_FORWARD, status);
}

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2002, International Business Machines Corporation and
* Copyright (c) 1997-2003, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
@ -63,12 +63,20 @@ UnicodeStringTest::TestBasicManipulation()
{
UnicodeString test1("Now is the time for all men to come swiftly to the aid of the party.\n");
UnicodeString expectedValue;
UnicodeString *c;
c=(UnicodeString *)test1.clone();
test1.insert(24, "good ");
expectedValue = "Now is the time for all good men to come swiftly to the aid of the party.\n";
if (test1 != expectedValue)
errln("insert() failed: expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
c->insert(24, "good ");
if(*c != expectedValue) {
errln("clone()->insert() failed: expected \"" + expectedValue + "\"\n,got \"" + *c + "\"");
}
delete c;
test1.remove(41, 8);
expectedValue = "Now is the time for all good men to come to the aid of the party.\n";
if (test1 != expectedValue)
@ -1117,11 +1125,19 @@ UnicodeStringTest::TestStackAllocation()
if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x125) {
errln("UnicodeString.setTo(readonly alias) does not alias correctly");
}
UnicodeString *c=(UnicodeString *)test->clone();
workingBuffer[1] = 0x109;
if(test->charAt(1) != 0x109) {
errln("UnicodeString.setTo(readonly alias) made a copy: did not see change in buffer");
}
if(c->length() != 2 || c->charAt(1) != 0x125) {
errln("clone(alias) did not copy the buffer");
}
delete c;
test->setTo(TRUE, workingBuffer, -1);
if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x109) {
errln("UnicodeString.setTo(readonly alias, length -1) does not alias correctly");