/* ********************************************************************** * Copyright (C) 1999, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Date Name Description * 11/17/99 aliu Creation. ********************************************************************** */ #include "unirange.h" #include "uvector.h" #include "unicode/unistr.h" U_NAMESPACE_BEGIN UnicodeRange::UnicodeRange(UChar theStart, int32_t theLength) { start = theStart; length = theLength; } UnicodeRange* UnicodeRange::clone() const { return new UnicodeRange(start, length); } /** * CALLER OWNS RESULT. */ UBool UnicodeRange::contains(UChar c) const { return c >= start && (c - start) < length; } /** * Assume that contains(c) is true. Split this range into two new * ranges around the character c. Make this range one of the new ranges * (modify it in place) and return the other new range. The character * itself is not included in either range. If the split results in an * empty range (that is, if c == start or c == start + length - 1) then * return null. * * MODIFIES THIS RANGE IN PLACE. * * CALLER OWNS RESULT. */ UnicodeRange* UnicodeRange::split(UChar c) { if (c == start) { ++start; --length; return 0; } else if (c - start == length - 1) { --length; return 0; } else { ++c; UnicodeRange* r = new UnicodeRange(c, start + length - c); length = --c - start; return r; } } /** * Finds the largest unused subrange by the given string. A * subrange is unused by a string if the string contains no * characters in that range. If the given string contains no * characters in this range, then this range itself is * returned. * * CALLER OWNS RESULT. */ UnicodeRange* UnicodeRange::largestUnusedSubrange(const UnicodeString& str, UErrorCode &status) const { int32_t n = str.length(); UVector v(status); if (U_FAILURE(status)) { return NULL; } v.setDeleter(UnicodeRange::deleter); v.addElement(clone(), status); for (int32_t i=0; icontains(c)) { r = r->split(c); if (r != 0) { v.addElement(r, status); } break; } } } } UnicodeRange* bestRange = 0; int32_t ibest = -1; for (int32_t j=0; jlength > bestRange->length) { bestRange = r; ibest = j; } } v.orphanElementAt(ibest); // So bestRange doesn't get deleted return bestRange; } // For UVector of UnicodeRange* objects void U_CALLCONV UnicodeRange::deleter(void* e) { delete (UnicodeRange*) e; } U_NAMESPACE_END