returns a string in which all occurrences of a specified string in the original string have been replaced by ANOTHER (specified) string. for example: RETURN replace('Well I wish I was in the land of cotton', 'cotton', 'the free') the result is Well I wish I was in the land of the free
| 574 | // for example: RETURN replace('Well I wish I was in the land of cotton', 'cotton', 'the free') |
| 575 | // the result is Well I wish I was in the land of the free |
| 576 | SIValue AR_REPLACE(SIValue *argv, int argc, void *private_data) { |
| 577 | // No string contains null. |
| 578 | if(SIValue_IsNull(argv[0]) || |
| 579 | SIValue_IsNull(argv[1]) || |
| 580 | SIValue_IsNull(argv[2])) return SI_NullVal(); |
| 581 | |
| 582 | // argv[0] is the original string to be manipulated |
| 583 | // argv[1] is the search sub string to be replaced |
| 584 | // argv[2] is the string to be replaced with |
| 585 | const char *str = argv[0].stringval; |
| 586 | const char *old_string = argv[1].stringval; |
| 587 | const char *new_string = argv[2].stringval; |
| 588 | size_t str_len = strlen(str); |
| 589 | size_t old_string_len = strlen(old_string); |
| 590 | size_t new_string_len = strlen(new_string); |
| 591 | |
| 592 | const char *ptr = str; |
| 593 | const char **arr = array_new(const char *, 0); |
| 594 | |
| 595 | // if any parameter is not a valid utf8 string return the original string |
| 596 | if(!str_utf8_validate(old_string) || !str_utf8_validate(new_string) || |
| 597 | !str_utf8_validate(str)) { |
| 598 | return SI_DuplicateStringVal(str); |
| 599 | } |
| 600 | |
| 601 | while(ptr <= str + str_len) { |
| 602 | // find pointer to next substring |
| 603 | ptr = strstr(ptr, old_string); |
| 604 | |
| 605 | // if no substring found, then break from the loop |
| 606 | if(ptr == NULL) break; |
| 607 | |
| 608 | // store ptr for replace use |
| 609 | array_append(arr, ptr); |
| 610 | |
| 611 | // increment our string pointer in case search string is empty move one char |
| 612 | ptr += old_string_len == 0 ? 1 : old_string_len; |
| 613 | } |
| 614 | |
| 615 | int occurrences = array_len(arr); |
| 616 | |
| 617 | // if sub string not found return original string |
| 618 | if(occurrences == 0) { |
| 619 | array_free(arr); |
| 620 | return SI_DuplicateStringVal(str); |
| 621 | } |
| 622 | |
| 623 | // calculate new buffer size |
| 624 | size_t buffer_size = strlen(str) + (occurrences * new_string_len) - (occurrences * old_string_len); |
| 625 | |
| 626 | // allocate buffer |
| 627 | char *buffer = (char*) rm_malloc(sizeof(char) * buffer_size + 1); |
| 628 | |
| 629 | // set pointers to start point |
| 630 | ptr = str; |
| 631 | char *buffer_ptr = buffer; |
| 632 | |
| 633 | // iterate occurrences |
nothing calls this directly
no test coverage detected