michael@0: /* michael@0: ********************************************************************** michael@0: * Copyright (C) 2013, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: ********************************************************************** michael@0: * michael@0: * scriptset.cpp michael@0: * michael@0: * created on: 2013 Jan 7 michael@0: * created by: Andy Heninger michael@0: */ michael@0: michael@0: #include "unicode/utypes.h" michael@0: michael@0: #include "unicode/uchar.h" michael@0: #include "unicode/unistr.h" michael@0: michael@0: #include "scriptset.h" michael@0: #include "uassert.h" michael@0: michael@0: U_NAMESPACE_BEGIN michael@0: michael@0: #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) michael@0: michael@0: //---------------------------------------------------------------------------- michael@0: // michael@0: // ScriptSet implementation michael@0: // michael@0: //---------------------------------------------------------------------------- michael@0: ScriptSet::ScriptSet() { michael@0: for (uint32_t i=0; i= (int32_t)sizeof(bits) * 8) { michael@0: status = U_ILLEGAL_ARGUMENT_ERROR; michael@0: return FALSE; michael@0: } michael@0: uint32_t index = script / 32; michael@0: uint32_t bit = 1 << (script & 31); michael@0: return ((bits[index] & bit) != 0); michael@0: } michael@0: michael@0: michael@0: ScriptSet &ScriptSet::set(UScriptCode script, UErrorCode &status) { michael@0: if (U_FAILURE(status)) { michael@0: return *this; michael@0: } michael@0: if (script < 0 || script >= (int32_t)sizeof(bits) * 8) { michael@0: status = U_ILLEGAL_ARGUMENT_ERROR; michael@0: return *this; michael@0: } michael@0: uint32_t index = script / 32; michael@0: uint32_t bit = 1 << (script & 31); michael@0: bits[index] |= bit; michael@0: return *this; michael@0: } michael@0: michael@0: ScriptSet &ScriptSet::reset(UScriptCode script, UErrorCode &status) { michael@0: if (U_FAILURE(status)) { michael@0: return *this; michael@0: } michael@0: if (script < 0 || script >= (int32_t)sizeof(bits) * 8) { michael@0: status = U_ILLEGAL_ARGUMENT_ERROR; michael@0: return *this; michael@0: } michael@0: uint32_t index = script / 32; michael@0: uint32_t bit = 1 << (script & 31); michael@0: bits[index] &= ~bit; michael@0: return *this; michael@0: } michael@0: michael@0: michael@0: michael@0: ScriptSet &ScriptSet::Union(const ScriptSet &other) { michael@0: for (uint32_t i=0; iintersect(t); michael@0: } michael@0: return *this; michael@0: } michael@0: michael@0: UBool ScriptSet::intersects(const ScriptSet &other) const { michael@0: for (uint32_t i=0; i 0) { michael@0: count++; michael@0: x &= (x - 1); // and off the least significant one bit. michael@0: } michael@0: } michael@0: return count; michael@0: } michael@0: michael@0: int32_t ScriptSet::hashCode() const { michael@0: int32_t hash = 0; michael@0: for (int32_t i=0; i= 0; i = nextSetBit(i + 1)) { michael@0: if (!firstTime) { michael@0: dest.append((UChar)0x20); michael@0: } michael@0: firstTime = FALSE; michael@0: const char *scriptName = uscript_getShortName((UScriptCode(i))); michael@0: dest.append(UnicodeString(scriptName, -1, US_INV)); michael@0: } michael@0: return dest; michael@0: } michael@0: michael@0: ScriptSet &ScriptSet::parseScripts(const UnicodeString &scriptString, UErrorCode &status) { michael@0: resetAll(); michael@0: if (U_FAILURE(status)) { michael@0: return *this; michael@0: } michael@0: UnicodeString oneScriptName; michael@0: for (int32_t i=0; i 0) { michael@0: char buf[40]; michael@0: oneScriptName.extract(0, oneScriptName.length(), buf, sizeof(buf)-1, US_INV); michael@0: buf[sizeof(buf)-1] = 0; michael@0: int32_t sc = u_getPropertyValueEnum(UCHAR_SCRIPT, buf); michael@0: if (sc == UCHAR_INVALID_CODE) { michael@0: status = U_ILLEGAL_ARGUMENT_ERROR; michael@0: } else { michael@0: this->set((UScriptCode)sc, status); michael@0: } michael@0: if (U_FAILURE(status)) { michael@0: return *this; michael@0: } michael@0: oneScriptName.remove(); michael@0: } michael@0: } michael@0: return *this; michael@0: } michael@0: michael@0: U_NAMESPACE_END michael@0: michael@0: U_CAPI UBool U_EXPORT2 michael@0: uhash_equalsScriptSet(const UElement key1, const UElement key2) { michael@0: icu::ScriptSet *s1 = static_cast(key1.pointer); michael@0: icu::ScriptSet *s2 = static_cast(key2.pointer); michael@0: return (*s1 == *s2); michael@0: } michael@0: michael@0: U_CAPI int8_t U_EXPORT2 michael@0: uhash_compareScriptSet(UElement key0, UElement key1) { michael@0: icu::ScriptSet *s0 = static_cast(key0.pointer); michael@0: icu::ScriptSet *s1 = static_cast(key1.pointer); michael@0: int32_t diff = s0->countMembers() - s1->countMembers(); michael@0: if (diff != 0) return diff; michael@0: int32_t i0 = s0->nextSetBit(0); michael@0: int32_t i1 = s1->nextSetBit(0); michael@0: while ((diff = i0-i1) == 0 && i0 > 0) { michael@0: i0 = s0->nextSetBit(i0+1); michael@0: i1 = s1->nextSetBit(i1+1); michael@0: } michael@0: return (int8_t)diff; michael@0: } michael@0: michael@0: U_CAPI int32_t U_EXPORT2 michael@0: uhash_hashScriptSet(const UElement key) { michael@0: icu::ScriptSet *s = static_cast(key.pointer); michael@0: return s->hashCode(); michael@0: } michael@0: michael@0: U_CAPI void U_EXPORT2 michael@0: uhash_deleteScriptSet(void *obj) { michael@0: icu::ScriptSet *s = static_cast(obj); michael@0: delete s; michael@0: }