Get string operations working on 3ds
This commit is contained in:
514
Shared/source/UnicodeScalarProps.cpp
Normal file
514
Shared/source/UnicodeScalarProps.cpp
Normal file
@@ -0,0 +1,514 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2021 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include "../include/ScalarPropsData.h"
|
||||
#include "../include/CaseData.h"
|
||||
#include "../include/ScriptData.h"
|
||||
|
||||
#include "UnicodeData.h"
|
||||
#include <stdint.h>
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
__swift_uint64_t _swift_stdlib_getBinaryProperties(__swift_uint32_t scalar) {
|
||||
auto lowerBoundIndex = 0;
|
||||
auto endIndex = BIN_PROPS_COUNT;
|
||||
auto upperBoundIndex = endIndex - 1;
|
||||
|
||||
while (upperBoundIndex >= lowerBoundIndex) {
|
||||
auto index = lowerBoundIndex + (upperBoundIndex - lowerBoundIndex) / 2;
|
||||
|
||||
auto entry = _swift_stdlib_scalar_binProps[index];
|
||||
|
||||
// Shift the ccc value out of the scalar.
|
||||
auto lowerBoundScalar = (entry << 11) >> 11;
|
||||
|
||||
__swift_uint32_t upperBoundScalar = 0;
|
||||
|
||||
// If we're not at the end of the array, the range count is simply the
|
||||
// distance to the next element.
|
||||
if (index != endIndex - 1) {
|
||||
auto nextEntry = _swift_stdlib_scalar_binProps[index + 1];
|
||||
|
||||
auto nextLower = (nextEntry << 11) >> 11;
|
||||
|
||||
upperBoundScalar = nextLower - 1;
|
||||
} else {
|
||||
// Otherwise, the range count is the distance to 0x10FFFF
|
||||
upperBoundScalar = 0x10FFFF;
|
||||
}
|
||||
|
||||
// Shift everything out.
|
||||
auto dataIndex = entry >> 21;
|
||||
|
||||
if (scalar >= lowerBoundScalar && scalar <= upperBoundScalar) {
|
||||
return _swift_stdlib_scalar_binProps_data[dataIndex];
|
||||
}
|
||||
|
||||
if (scalar > upperBoundScalar) {
|
||||
lowerBoundIndex = index + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scalar < lowerBoundScalar) {
|
||||
upperBoundIndex = index - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we make it out of this loop, then it means the scalar was not found at
|
||||
// all in the array. This should never happen because the array represents all
|
||||
// scalars from 0x0 to 0x10FFFF, but if somehow this branch gets reached,
|
||||
// return 0 to indicate no properties.
|
||||
return 0;
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
__swift_uint8_t _swift_stdlib_getNumericType(__swift_uint32_t scalar) {
|
||||
auto lowerBoundIndex = 0;
|
||||
auto endIndex = NUMERIC_TYPE_COUNT;
|
||||
auto upperBoundIndex = endIndex - 1;
|
||||
|
||||
while (upperBoundIndex >= lowerBoundIndex) {
|
||||
auto idx = lowerBoundIndex + (upperBoundIndex - lowerBoundIndex) / 2;
|
||||
|
||||
auto entry = _swift_stdlib_numeric_type[idx];
|
||||
|
||||
auto lowerBoundScalar = (entry << 11) >> 11;
|
||||
auto rangeCount = (entry << 3) >> 24;
|
||||
auto upperBoundScalar = lowerBoundScalar + rangeCount;
|
||||
|
||||
auto numericType = (__swift_uint8_t)(entry >> 29);
|
||||
|
||||
if (scalar >= lowerBoundScalar && scalar <= upperBoundScalar) {
|
||||
return numericType;
|
||||
}
|
||||
|
||||
if (scalar > upperBoundScalar) {
|
||||
lowerBoundIndex = idx + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scalar < lowerBoundScalar) {
|
||||
upperBoundIndex = idx - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we made it out here, then our scalar was not found in the composition
|
||||
// array.
|
||||
// Return the max here to indicate that we couldn't find one.
|
||||
return UINT8_MAX;
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
double _swift_stdlib_getNumericValue(__swift_uint32_t scalar) {
|
||||
auto levelCount = NUMERIC_VALUES_LEVEL_COUNT;
|
||||
__swift_intptr_t scalarIdx = _swift_stdlib_getMphIdx(scalar, levelCount,
|
||||
_swift_stdlib_numeric_values_keys,
|
||||
_swift_stdlib_numeric_values_ranks,
|
||||
_swift_stdlib_numeric_values_sizes);
|
||||
|
||||
auto valueIdx = _swift_stdlib_numeric_values_indices[scalarIdx];
|
||||
return _swift_stdlib_numeric_values[valueIdx];
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
const char *_swift_stdlib_getNameAlias(__swift_uint32_t scalar) {
|
||||
auto dataIdx = _swift_stdlib_getScalarBitArrayIdx(scalar,
|
||||
_swift_stdlib_nameAlias,
|
||||
_swift_stdlib_nameAlias_ranks);
|
||||
|
||||
if (dataIdx == INTPTR_MAX) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return _swift_stdlib_nameAlias_data[dataIdx];
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
__swift_int32_t _swift_stdlib_getMapping(__swift_uint32_t scalar,
|
||||
__swift_uint8_t mapping) {
|
||||
auto dataIdx = _swift_stdlib_getScalarBitArrayIdx(scalar,
|
||||
_swift_stdlib_mappings,
|
||||
_swift_stdlib_mappings_ranks);
|
||||
|
||||
if (dataIdx == INTPTR_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto mappings = _swift_stdlib_mappings_data_indices[dataIdx];
|
||||
|
||||
__swift_uint8_t mappingIdx;
|
||||
|
||||
switch (mapping) {
|
||||
// Uppercase
|
||||
case 0:
|
||||
mappingIdx = mappings & 0xFF;
|
||||
break;
|
||||
|
||||
// Lowercase
|
||||
case 1:
|
||||
mappingIdx = (mappings & 0xFF00) >> 8;
|
||||
break;
|
||||
|
||||
// Titlecase
|
||||
case 2:
|
||||
mappingIdx = (mappings & 0xFF0000) >> 16;
|
||||
break;
|
||||
|
||||
// Unknown mapping
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mappingIdx == 0xFF) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _swift_stdlib_mappings_data[mappingIdx];
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
const __swift_uint8_t *_swift_stdlib_getSpecialMapping(__swift_uint32_t scalar,
|
||||
__swift_uint8_t mapping,
|
||||
__swift_intptr_t *length) {
|
||||
auto dataIdx = _swift_stdlib_getScalarBitArrayIdx(scalar,
|
||||
_swift_stdlib_special_mappings,
|
||||
_swift_stdlib_special_mappings_ranks);
|
||||
|
||||
if (dataIdx == INTPTR_MAX) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto index = _swift_stdlib_special_mappings_data_indices[dataIdx];
|
||||
|
||||
auto uppercase = _swift_stdlib_special_mappings_data + index;
|
||||
auto lowercase = uppercase + 1 + *uppercase;
|
||||
auto titlecase = lowercase + 1 + *lowercase;
|
||||
|
||||
switch (mapping) {
|
||||
// Uppercase
|
||||
case 0:
|
||||
*length = *uppercase;
|
||||
return uppercase + 1;
|
||||
|
||||
// Lowercase
|
||||
case 1:
|
||||
*length = *lowercase;
|
||||
return lowercase + 1;
|
||||
|
||||
// Titlecase
|
||||
case 2:
|
||||
*length = *titlecase;
|
||||
return titlecase + 1;
|
||||
|
||||
// Unknown mapping.
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
__swift_intptr_t _swift_stdlib_getScalarName(__swift_uint32_t scalar,
|
||||
__swift_uint8_t *buffer,
|
||||
__swift_intptr_t capacity) {
|
||||
auto setOffset = _swift_stdlib_names_scalar_sets[scalar >> 7];
|
||||
|
||||
if (setOffset == UINT16_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto scalarIndex = (setOffset << 7) + (scalar & ((1 << 7) - 1));
|
||||
auto scalarOffset = _swift_stdlib_names_scalars[scalarIndex];
|
||||
|
||||
// U+20 is the first scalar that Unicode defines a name for, so their offset
|
||||
// will the only valid 0.
|
||||
if (scalarOffset == 0 && scalar != 0x20) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
__swift_uint32_t nextScalarOffset = 0;
|
||||
|
||||
if (scalarIndex != NAMES_SCALARS_MAX_INDEX) {
|
||||
int i = 1;
|
||||
|
||||
// Look for the next scalar who has a name and their position in the names
|
||||
// array. This tells us exactly how many bytes our name takes up.
|
||||
while (nextScalarOffset == 0) {
|
||||
nextScalarOffset = _swift_stdlib_names_scalars[scalarIndex + i];
|
||||
i += 1;
|
||||
}
|
||||
} else {
|
||||
// This is the last element in the array which represents the last scalar
|
||||
// name that Unicode defines (excluding variation selectors).
|
||||
nextScalarOffset = NAMES_LAST_SCALAR_OFFSET;
|
||||
}
|
||||
|
||||
auto nameSize = nextScalarOffset - scalarOffset;
|
||||
|
||||
// The total number of initialized bytes in the name string.
|
||||
int c = 0;
|
||||
|
||||
for (__swift_uint32_t i = 0; i < nameSize; i += 1) {
|
||||
__swift_uint16_t wordIndex = (__swift_uint16_t) _swift_stdlib_names[
|
||||
scalarOffset + i
|
||||
];
|
||||
|
||||
// If our word index is 0xFF, then it means our word index is larger than a
|
||||
// byte, so the next two bytes will compose the 16 bit index.
|
||||
if (wordIndex == 0xFF) {
|
||||
i += 1;
|
||||
auto firstPart = _swift_stdlib_names[scalarOffset + i];
|
||||
wordIndex = firstPart;
|
||||
|
||||
i += 1;
|
||||
auto secondPart = _swift_stdlib_names[scalarOffset + i];
|
||||
wordIndex |= secondPart << 8;
|
||||
}
|
||||
|
||||
auto wordOffset = _swift_stdlib_word_indices[wordIndex];
|
||||
|
||||
auto word = _swift_stdlib_words + wordOffset;
|
||||
|
||||
// The last character in a word has the 7th bit set.
|
||||
while (*word < 0x80) {
|
||||
if (c >= capacity) {
|
||||
return c;
|
||||
}
|
||||
|
||||
buffer[c++] = *word++;
|
||||
}
|
||||
|
||||
if (c >= capacity) {
|
||||
return c;
|
||||
}
|
||||
|
||||
buffer[c++] = *word & 0x7F;
|
||||
|
||||
if (c >= capacity) {
|
||||
return c;
|
||||
}
|
||||
|
||||
buffer[c++] = ' ';
|
||||
}
|
||||
|
||||
// Remove the trailing space.
|
||||
c -= 1;
|
||||
|
||||
// The return value is the number of initialized bytes.
|
||||
return c;
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
__swift_uint16_t _swift_stdlib_getAge(__swift_uint32_t scalar) {
|
||||
auto lowerBoundIndex = 0;
|
||||
auto endIndex = AGE_COUNT;
|
||||
auto upperBoundIndex = endIndex - 1;
|
||||
|
||||
while (upperBoundIndex >= lowerBoundIndex) {
|
||||
auto idx = lowerBoundIndex + (upperBoundIndex - lowerBoundIndex) / 2;
|
||||
|
||||
auto entry = _swift_stdlib_ages[idx];
|
||||
|
||||
auto lowerBoundScalar = (entry << 43) >> 43;
|
||||
auto rangeCount = entry >> 32;
|
||||
auto upperBoundScalar = lowerBoundScalar + rangeCount;
|
||||
|
||||
auto ageIdx = (__swift_uint8_t)((entry << 32) >> 32 >> 21);
|
||||
|
||||
if (scalar >= lowerBoundScalar && scalar <= upperBoundScalar) {
|
||||
return _swift_stdlib_ages_data[ageIdx];
|
||||
}
|
||||
|
||||
if (scalar > upperBoundScalar) {
|
||||
lowerBoundIndex = idx + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scalar < lowerBoundScalar) {
|
||||
upperBoundIndex = idx - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we made it out here, then our scalar was not found in the composition
|
||||
// array.
|
||||
// Return the max here to indicate that we couldn't find one.
|
||||
return UINT16_MAX;
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
__swift_uint8_t _swift_stdlib_getGeneralCategory(__swift_uint32_t scalar) {
|
||||
auto lowerBoundIndex = 0;
|
||||
auto endIndex = GENERAL_CATEGORY_COUNT;
|
||||
auto upperBoundIndex = endIndex - 1;
|
||||
|
||||
while (upperBoundIndex >= lowerBoundIndex) {
|
||||
auto idx = lowerBoundIndex + (upperBoundIndex - lowerBoundIndex) / 2;
|
||||
|
||||
auto entry = _swift_stdlib_generalCategory[idx];
|
||||
|
||||
auto lowerBoundScalar = (entry << 43) >> 43;
|
||||
auto rangeCount = entry >> 32;
|
||||
auto upperBoundScalar = lowerBoundScalar + rangeCount;
|
||||
|
||||
auto generalCategory = (__swift_uint8_t)((entry << 32) >> 32 >> 21);
|
||||
|
||||
if (scalar >= lowerBoundScalar && scalar <= upperBoundScalar) {
|
||||
return generalCategory;
|
||||
}
|
||||
|
||||
if (scalar > upperBoundScalar) {
|
||||
lowerBoundIndex = idx + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scalar < lowerBoundScalar) {
|
||||
upperBoundIndex = idx - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we made it out here, then our scalar was not found in the composition
|
||||
// array.
|
||||
// Return the max here to indicate that we couldn't find one.
|
||||
return UINT8_MAX;
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
__swift_uint8_t _swift_stdlib_getScript(__swift_uint32_t scalar) {
|
||||
auto lowerBoundIndex = 0;
|
||||
auto endIndex = SCRIPTS_COUNT;
|
||||
auto upperBoundIndex = endIndex - 1;
|
||||
|
||||
while (upperBoundIndex >= lowerBoundIndex) {
|
||||
auto index = lowerBoundIndex + (upperBoundIndex - lowerBoundIndex) / 2;
|
||||
|
||||
auto entry = _swift_stdlib_scripts[index];
|
||||
|
||||
// Shift the enum value out of the scalar.
|
||||
auto lowerBoundScalar = (entry << 11) >> 11;
|
||||
|
||||
__swift_uint32_t upperBoundScalar = 0;
|
||||
|
||||
// If we're not at the end of the array, the range count is simply the
|
||||
// distance to the next element.
|
||||
if (index != endIndex - 1) {
|
||||
auto nextEntry = _swift_stdlib_scripts[index + 1];
|
||||
|
||||
auto nextLower = (nextEntry << 11) >> 11;
|
||||
|
||||
upperBoundScalar = nextLower - 1;
|
||||
} else {
|
||||
// Otherwise, the range count is the distance to 0x10FFFF
|
||||
upperBoundScalar = 0x10FFFF;
|
||||
}
|
||||
|
||||
// Shift the scalar out and get the enum value.
|
||||
auto script = entry >> 21;
|
||||
|
||||
if (scalar >= lowerBoundScalar && scalar <= upperBoundScalar) {
|
||||
return script;
|
||||
}
|
||||
|
||||
if (scalar > upperBoundScalar) {
|
||||
lowerBoundIndex = index + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scalar < lowerBoundScalar) {
|
||||
upperBoundIndex = index - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we make it out of this loop, then it means the scalar was not found at
|
||||
// all in the array. This should never happen because the array represents all
|
||||
// scalars from 0x0 to 0x10FFFF, but if somehow this branch gets reached,
|
||||
// return 255 to indicate a failure.
|
||||
return UINT8_MAX;
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
const __swift_uint8_t *_swift_stdlib_getScriptExtensions(__swift_uint32_t scalar,
|
||||
__swift_uint8_t *count) {
|
||||
auto dataIdx = _swift_stdlib_getScalarBitArrayIdx(scalar,
|
||||
_swift_stdlib_script_extensions,
|
||||
_swift_stdlib_script_extensions_ranks);
|
||||
|
||||
// If we don't have an index into the data indices, then this scalar has no
|
||||
// script extensions
|
||||
if (dataIdx == INTPTR_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto scalarDataIdx = _swift_stdlib_script_extensions_data_indices[dataIdx];
|
||||
*count = scalarDataIdx >> 11;
|
||||
|
||||
return _swift_stdlib_script_extensions_data + (scalarDataIdx & 0x7FF);
|
||||
}
|
||||
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
void _swift_stdlib_getCaseMapping(__swift_uint32_t scalar,
|
||||
__swift_uint32_t *buffer) {
|
||||
auto mphIdx = _swift_stdlib_getMphIdx(scalar, CASE_FOLD_LEVEL_COUNT,
|
||||
_swift_stdlib_case_keys,
|
||||
_swift_stdlib_case_ranks,
|
||||
_swift_stdlib_case_sizes);
|
||||
|
||||
auto caseValue = _swift_stdlib_case[mphIdx];
|
||||
__swift_uint32_t hashedScalar = (caseValue << 43) >> 43;
|
||||
|
||||
// If our scalar is not the original one we hashed, then this scalar has no
|
||||
// case mapping. It maps to itself.
|
||||
if (scalar != hashedScalar) {
|
||||
buffer[0] = scalar;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the top bit is NOT set, then this scalar simply maps to another scalar.
|
||||
// We have stored the distance to said scalar in this value.
|
||||
if ((caseValue & ((__swift_uint64_t)(0x1) << 63)) == 0) {
|
||||
auto distance = (__swift_int32_t)((caseValue << 1) >> 22);
|
||||
auto mappedScalar = (__swift_uint32_t)((__swift_int32_t)(scalar) - distance);
|
||||
|
||||
buffer[0] = mappedScalar;
|
||||
return;
|
||||
}
|
||||
|
||||
// Our top bit WAS set which means this scalar maps to multiple scalars.
|
||||
// Lookup our mapping in the full mph.
|
||||
auto fullMphIdx = _swift_stdlib_getMphIdx(scalar, CASE_FULL_FOLD_LEVEL_COUNT,
|
||||
_swift_stdlib_case_full_keys,
|
||||
_swift_stdlib_case_full_ranks,
|
||||
_swift_stdlib_case_full_sizes);
|
||||
|
||||
auto fullCaseValue = _swift_stdlib_case_full[fullMphIdx];
|
||||
|
||||
// Count is either 2 or 3.
|
||||
auto count = fullCaseValue >> 62;
|
||||
|
||||
for (__swift_uint64_t i = 0; i != count; i += 1) {
|
||||
auto distance = (__swift_int32_t)(fullCaseValue & 0xFFFF);
|
||||
|
||||
if ((fullCaseValue & 0x10000) != 0) {
|
||||
distance = -distance;
|
||||
}
|
||||
|
||||
fullCaseValue >>= 17;
|
||||
|
||||
auto mappedScalar = (__swift_uint32_t)((__swift_int32_t)(scalar) - distance);
|
||||
|
||||
buffer[i] = mappedScalar;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user