| 1986 | } |
| 1987 | |
| 1988 | FORCE_INLINE |
| 1989 | const char* lpad_utf8_int32_utf8(gdv_int64 context, const char* text, gdv_int32 text_len, |
| 1990 | gdv_int32 return_length, const char* fill_text, |
| 1991 | gdv_int32 fill_text_len, gdv_int32* out_len) { |
| 1992 | // if the text length or the defined return length (number of characters to return) |
| 1993 | // is <=0, then return an empty string. |
| 1994 | return_length = std::min(max_str_length, return_length); |
| 1995 | return_length = std::max(min_str_length, return_length); |
| 1996 | if (text_len == 0 || return_length <= 0) { |
| 1997 | *out_len = 0; |
| 1998 | return ""; |
| 1999 | } |
| 2000 | |
| 2001 | // count the number of utf8 characters on text, ignoring invalid bytes |
| 2002 | int actual_text_len = utf8_length_ignore_invalid(text, text_len); |
| 2003 | |
| 2004 | if (return_length == actual_text_len || |
| 2005 | (return_length > actual_text_len && fill_text_len == 0)) { |
| 2006 | // case where the return length is same as the text's length, or if it need to |
| 2007 | // fill into text but "fill_text" is empty, then return text directly. |
| 2008 | *out_len = text_len; |
| 2009 | return text; |
| 2010 | } |
| 2011 | if (return_length < actual_text_len) { |
| 2012 | // case where it truncates the result on return length. |
| 2013 | *out_len = utf8_byte_pos(context, text, text_len, return_length); |
| 2014 | return text; |
| 2015 | } |
| 2016 | |
| 2017 | gdv_int32 chars_to_pad = return_length - actual_text_len; |
| 2018 | |
| 2019 | // FAST PATH: Single-byte fill (most common - space padding) |
| 2020 | if (fill_text_len == 1) { |
| 2021 | gdv_int32 out_len_bytes = chars_to_pad + text_len; |
| 2022 | gdv_binary ret = |
| 2023 | reinterpret_cast<gdv_binary>(gdv_fn_context_arena_malloc(context, out_len_bytes)); |
| 2024 | if (ret == nullptr) { |
| 2025 | gdv_fn_context_set_error_msg(context, |
| 2026 | "Could not allocate memory for output string"); |
| 2027 | *out_len = 0; |
| 2028 | return ""; |
| 2029 | } |
| 2030 | memset(ret, fill_text[0], chars_to_pad); |
| 2031 | memcpy(ret + chars_to_pad, text, text_len); |
| 2032 | *out_len = out_len_bytes; |
| 2033 | return ret; |
| 2034 | } |
| 2035 | |
| 2036 | // GENERAL PATH: Multi-byte fill - use evaluate_return_char_length for buffer size |
| 2037 | gdv_int32 return_char_length = evaluate_return_char_length( |
| 2038 | text_len, actual_text_len, return_length, fill_text, fill_text_len); |
| 2039 | gdv_binary ret = reinterpret_cast<gdv_binary>( |
| 2040 | gdv_fn_context_arena_malloc(context, return_char_length)); |
| 2041 | if (ret == nullptr) { |
| 2042 | gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string"); |
| 2043 | *out_len = 0; |
| 2044 | return ""; |
| 2045 | } |