/* $Id: splice.c 710 2006-07-27 19:02:06Z bruce $ */ /* str/splice.c - Insert into the middle of a string. * Copyright (C) 2003,2005 Bruce Guenter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "str.h" /* Insert one string into another */ int str_splice(str* s, unsigned start, unsigned len, const str* r) { return str_spliceb(s, start, len, r->s, r->len); } /* Insert a C string into a string */ int str_splices(str* s, unsigned start, unsigned len, const char* r) { return str_spliceb(s, start, len, r, strlen(r)); } /* Insert a binary block into a string */ int str_spliceb(str* s, unsigned start, unsigned len, const char* r, unsigned rlen) { if (start > s->len || start + len > s->len) return 0; if (rlen != len) { const long diff = rlen - len; if (!str_realloc(s, s->len + diff)) return 0; memmove(s->s + start + rlen, s->s + start + len, s->len - start - len + 1); s->len += diff; } memcpy(s->s + start, r, rlen); return 1; } #ifdef SELFTEST_MAIN #include "selftest.c" MAIN { static str s; str_copyb(&s, "abcde", 5); debugstrfn(str_splices(&s, 6, 0, ""), &s); /* start is too large */ debugstrfn(str_splices(&s, 4, 4, ""), &s); /* len is too large */ debugstrfn(str_splices(&s, 0, 1, "fg"), &s); /* expand the front */ debugstrfn(str_splices(&s, 1, 1, "hi"), &s); /* expand the middle */ debugstrfn(str_splices(&s, 6, 1, "jk"), &s); /* expand the end */ debugstrfn(str_splices(&s, 4, 2, "lm"), &s); /* replace */ debugstrfn(str_splices(&s, 3, 3, "no"), &s); /* contract */ debugstrfn(str_splices(&s, 7, 0, "pqrstuvwxyz"), &s); /* grow string */ } #endif #ifdef SELFTEST_EXP result=0 len=5 size=16 s=abcde result=0 len=5 size=16 s=abcde result=1 len=6 size=16 s=fgbcde result=1 len=7 size=16 s=fhibcde result=1 len=8 size=16 s=fhibcdjk result=1 len=8 size=16 s=fhiblmjk result=1 len=7 size=16 s=fhinojk result=1 len=18 size=32 s=fhinojkpqrstuvwxyz #endif