/* ********************************************************************** * Copyright (C) 2001, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Date Name Description * 05/24/01 aliu Creation. ********************************************************************** */ #include "tolowtrn.h" #include "unicode/ustring.h" #include "ustr_imp.h" #include "cpputils.h" #include "unicode/uchar.h" U_NAMESPACE_BEGIN const char LowercaseTransliterator::_ID[] = "Any-Lower"; /** * Constructs a transliterator. */ LowercaseTransliterator::LowercaseTransliterator(const Locale& theLoc) : Transliterator(_ID, 0), loc(theLoc) , buffer(0) { buffer = new UChar[u_getMaxCaseExpansion()]; } /** * Destructor. */ LowercaseTransliterator::~LowercaseTransliterator() { delete [] buffer; } /** * Copy constructor. */ LowercaseTransliterator::LowercaseTransliterator(const LowercaseTransliterator& o) : Transliterator(o), loc(o.loc), buffer(0) { buffer = new UChar[u_getMaxCaseExpansion()]; } /** * Assignment operator. */ LowercaseTransliterator& LowercaseTransliterator::operator=( const LowercaseTransliterator& o) { Transliterator::operator=(o); loc = o.loc; uprv_arrayCopy((const UChar*)o.buffer, 0, this->buffer, 0, u_getMaxCaseExpansion()); return *this; } /** * Transliterator API. */ Transliterator* LowercaseTransliterator::clone(void) const { return new LowercaseTransliterator(*this); } /** * Implements {@link Transliterator#handleTransliterate}. */ void LowercaseTransliterator::handleTransliterate(Replaceable& text, UTransPosition& offsets, UBool isIncremental) const { int32_t textPos = offsets.start; int32_t loop; if (textPos >= offsets.limit) return; // get string for context // TODO: add convenience method to do this, since we do it all over UnicodeString original; /*UChar *original = new UChar[offsets.contextLimit - offsets.contextStart+1];*/ // get whole context /* Extract the characters from Replaceable */ for (loop = offsets.contextStart; loop < offsets.contextLimit; loop++) { original.append(text.charAt(loop)); } // Walk through original string // If there is a case change, modify corresponding position in replaceable int32_t i = textPos - offsets.contextStart; int32_t limit = offsets.limit - offsets.contextStart; UChar32 cp, bufferCH; int32_t oldLen; for (; i < limit; ) { UErrorCode status = U_ZERO_ERROR; int32_t s = i; bufferCH = original.char32At(s); UTF_GET_CHAR(original.getBuffer(), 0, i, original.length(), cp); oldLen = UTF_CHAR_LENGTH(cp); i += oldLen; int32_t len = u_strToLower(buffer, u_getMaxCaseExpansion(), original.getBuffer()+s, i-s, loc.getName(), &status); /* Skip checking of status code here because the buffer should not have overflowed. */ UTF_GET_CHAR(buffer, 0, 0, len, cp); if ( bufferCH != cp ) { UnicodeString temp(buffer); text.handleReplaceBetween(textPos, textPos + oldLen, temp); if (len != oldLen) { textPos += len; offsets.limit += len - oldLen; offsets.contextLimit += len - oldLen; continue; } } textPos += oldLen; } offsets.start = offsets.limit; } U_NAMESPACE_END