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

Function gdv_fn_initcap_utf8

cpp/src/gandiva/gdv_string_function_stubs.cc:515–612  ·  view source on GitHub ↗

For a given text, initialize the first letter after a word-separator and lowercase the others e.g: - "IT is a tEXt str" -> "It Is A Text Str"

Source from the content-addressed store, hash-verified

513// the others e.g:
514// - "IT is a tEXt str" -> "It Is A Text Str"
515GANDIVA_EXPORT
516const char* gdv_fn_initcap_utf8(int64_t context, const char* data, int32_t data_len,
517 int32_t* out_len) {
518 if (data_len == 0) {
519 *out_len = data_len;
520 return "";
521 }
522
523 int32_t alloc_length = 0;
524 if (ARROW_PREDICT_FALSE(!is_datalen_valid(context, data_len, &alloc_length, out_len))) {
525 return "";
526 }
527
528 // If it is a single-byte character (ASCII), corresponding uppercase is always 1-byte
529 // long; if it is >= 2 bytes long, uppercase can be at most 4 bytes long, so length of
530 // the output can be at most twice the length of the input
531 char* out = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, alloc_length));
532 if (out == nullptr) {
533 gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");
534 *out_len = 0;
535 return "";
536 }
537
538 int32_t char_len = 0;
539 int32_t out_char_len = 0;
540 int32_t out_idx = 0;
541 uint32_t char_codepoint;
542
543 // Any character is considered as space, except if it is alphanumeric
544 bool last_char_was_space = true;
545
546 for (int32_t i = 0; i < data_len; i += char_len) {
547 // An optimization for single byte characters:
548 if (static_cast<signed char>(data[i]) >= 0) { // 1-byte char (0x00 ~ 0x7F)
549 char_len = 1;
550 char cur = data[i];
551
552 if (cur >= 0x61 && cur <= 0x7a && last_char_was_space) {
553 // Check if the character is the first one of the word and it is
554 // lowercase -> 'a' - 'z' : 0x61 - 0x7a.
555 // Then turn it into uppercase -> 'A' - 'Z' : 0x41 - 0x5a
556 out[out_idx++] = static_cast<char>(cur - 0x20);
557 last_char_was_space = false;
558 } else if (cur >= 0x41 && cur <= 0x5a && !last_char_was_space) {
559 out[out_idx++] = static_cast<char>(cur + 0x20);
560 } else {
561 // Check if the ASCII character is not an alphanumeric character:
562 // '0' - '9': 0x30 - 0x39
563 // 'a' - 'z' : 0x61 - 0x7a
564 // 'A' - 'Z' : 0x41 - 0x5a
565 last_char_was_space = (cur < 0x30) || (cur > 0x39 && cur < 0x41) ||
566 (cur > 0x5a && cur < 0x61) || (cur > 0x7a);
567 out[out_idx++] = cur;
568 }
569 continue;
570 }
571
572 char_len = gdv_fn_utf8_char_length(data[i]);

Callers 1

TESTFunction · 0.85

Calls 8

is_datalen_validFunction · 0.85
gdv_fn_utf8_char_lengthFunction · 0.85
UTF8DecodeFunction · 0.85
UTF8EncodeFunction · 0.85

Tested by 1

TESTFunction · 0.68