MCPcopy Create free account
hub / github.com/apache/arrow / gdv_fn_lower_utf8

Function gdv_fn_lower_utf8

cpp/src/gandiva/gdv_string_function_stubs.cc:217–286  ·  view source on GitHub ↗

Convert an utf8 string to its corresponding lowercase string

Source from the content-addressed store, hash-verified

215
216// Convert an utf8 string to its corresponding lowercase string
217GANDIVA_EXPORT
218const char* gdv_fn_lower_utf8(int64_t context, const char* data, int32_t data_len,
219 int32_t* out_len) {
220 if (data_len == 0) {
221 *out_len = 0;
222 return "";
223 }
224
225 // If it is a single-byte character (ASCII), corresponding lowercase is always 1-byte
226 // long; if it is >= 2 bytes long, lowercase can be at most 4 bytes long, so length of
227 // the output can be at most twice the length of the input
228 char* out = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, 2 * data_len));
229 if (out == nullptr) {
230 gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
231 *out_len = 0;
232 return "";
233 }
234
235 int32_t char_len, out_char_len, out_idx = 0;
236 uint32_t char_codepoint;
237
238 for (int32_t i = 0; i < data_len; i += char_len) {
239 char_len = gdv_fn_utf8_char_length(data[i]);
240 // For single byte characters:
241 // If it is an uppercase ASCII character, set the output to its corresponding
242 // lowercase character; else, set the output to the read character
243 if (char_len == 1) {
244 char cur = data[i];
245 // 'A' - 'Z' : 0x41 - 0x5a
246 // 'a' - 'z' : 0x61 - 0x7a
247 if (cur >= 0x41 && cur <= 0x5a) {
248 out[out_idx++] = static_cast<char>(cur + 0x20);
249 } else {
250 out[out_idx++] = cur;
251 }
252 continue;
253 }
254
255 // Control reaches here when we encounter a multibyte character
256 const auto* in_char = (const uint8_t*)(data + i);
257
258 // Decode the multibyte character
259 bool is_valid_utf8_char =
260 arrow::util::UTF8Decode((const uint8_t**)&in_char, &char_codepoint);
261
262 // If it is an invalid utf8 character, UTF8Decode evaluates to false
263 if (!is_valid_utf8_char) {
264 gdv_fn_set_error_for_invalid_utf8(context, data[i]);
265 *out_len = 0;
266 return "";
267 }
268
269 // Convert the encoded codepoint to its lowercase codepoint
270 int32_t lower_codepoint = utf8proc_tolower(char_codepoint);
271
272 // UTF8Encode advances the pointer by the number of bytes present in the lowercase
273 // character
274 auto* out_char = (uint8_t*)(out + out_idx);

Callers 1

TESTFunction · 0.85

Calls 6

gdv_fn_utf8_char_lengthFunction · 0.85
UTF8DecodeFunction · 0.85
UTF8EncodeFunction · 0.85

Tested by 1

TESTFunction · 0.68