// ------------------------------------------
//
-// Default constructor and destructor
+// Constructors, destructor and assignment operator
//
//-------------------------------------------
*validLocale = *actualLocale = 0;
}
+BreakIterator::BreakIterator(const BreakIterator &other) : UObject(other) {
+ uprv_strncpy(actualLocale, other.actualLocale, sizeof(actualLocale));
+ uprv_strncpy(validLocale, other.validLocale, sizeof(validLocale));
+}
+
+BreakIterator &BreakIterator::operator =(const BreakIterator &other) {
+ if (this != &other) {
+ uprv_strncpy(actualLocale, other.actualLocale, sizeof(actualLocale));
+ uprv_strncpy(validLocale, other.validLocale, sizeof(validLocale));
+ }
+ return *this;
+}
+
BreakIterator::~BreakIterator()
{
}
if (this == &that) {
return *this;
}
+ BreakIterator::operator=(that);
+
reset(); // Delete break cache information
fBreakType = that.fBreakType;
if (fLanguageBreakEngines != NULL) {
return FALSE;
}
+ // The base class BreakIterator carries no state that participates in equality,
+ // and does not implement an equality function that would otherwise be
+ // checked at this point.
+
const RuleBasedBreakIterator& that2 = (const RuleBasedBreakIterator&) that;
if (!utext_equals(fText, that2.fText)) {
// The two break iterators are operating on different text,
- // or have a different interation position.
+ // or have a different iteration position.
+ // Note that fText's position is always the same as the break iterator's position.
return FALSE;
};
- // TODO: need a check for when in a dictionary region at different offsets.
-
if (that2.fData == fData ||
(fData != NULL && that2.fData != NULL && *that2.fData == *fData)) {
// The two break iterators are using the same rules.
virtual int32_t next(void) = 0;
/**
- * Return character index of the current interator position within the text.
+ * Return character index of the current iterator position within the text.
* @return The boundary most recently returned.
* @stable ICU 2.0
*/
virtual int32_t preceding(int32_t offset) = 0;
/**
- * Return true if the specfied position is a boundary position.
+ * Return true if the specified position is a boundary position.
* As a side effect, the current position of the iterator is set
* to the first boundary position at or following the specified offset.
* @param offset the offset to check.
* @param fillInVec an array to be filled in with the status values.
* @param capacity the length of the supplied vector. A length of zero causes
* the function to return the number of status values, in the
- * normal way, without attemtping to store any values.
+ * normal way, without attempting to store any values.
* @param status receives error codes.
* @return The number of rule status values from rules that determined
* the most recent boundary returned by the break iterator.
static const Locale* U_EXPORT2 getAvailableLocales(int32_t& count);
/**
- * Get name of the object for the desired Locale, in the desired langauge.
+ * Get name of the object for the desired Locale, in the desired language.
* @param objectLocale must be from getAvailableLocales.
* @param displayLocale specifies the desired locale for output.
* @param name the fill-in parameter of the return value
UnicodeString& name);
/**
- * Get name of the object for the desired Locale, in the langauge of the
+ * Get name of the object for the desired Locale, in the language of the
* default locale.
* @param objectLocale must be from getMatchingLocales
* @param name the fill-in parameter of the return value
/** @internal */
BreakIterator();
/** @internal */
- BreakIterator (const BreakIterator &other) : UObject(other) {}
+ BreakIterator (const BreakIterator &other);
#ifndef U_HIDE_INTERNAL_API
/** @internal */
- BreakIterator (const Locale& valid, const Locale& actual);
+ BreakIterator (const Locale& valid, const Locale &actual);
+ /** @internal. Assignment Operator, used by RuleBasedBreakIterator. */
+ BreakIterator &operator = (const BreakIterator &other);
#endif /* U_HIDE_INTERNAL_API */
private:
/** @internal */
char actualLocale[ULOC_FULLNAME_CAPACITY];
char validLocale[ULOC_FULLNAME_CAPACITY];
-
- /**
- * The assignment operator has no real implementation.
- * It's provided to make the compiler happy. Do not call.
- */
- BreakIterator& operator=(const BreakIterator&);
};
#ifndef U_HIDE_DEPRECATED_API
#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
-#endif // _BRKITER
+#endif // BRKITER_H
//eof
#define TEST_ASSERT_SUCCESS(errcode) { if (U_FAILURE(errcode)) { \
errcheckln(errcode, "Failure in file %s, line %d, status = \"%s\"", __FILE__, __LINE__, u_errorName(errcode));}}
-
//---------------------------------------------
// runIndexedTest
//---------------------------------------------
TESTCASE_AUTO(TestBug12918);
TESTCASE_AUTO(TestBug12932);
TESTCASE_AUTO(TestEmoji);
+ TESTCASE_AUTO(TestBug12519);
TESTCASE_AUTO_END;
}
}
+// TestBug12519 - Correct handling of Locales by assignment / copy / clone
+
+// WHERE Macro yields a literal string of the form "source_file_name:line number "
+// TODO: propose something equivalent as a test framework addition.
+
+#define WHERE __FILE__ ":" XLINE(__LINE__) " "
+#define XLINE(s) LINE(s)
+#define LINE(s) #s
+
+void RBBITest::TestBug12519() {
+ UErrorCode status = U_ZERO_ERROR;
+ LocalPointer<RuleBasedBreakIterator> biEn((RuleBasedBreakIterator *)BreakIterator::createWordInstance(Locale::getEnglish(), status));
+ LocalPointer<RuleBasedBreakIterator> biFr((RuleBasedBreakIterator *)BreakIterator::createWordInstance(Locale::getFrance(), status));
+ assertSuccess(WHERE, status);
+ assertTrue(WHERE, Locale::getEnglish() == biEn->getLocale(ULOC_VALID_LOCALE, status));
+ assertTrue(WHERE, Locale::getFrench() == biFr->getLocale(ULOC_VALID_LOCALE, status));
+ assertTrue(WHERE "Locales do not participate in BreakIterator equality.", *biEn == *biFr);
+
+ LocalPointer<RuleBasedBreakIterator>cloneEn((RuleBasedBreakIterator *)biEn->clone());
+ assertTrue(WHERE, *biEn == *cloneEn);
+ assertTrue(WHERE, Locale::getEnglish() == cloneEn->getLocale(ULOC_VALID_LOCALE, status));
+
+ LocalPointer<RuleBasedBreakIterator>cloneFr((RuleBasedBreakIterator *)biFr->clone());
+ assertTrue(WHERE, *biFr == *cloneFr);
+ assertTrue(WHERE, Locale::getFrench() == cloneFr->getLocale(ULOC_VALID_LOCALE, status));
+
+ LocalPointer<RuleBasedBreakIterator>biDe((RuleBasedBreakIterator *)BreakIterator::createLineInstance(Locale::getGerman(), status));
+ UnicodeString text("Hallo Welt");
+ biDe->setText(text);
+ assertTrue(WHERE "before assignment of \"biDe = biFr\", they should be different, but are equal.", *biFr != *biDe);
+ *biDe = *biFr;
+ assertTrue(WHERE "after assignment of \"biDe = biFr\", they should be equal, but are not.", *biFr == *biDe);
+}
+
//
// TestDebug - A place-holder test for debugging purposes.
// For putting in fragments of other tests that can be invoked
void TestBug12918();
void TestBug12932();
void TestEmoji();
+ void TestBug12519();
void TestDebug();
void TestProperties();
}
}
+ @Test
+ public void TestBug12519() {
+ RuleBasedBreakIterator biEn = (RuleBasedBreakIterator)BreakIterator.getWordInstance(ULocale.ENGLISH);
+ RuleBasedBreakIterator biFr = (RuleBasedBreakIterator)BreakIterator.getWordInstance(ULocale.FRANCE);
+ assertEquals("", ULocale.ENGLISH, biEn.getLocale(ULocale.VALID_LOCALE));
+ assertEquals("", ULocale.FRENCH, biFr.getLocale(ULocale.VALID_LOCALE));
+ assertEquals("Locales do not participate in BreakIterator equality.", biEn, biFr);
+
+ RuleBasedBreakIterator cloneEn = (RuleBasedBreakIterator)biEn.clone();
+ assertEquals("", biEn, cloneEn);
+ assertEquals("", ULocale.ENGLISH, cloneEn.getLocale(ULocale.VALID_LOCALE));
+
+ RuleBasedBreakIterator cloneFr = (RuleBasedBreakIterator)biFr.clone();
+ assertEquals("", biFr, cloneFr);
+ assertEquals("", ULocale.FRENCH, cloneFr.getLocale(ULocale.VALID_LOCALE));
+ }
}