Returns the x leftmost characters of a given string. Cases: LEFT("TestString", 10) => "TestString" LEFT("TestString", 3) => "Tes" LEFT("TestString", -3) => "TestStr"
| 2243 | // LEFT("TestString", 3) => "Tes" |
| 2244 | // LEFT("TestString", -3) => "TestStr" |
| 2245 | FORCE_INLINE |
| 2246 | const char* left_utf8_int32(gdv_int64 context, const char* text, gdv_int32 text_len, |
| 2247 | gdv_int32 number, gdv_int32* out_len) { |
| 2248 | // returns the 'number' left most characters of a given text |
| 2249 | if (text_len == 0 || number == 0) { |
| 2250 | *out_len = 0; |
| 2251 | return ""; |
| 2252 | } |
| 2253 | |
| 2254 | int32_t char_count = utf8_length(context, text, text_len); |
| 2255 | |
| 2256 | // char_count is zero if input has invalid utf8 char |
| 2257 | if (char_count == 0) { |
| 2258 | *out_len = 0; |
| 2259 | return ""; |
| 2260 | } |
| 2261 | |
| 2262 | // case where left('abcdef', -6) -> "" and left('abcdef', -7) -> "" |
| 2263 | if (number < 0 && -(number) >= char_count) { |
| 2264 | *out_len = 0; |
| 2265 | return ""; |
| 2266 | } |
| 2267 | |
| 2268 | // iterate over the utf8 string validating each character |
| 2269 | int char_len; |
| 2270 | int current_char_count = 0; |
| 2271 | int byte_index = 0; |
| 2272 | for (int i = 0; i < text_len; i += char_len) { |
| 2273 | char_len = utf8_char_length(text[i]); |
| 2274 | byte_index += char_len; |
| 2275 | ++current_char_count; |
| 2276 | // Define the rules to stop the iteration over the string |
| 2277 | // case where left('abc', 5) -> 'abc' |
| 2278 | if (number > 0 && current_char_count == number) { |
| 2279 | break; |
| 2280 | } |
| 2281 | // case where left('abc', -5) ==> '' |
| 2282 | if (number < 0 && current_char_count == number + char_count) { |
| 2283 | break; |
| 2284 | } |
| 2285 | } |
| 2286 | |
| 2287 | *out_len = byte_index; |
| 2288 | return text; |
| 2289 | } |
| 2290 | |
| 2291 | // Returns the x rightmost characters of a given string. Cases: |
| 2292 | // RIGHT("TestString", 10) => "TestString" |