-
- // The String Lengths Table
- // While copying into the runtime array do some sanity checks on the values
- // Each complete entry contains two fields, an index and an offset.
- // Lengths should increase with each entry.
- // Offsets should be less than the size of the string table.
- int32_t lengthTableLength = fStringLengthsTable->size();
- uint16_t *stringLengths =
- static_cast<uint16_t *>(fSpoofImpl->fSpoofData->reserveSpace(lengthTableLength*sizeof(uint16_t), status));
- if (U_FAILURE(status)) {
- return;
- }
- int32_t destIndex = 0;
- uint32_t previousLength = 0;
- for (i=0; i<lengthTableLength; i+=2) {
- uint32_t offset = static_cast<uint32_t>(fStringLengthsTable->elementAti(i));
- uint32_t length = static_cast<uint32_t>(fStringLengthsTable->elementAti(i+1));
- U_ASSERT(offset < stringsLength);
- U_ASSERT(length < 40);
- U_ASSERT(length > previousLength);
- stringLengths[destIndex++] = static_cast<uint16_t>(offset);
- stringLengths[destIndex++] = static_cast<uint16_t>(length);
- previousLength = length;
- }
- rawData = fSpoofImpl->fSpoofData->fRawData;
- rawData->fCFUStringLengths = (int32_t)((char *)stringLengths - (char *)rawData);
- // Note: StringLengthsSize in the raw data is the number of complete entries,
- // each consisting of a pair of 16 bit values, hence the divide by 2.
- rawData->fCFUStringLengthsSize = lengthTableLength / 2;
- fSpoofImpl->fSpoofData->fCFUStringLengths =
- reinterpret_cast<SpoofStringLengthsElement *>(stringLengths);
-}
-
-
-
-// addKeyEntry Construction of the confusable Key and Mapping Values tables.
-// This is an intermediate point in the building process.
-// We already have the mappings in the hash tables fSLTable, etc.
-// This function builds corresponding run-time style table entries into
-// fKeyVec and fValueVec
-
-void ConfusabledataBuilder::addKeyEntry(
- UChar32 keyChar, // The key character
- UHashtable *table, // The table, one of SATable, MATable, etc.
- int32_t tableFlag, // One of USPOOF_SA_TABLE_FLAG, etc.
- UErrorCode &status) {
-
- SPUString *targetMapping = static_cast<SPUString *>(uhash_iget(table, keyChar));
- if (targetMapping == NULL) {
- // No mapping for this key character.
- // (This function is called for all four tables for each key char that
- // is seen anywhere, so this no entry cases are very much expected.)
- return;
- }
-
- // Check whether there is already an entry with the correct mapping.
- // If so, simply set the flag in the keyTable saying that the existing entry
- // applies to the table that we're doing now.
-
- UBool keyHasMultipleValues = FALSE;
- int32_t i;
- for (i=fKeyVec->size()-1; i>=0 ; i--) {
- int32_t key = fKeyVec->elementAti(i);
- if ((key & 0x0ffffff) != keyChar) {
- // We have now checked all existing key entries for this key char (if any)
- // without finding one with the same mapping.
- break;
- }
- UnicodeString mapping = getMapping(i);
- if (mapping == *(targetMapping->fStr)) {
- // The run time entry we are currently testing has the correct mapping.
- // Set the flag in it indicating that it applies to the new table also.
- key |= tableFlag;
- fKeyVec->setElementAt(key, i);
- return;
- }
- keyHasMultipleValues = TRUE;
- }
-
- // Need to add a new entry to the binary data being built for this mapping.
- // Includes adding entries to both the key table and the parallel values table.
-
- int32_t newKey = keyChar | tableFlag;
- if (keyHasMultipleValues) {
- newKey |= USPOOF_KEY_MULTIPLE_VALUES;
- }
- int32_t adjustedMappingLength = targetMapping->fStr->length() - 1;
- if (adjustedMappingLength>3) {
- adjustedMappingLength = 3;
- }
- newKey |= adjustedMappingLength << USPOOF_KEY_LENGTH_SHIFT;
-
- int32_t newData = targetMapping->fStrTableIndex;
-
- fKeyVec->addElement(newKey, status);
- fValueVec->addElement(newData, status);
-
- // If the preceding key entry is for the same key character (but with a different mapping)
- // set the multiple-values flag on it.
- if (keyHasMultipleValues) {
- int32_t previousKeyIndex = fKeyVec->size() - 2;
- int32_t previousKey = fKeyVec->elementAti(previousKeyIndex);
- previousKey |= USPOOF_KEY_MULTIPLE_VALUES;
- fKeyVec->setElementAt(previousKey, previousKeyIndex);
- }
-}
-
-
-
-UnicodeString ConfusabledataBuilder::getMapping(int32_t index) {
- int32_t key = fKeyVec->elementAti(index);
- int32_t value = fValueVec->elementAti(index);
- int32_t length = USPOOF_KEY_LENGTH_FIELD(key);
- int32_t lastIndexWithLen;
- switch (length) {
- case 0:
- return UnicodeString(static_cast<UChar>(value));
- case 1:
- case 2:
- return UnicodeString(*fStringTable, value, length+1);
- case 3:
- length = 0;
- int32_t i;
- for (i=0; i<fStringLengthsTable->size(); i+=2) {
- lastIndexWithLen = fStringLengthsTable->elementAti(i);
- if (value <= lastIndexWithLen) {
- length = fStringLengthsTable->elementAti(i+1);
- break;
- }
- }
- U_ASSERT(length>=3);
- return UnicodeString(*fStringTable, value, length);
- default:
- U_ASSERT(FALSE);
- }
- return UnicodeString();