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

Function gdv_fn_upper_utf8

cpp/src/gandiva/gdv_string_function_stubs.cc:289–358  ·  view source on GitHub ↗

Convert an utf8 string to its corresponding uppercase string

Source from the content-addressed store, hash-verified

287
288// Convert an utf8 string to its corresponding uppercase string
289GANDIVA_EXPORT
290const char* gdv_fn_upper_utf8(int64_t context, const char* data, int32_t data_len,
291 int32_t* out_len) {
292 if (data_len == 0) {
293 *out_len = 0;
294 return "";
295 }
296
297 // If it is a single-byte character (ASCII), corresponding uppercase is always 1-byte
298 // long; if it is >= 2 bytes long, uppercase can be at most 4 bytes long, so length of
299 // the output can be at most twice the length of the input
300 char* out = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, 2 * data_len));
301 if (out == nullptr) {
302 gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
303 *out_len = 0;
304 return "";
305 }
306
307 int32_t char_len, out_char_len, out_idx = 0;
308 uint32_t char_codepoint;
309
310 for (int32_t i = 0; i < data_len; i += char_len) {
311 char_len = gdv_fn_utf8_char_length(data[i]);
312 // For single byte characters:
313 // If it is a lowercase ASCII character, set the output to its corresponding uppercase
314 // character; else, set the output to the read character
315 if (char_len == 1) {
316 char cur = data[i];
317 // 'A' - 'Z' : 0x41 - 0x5a
318 // 'a' - 'z' : 0x61 - 0x7a
319 if (cur >= 0x61 && cur <= 0x7a) {
320 out[out_idx++] = static_cast<char>(cur - 0x20);
321 } else {
322 out[out_idx++] = cur;
323 }
324 continue;
325 }
326
327 // Control reaches here when we encounter a multibyte character
328 const auto* in_char = (const uint8_t*)(data + i);
329
330 // Decode the multibyte character
331 bool is_valid_utf8_char =
332 arrow::util::UTF8Decode((const uint8_t**)&in_char, &char_codepoint);
333
334 // If it is an invalid utf8 character, UTF8Decode evaluates to false
335 if (!is_valid_utf8_char) {
336 gdv_fn_set_error_for_invalid_utf8(context, data[i]);
337 *out_len = 0;
338 return "";
339 }
340
341 // Convert the encoded codepoint to its uppercase codepoint
342 int32_t upper_codepoint = utf8proc_toupper(char_codepoint);
343
344 // UTF8Encode advances the pointer by the number of bytes present in the uppercase
345 // character
346 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