Returns the x rightmost characters of a given string. Cases: RIGHT("TestString", 10) => "TestString" RIGHT("TestString", 3) => "ing" RIGHT("TestString", -3) => "tString"
| 2293 | // RIGHT("TestString", 3) => "ing" |
| 2294 | // RIGHT("TestString", -3) => "tString" |
| 2295 | FORCE_INLINE |
| 2296 | const char* right_utf8_int32(gdv_int64 context, const char* text, gdv_int32 text_len, |
| 2297 | gdv_int32 number, gdv_int32* out_len) { |
| 2298 | // returns the 'number' left most characters of a given text |
| 2299 | if (text_len == 0 || number == 0) { |
| 2300 | *out_len = 0; |
| 2301 | return ""; |
| 2302 | } |
| 2303 | |
| 2304 | // initially counts the number of utf8 characters in the defined text |
| 2305 | int32_t char_count = utf8_length(context, text, text_len); |
| 2306 | |
| 2307 | // char_count is zero if input has invalid utf8 char |
| 2308 | if (char_count == 0) { |
| 2309 | *out_len = 0; |
| 2310 | return ""; |
| 2311 | } |
| 2312 | |
| 2313 | // case where right('abcdef', -6) -> "" and right('abcdef', -7) -> "" |
| 2314 | if (number < 0 && -(number) >= char_count) { |
| 2315 | *out_len = 0; |
| 2316 | return ""; |
| 2317 | } |
| 2318 | |
| 2319 | int32_t start_char_pos; // the char result start position (inclusive) |
| 2320 | |
| 2321 | if (number > 0) { |
| 2322 | // case where right('abc', 5) ==> 'abc' start_char_pos=1. |
| 2323 | start_char_pos = (char_count > number) ? char_count - number : 0; |
| 2324 | } else { |
| 2325 | start_char_pos = number * -1; |
| 2326 | } |
| 2327 | |
| 2328 | // calculate the start byte position |
| 2329 | int32_t start_byte_pos = utf8_byte_pos(context, text, text_len, start_char_pos); |
| 2330 | |
| 2331 | // calculate output length |
| 2332 | *out_len = (text_len - start_byte_pos); |
| 2333 | return text + start_byte_pos; |
| 2334 | } |
| 2335 | |
| 2336 | FORCE_INLINE |
| 2337 | const char* binary_string(gdv_int64 context, const char* text, gdv_int32 text_len, |