diff --git a/all.h b/all.h index c3ab619..ce29b53 100644 --- a/all.h +++ b/all.h @@ -684,6 +684,8 @@ fn u32 stringCountLines(String s); fn u32 stringLineLen(String s, u32 line_number); fn u32 stringLineStartByteOffset(String s, u32 line_number); fn bool stringInsertBytesAt(String* s, str bytes, u32 at); +fn bool stringInsertBytesAtMaybeAlloc(Arena* a, String* s, str bytes, u32 at); +fn u32 stringFindNextCharPosFrom(String s, u32 from, u8 c); ///// OS-wrapped apis void osInit(); diff --git a/string.c b/string.c index 600b8b1..4d801a7 100644 --- a/string.c +++ b/string.c @@ -472,8 +472,10 @@ fn bool stringInsertBytesAt(String* s, str bytes, u32 at) { return false; } for (u32 i = 0; i < len; i++) { - // move the original byte over by `len` - s->bytes[at + i + len] = s->bytes[at + i]; + // shift all the following bytes over by one, starting from the end and working toward `at` + for (u32 ii = s->length; ii > at+i; ii--) { + s->bytes[ii] = s->bytes[ii-1]; + } // copy the new byte in s->bytes[at + i] = bytes[i]; s->length += 1; @@ -481,3 +483,25 @@ fn bool stringInsertBytesAt(String* s, str bytes, u32 at) { return true; } +// will alloc a new string over top of s.bytes if it didnt have enough space +// this is destructive of the pointer +// may cause mem-leak if you arent clearing the arena correctly +fn bool stringInsertBytesAtMaybeAlloc(Arena* a, String* s, str bytes, u32 at) { + bool is_already_enough_space = stringInsertBytesAt(s, bytes, at); + if (!is_already_enough_space) { + ptr old_bytes = s->bytes; + s->bytes = arenaAllocZero(a, s->capacity + 64); + MemoryCopy(s->bytes, old_bytes, s->length); + return stringInsertBytesAt(s, bytes, at); + } + return true; +} + +fn u32 stringFindNextCharPosFrom(String s, u32 from, u8 c) { + for (u32 i = from; i < s.length; i++) { + if (s.bytes[i] == c) { + return i; + } + } + return s.length; +}