File: UnicodeNormalization.cpp

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (139 lines) | stat: -rw-r--r-- 4,290 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#if SWIFT_STDLIB_ENABLE_UNICODE_DATA

#if defined(__APPLE__)
#include "Apple/NormalizationData.h"
#else
#include "Common/NormalizationData.h"
#endif

#else
#include "swift/Runtime/Debug.h"
#endif

#include "swift/shims/UnicodeData.h"
#include <limits>

SWIFT_RUNTIME_STDLIB_INTERNAL
__swift_uint16_t _swift_stdlib_getNormData(__swift_uint32_t scalar) {
  // Fast Path: ASCII and some latiny scalars are very basic and have no
  // normalization properties.
  if (scalar < 0xC0) {
    return 0;
  }
  
#if !SWIFT_STDLIB_ENABLE_UNICODE_DATA
  swift::swift_abortDisabledUnicodeSupport();
#else
  auto dataIdx = _swift_stdlib_getScalarBitArrayIdx(scalar,
                                                    _swift_stdlib_normData,
                                                  _swift_stdlib_normData_ranks);

  // If we don't have an index into the data indices, then this scalar has no
  // normalization information.
  if (dataIdx == std::numeric_limits<__swift_intptr_t>::max()) {
    return 0;
  }

  auto scalarDataIdx = _swift_stdlib_normData_data_indices[dataIdx];
  return _swift_stdlib_normData_data[scalarDataIdx];
#endif
}

#if SWIFT_STDLIB_ENABLE_UNICODE_DATA
SWIFT_RUNTIME_STDLIB_INTERNAL
const __swift_uint8_t * const _swift_stdlib_nfd_decompositions = _swift_stdlib_nfd_decomp;
#else
SWIFT_RUNTIME_STDLIB_INTERNAL
const __swift_uint8_t * const _swift_stdlib_nfd_decompositions = nullptr;
#endif

SWIFT_RUNTIME_STDLIB_INTERNAL
__swift_uint32_t _swift_stdlib_getDecompositionEntry(__swift_uint32_t scalar) {
#if !SWIFT_STDLIB_ENABLE_UNICODE_DATA
  swift::swift_abortDisabledUnicodeSupport();
#else
  auto levelCount = NFD_DECOMP_LEVEL_COUNT;
  __swift_intptr_t decompIdx = _swift_stdlib_getMphIdx(scalar, levelCount,
                                                  _swift_stdlib_nfd_decomp_keys,
                                                  _swift_stdlib_nfd_decomp_ranks,
                                                  _swift_stdlib_nfd_decomp_sizes);

  return _swift_stdlib_nfd_decomp_indices[decompIdx];
#endif
}

SWIFT_RUNTIME_STDLIB_INTERNAL
__swift_uint32_t _swift_stdlib_getComposition(__swift_uint32_t x,
                                            __swift_uint32_t y) {
#if !SWIFT_STDLIB_ENABLE_UNICODE_DATA
  swift::swift_abortDisabledUnicodeSupport();
#else
  auto levelCount = NFC_COMP_LEVEL_COUNT;
  __swift_intptr_t compIdx = _swift_stdlib_getMphIdx(y, levelCount,
                                                  _swift_stdlib_nfc_comp_keys,
                                                  _swift_stdlib_nfc_comp_ranks,
                                                  _swift_stdlib_nfc_comp_sizes);
  auto array = _swift_stdlib_nfc_comp_indices[compIdx];

  // Ensure that the first element in this array is equal to our y scalar.
  auto realY = (array[0] << 11) >> 11;

  if (y != realY) {
    return std::numeric_limits<__swift_uint32_t>::max();
  }

  auto count = array[0] >> 21;

  __swift_uint32_t low = 1;
  __swift_uint32_t high = count - 1;

  while (high >= low) {
    auto idx = low + (high - low) / 2;
  
    auto entry = array[idx];
  
    // Shift the range count out of the scalar.
    auto lower = (entry << 15) >> 15;
  
    bool isNegative = entry >> 31;
    auto rangeCount = (entry << 1) >> 18;
  
    if (isNegative) {
      rangeCount = -rangeCount;
    }
  
    auto composed = lower + rangeCount;
  
    if (x == lower) {
      return composed;
    }
  
    if (x > lower) {
      low = idx + 1;
      continue;
    }
  
    if (x < lower) {
      high = 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 std::numeric_limits<__swift_uint32_t>::max();
#endif
}