18393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/*
28393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius**********************************************************************
3f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius*   Copyright (C) 2014, International Business Machines
48393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius*   Corporation and others.  All Rights Reserved.
58393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius**********************************************************************
68393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius*
78393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius* scriptset.cpp
88393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius*
98393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius* created on: 2013 Jan 7
108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius* created by: Andy Heninger
118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius*/
128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "unicode/utypes.h"
148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "unicode/uchar.h"
168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "unicode/unistr.h"
178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "scriptset.h"
198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "uassert.h"
20f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "cmemory.h"
218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_NAMESPACE_BEGIN
238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius//----------------------------------------------------------------------------
258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius//
268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius//  ScriptSet implementation
278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius//
288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius//----------------------------------------------------------------------------
298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet::ScriptSet() {
30f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        bits[i] = 0;
328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet::~ScriptSet() {
368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet::ScriptSet(const ScriptSet &other) {
398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    *this = other;
408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet & ScriptSet::operator =(const ScriptSet &other) {
44f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        bits[i] = other.bits[i];
468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return *this;
488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUBool ScriptSet::operator == (const ScriptSet &other) const {
52f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (bits[i] != other.bits[i]) {
548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return FALSE;
558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return TRUE;
588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUBool ScriptSet::test(UScriptCode script, UErrorCode &status) const {
618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (U_FAILURE(status)) {
628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return FALSE;
638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (script < 0 || script >= (int32_t)sizeof(bits) * 8) {
658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        status = U_ILLEGAL_ARGUMENT_ERROR;
668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return FALSE;
678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    uint32_t index = script / 32;
698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    uint32_t bit   = 1 << (script & 31);
708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return ((bits[index] & bit) != 0);
718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet &ScriptSet::set(UScriptCode script, UErrorCode &status) {
758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (U_FAILURE(status)) {
768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return *this;
778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (script < 0 || script >= (int32_t)sizeof(bits) * 8) {
798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        status = U_ILLEGAL_ARGUMENT_ERROR;
808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return *this;
818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    uint32_t index = script / 32;
838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    uint32_t bit   = 1 << (script & 31);
848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    bits[index] |= bit;
858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return *this;
868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet &ScriptSet::reset(UScriptCode script, UErrorCode &status) {
898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (U_FAILURE(status)) {
908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return *this;
918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (script < 0 || script >= (int32_t)sizeof(bits) * 8) {
938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        status = U_ILLEGAL_ARGUMENT_ERROR;
948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return *this;
958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    uint32_t index = script / 32;
978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    uint32_t bit   = 1 << (script & 31);
988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    bits[index] &= ~bit;
998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return *this;
1008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet &ScriptSet::Union(const ScriptSet &other) {
105f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
1068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        bits[i] |= other.bits[i];
1078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return *this;
1098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet &ScriptSet::intersect(const ScriptSet &other) {
112f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
1138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        bits[i] &= other.bits[i];
1148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return *this;
1168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet &ScriptSet::intersect(UScriptCode script, UErrorCode &status) {
1198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    ScriptSet t;
1208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    t.set(script, status);
1218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (U_SUCCESS(status)) {
1228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        this->intersect(t);
1238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return *this;
1258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUBool ScriptSet::intersects(const ScriptSet &other) const {
128f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
1298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if ((bits[i] & other.bits[i]) != 0) {
1308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return true;
1318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
1328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return false;
1348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUBool ScriptSet::contains(const ScriptSet &other) const {
1378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    ScriptSet t(*this);
1388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    t.intersect(other);
1398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return (t == other);
1408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet &ScriptSet::setAll() {
144f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
1458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        bits[i] = 0xffffffffu;
1468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return *this;
1488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet &ScriptSet::resetAll() {
152f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
1538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        bits[i] = 0;
1548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return *this;
1568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusint32_t ScriptSet::countMembers() const {
1598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // This bit counter is good for sparse numbers of '1's, which is
1608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    //  very much the case that we will usually have.
1618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    int32_t count = 0;
162f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
1638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        uint32_t x = bits[i];
1648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        while (x > 0) {
1658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            count++;
1668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            x &= (x - 1);    // and off the least significant one bit.
1678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
1688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return count;
1708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusint32_t ScriptSet::hashCode() const {
1738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    int32_t hash = 0;
174f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (int32_t i=0; i<UPRV_LENGTHOF(bits); i++) {
1758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        hash ^= bits[i];
1768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return hash;
1788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusint32_t ScriptSet::nextSetBit(int32_t fromIndex) const {
1818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // TODO: Wants a better implementation.
1828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (fromIndex < 0) {
1838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return -1;
1848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
1868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    for (int32_t scriptIndex = fromIndex; scriptIndex < (int32_t)sizeof(bits)*8; scriptIndex++) {
1878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (test((UScriptCode)scriptIndex, status)) {
1888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return scriptIndex;
1898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
1908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
1918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return -1;
1928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
1938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString &ScriptSet::displayScripts(UnicodeString &dest) const {
1958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UBool firstTime = TRUE;
1968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    for (int32_t i = nextSetBit(0); i >= 0; i = nextSetBit(i + 1)) {
1978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (!firstTime) {
19859d709d503bab6e2b61931737e662dd293b40578ccornelius            dest.append((UChar)0x20);
1998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
2008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        firstTime = FALSE;
2018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        const char *scriptName = uscript_getShortName((UScriptCode(i)));
2028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        dest.append(UnicodeString(scriptName, -1, US_INV));
2038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
2048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return dest;
2058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
2068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
2078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusScriptSet &ScriptSet::parseScripts(const UnicodeString &scriptString, UErrorCode &status) {
2088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    resetAll();
2098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (U_FAILURE(status)) {
2108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return *this;
2118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
2128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UnicodeString oneScriptName;
2138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    for (int32_t i=0; i<scriptString.length();) {
2148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        UChar32 c = scriptString.char32At(i);
2158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        i = scriptString.moveIndex32(i, 1);
2168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (!u_isUWhiteSpace(c)) {
2178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            oneScriptName.append(c);
2188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (i < scriptString.length()) {
2198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                continue;
2208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
2218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
2228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (oneScriptName.length() > 0) {
2238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            char buf[40];
2248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            oneScriptName.extract(0, oneScriptName.length(), buf, sizeof(buf)-1, US_INV);
2258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            buf[sizeof(buf)-1] = 0;
2268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            int32_t sc = u_getPropertyValueEnum(UCHAR_SCRIPT, buf);
2278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (sc == UCHAR_INVALID_CODE) {
2288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                status = U_ILLEGAL_ARGUMENT_ERROR;
2298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            } else {
2308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                this->set((UScriptCode)sc, status);
2318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
2328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (U_FAILURE(status)) {
2338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                return *this;
2348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
2358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            oneScriptName.remove();
2368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
2378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
2388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return *this;
2398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
2408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
2418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_NAMESPACE_END
2428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
2438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_CAPI UBool U_EXPORT2
2448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusuhash_equalsScriptSet(const UElement key1, const UElement key2) {
2458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    icu::ScriptSet *s1 = static_cast<icu::ScriptSet *>(key1.pointer);
2468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    icu::ScriptSet *s2 = static_cast<icu::ScriptSet *>(key2.pointer);
2478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return (*s1 == *s2);
2488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
2498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
2508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_CAPI int8_t U_EXPORT2
2518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusuhash_compareScriptSet(UElement key0, UElement key1) {
2528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    icu::ScriptSet *s0 = static_cast<icu::ScriptSet *>(key0.pointer);
2538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    icu::ScriptSet *s1 = static_cast<icu::ScriptSet *>(key1.pointer);
2548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    int32_t diff = s0->countMembers() - s1->countMembers();
2558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (diff != 0) return diff;
2568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    int32_t i0 = s0->nextSetBit(0);
2578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    int32_t i1 = s1->nextSetBit(0);
2588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    while ((diff = i0-i1) == 0 && i0 > 0) {
2598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        i0 = s0->nextSetBit(i0+1);
2608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        i1 = s1->nextSetBit(i1+1);
2618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
2628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return (int8_t)diff;
2638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
2648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
2658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_CAPI int32_t U_EXPORT2
2668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusuhash_hashScriptSet(const UElement key) {
2678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    icu::ScriptSet *s = static_cast<icu::ScriptSet *>(key.pointer);
2688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return s->hashCode();
2698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
2708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
2718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_CAPI void U_EXPORT2
2728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusuhash_deleteScriptSet(void *obj) {
2738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    icu::ScriptSet *s = static_cast<icu::ScriptSet *>(obj);
2748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    delete s;
2758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
276