MCPcopy Create free account
hub / github.com/Snapchat/Valdi / utf8DecodeCheck

Function utf8DecodeCheck

valdi_core/src/valdi_core/cpp/Text/UTF16Utils.cpp:84–138  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

82}
83
84static inline OffsetPt utf8DecodeCheck(const char* str, std::string::size_type i) {
85 uint32_t b0;
86 uint32_t b1;
87 uint32_t b2;
88 uint32_t b3;
89
90 b0 = static_cast<unsigned char>(str[i]);
91
92 if (b0 < 0x80) {
93 // 1-byte character
94 return {1, b0};
95 } else if (b0 < 0xC0) {
96 // Unexpected continuation byte
97 return kInvalidPt;
98 } else if (b0 < 0xE0) {
99 // 2-byte character
100 if (((b1 = str[i + 1]) & 0xC0) != 0x80)
101 return kInvalidPt;
102
103 char32_t pt = (b0 & 0x1F) << 6 | (b1 & 0x3F);
104 if (pt < 0x80)
105 return kInvalidPt;
106
107 return {2, pt};
108 } else if (b0 < 0xF0) {
109 // 3-byte character
110 if (((b1 = str[i + 1]) & 0xC0) != 0x80)
111 return kInvalidPt;
112 if (((b2 = str[i + 2]) & 0xC0) != 0x80)
113 return kInvalidPt;
114
115 char32_t pt = (b0 & 0x0F) << 12 | (b1 & 0x3F) << 6 | (b2 & 0x3F);
116 if (pt < 0x800)
117 return kInvalidPt;
118
119 return {3, pt};
120 } else if (b0 < 0xF8) {
121 // 4-byte character
122 if (((b1 = str[i + 1]) & 0xC0) != 0x80)
123 return kInvalidPt;
124 if (((b2 = str[i + 2]) & 0xC0) != 0x80)
125 return kInvalidPt;
126 if (((b3 = str[i + 3]) & 0xC0) != 0x80)
127 return kInvalidPt;
128
129 char32_t pt = (b0 & 0x0F) << 18 | (b1 & 0x3F) << 12 | (b2 & 0x3F) << 6 | (b3 & 0x3F);
130 if (pt < 0x10000 || pt >= 0x110000)
131 return kInvalidPt;
132
133 return {4, pt};
134 } else {
135 // Codepoint out of range
136 return kInvalidPt;
137 }
138}
139
140static inline char32_t utf8Decode(const char* str, std::string::size_type& i) {
141 OffsetPt res = utf8DecodeCheck(str, i);

Callers 1

utf8DecodeFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected