Returns the x leftmost characters of a given string. Cases: LEFT("TestString", 10) => "TestString" LEFT("TestString", 3) => "Tes" LEFT("TestString", -3) => "TestStr"
| 2186 | // LEFT("TestString", 3) => "Tes" |
| 2187 | // LEFT("TestString", -3) => "TestStr" |
| 2188 | FORCE_INLINE |
| 2189 | const char* left_utf8_int32(gdv_int64 context, const char* text, gdv_int32 text_len, |
| 2190 | gdv_int32 number, gdv_int32* out_len) { |
| 2191 | // returns the 'number' left most characters of a given text |
| 2192 | if (text_len == 0 || number == 0) { |
| 2193 | *out_len = 0; |
| 2194 | return ""; |
| 2195 | } |
| 2196 | |
| 2197 | int32_t char_count = utf8_length(context, text, text_len); |
| 2198 | |
| 2199 | // char_count is zero if input has invalid utf8 char |
| 2200 | if (char_count == 0) { |
| 2201 | *out_len = 0; |
| 2202 | return ""; |
| 2203 | } |
| 2204 | |
| 2205 | // case where left('abcdef', -6) -> "" and left('abcdef', -7) -> "" |
| 2206 | if (number < 0 && -(number) >= char_count) { |
| 2207 | *out_len = 0; |
| 2208 | return ""; |
| 2209 | } |
| 2210 | |
| 2211 | // iterate over the utf8 string validating each character |
| 2212 | int char_len; |
| 2213 | int current_char_count = 0; |
| 2214 | int byte_index = 0; |
| 2215 | for (int i = 0; i < text_len; i += char_len) { |
| 2216 | char_len = utf8_char_length(text[i]); |
| 2217 | byte_index += char_len; |
| 2218 | ++current_char_count; |
| 2219 | // Define the rules to stop the iteration over the string |
| 2220 | // case where left('abc', 5) -> 'abc' |
| 2221 | if (number > 0 && current_char_count == number) { |
| 2222 | break; |
| 2223 | } |
| 2224 | // case where left('abc', -5) ==> '' |
| 2225 | if (number < 0 && current_char_count == number + char_count) { |
| 2226 | break; |
| 2227 | } |
| 2228 | } |
| 2229 | |
| 2230 | *out_len = byte_index; |
| 2231 | return text; |
| 2232 | } |
| 2233 | |
| 2234 | // Returns the x rightmost characters of a given string. Cases: |
| 2235 | // RIGHT("TestString", 10) => "TestString" |