! \return the substitution result in a str, input must be 0 term * 0 on no match or malloc error * if count is non zero it will be set to the number of matches, or -1 * if error */
| 590 | * if error |
| 591 | */ |
| 592 | str* subst_str(const char *input, struct sip_msg* msg, struct subst_expr* se, |
| 593 | int* count) |
| 594 | { |
| 595 | str* res; |
| 596 | struct replace_lst *lst; |
| 597 | struct replace_lst* l; |
| 598 | int len; |
| 599 | int size; |
| 600 | const char* p; |
| 601 | char* dest; |
| 602 | const char* end; |
| 603 | |
| 604 | |
| 605 | /* compute the len */ |
| 606 | len=strlen(input); |
| 607 | end=input+len; |
| 608 | lst=subst_run(se, input, msg, count); |
| 609 | if (lst==0){ |
| 610 | LM_DBG("no match\n"); |
| 611 | return 0; |
| 612 | } |
| 613 | for (l=lst; l; l=l->next) |
| 614 | len+=(int)(l->rpl.len)-l->size; |
| 615 | res=pkg_malloc(sizeof(str)); |
| 616 | if (res==0){ |
| 617 | LM_ERR("out of pkg memory\n"); |
| 618 | goto error; |
| 619 | } |
| 620 | res->s=pkg_malloc(len+1); /* space for null termination */ |
| 621 | if (res->s==0){ |
| 622 | LM_ERR("out of pkg memory (res->s)\n"); |
| 623 | goto error; |
| 624 | } |
| 625 | res->s[len]=0; |
| 626 | res->len=len; |
| 627 | |
| 628 | /* replace */ |
| 629 | dest=res->s; |
| 630 | p=input; |
| 631 | for(l=lst; l; l=l->next){ |
| 632 | size=l->offset+input-p; |
| 633 | memcpy(dest, p, size); /* copy till offset */ |
| 634 | p+=size + l->size; /* skip l->size bytes */ |
| 635 | dest+=size; |
| 636 | if (l->rpl.len){ |
| 637 | memcpy(dest, l->rpl.s, l->rpl.len); |
| 638 | dest+=l->rpl.len; |
| 639 | } |
| 640 | } |
| 641 | memcpy(dest, p, end-p); |
| 642 | if(lst) replace_lst_free(lst); |
| 643 | return res; |
| 644 | error: |
| 645 | if (lst) replace_lst_free(lst); |
| 646 | if (res){ |
| 647 | if (res->s) pkg_free(res->s); |
| 648 | pkg_free(res); |
| 649 | } |
no test coverage detected