From ad19eb8d8d8e5272365a5808ad09c34defd88a7e Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 12 Nov 2015 14:47:14 +0100 Subject: [PATCH 1/6] Remove obsolete CharBuf ctors and methods Also change CB_Grow return type. --- runtime/core/Clownfish/CharBuf.c | 100 ++-------------------- runtime/core/Clownfish/CharBuf.cfh | 47 +--------- runtime/core/Clownfish/Err.c | 3 +- runtime/core/Clownfish/Test/TestCharBuf.c | 79 ++--------------- 4 files changed, 17 insertions(+), 212 deletions(-) diff --git a/runtime/core/Clownfish/CharBuf.c b/runtime/core/Clownfish/CharBuf.c index 6e549101..bd388b88 100644 --- a/runtime/core/Clownfish/CharBuf.c +++ b/runtime/core/Clownfish/CharBuf.c @@ -68,60 +68,18 @@ CB_init(CharBuf *self, size_t size) { return self; } -CharBuf* -CB_new_from_str(String *string) { - return CB_new_from_trusted_utf8(string->ptr, string->size); -} - -CharBuf* -CB_new_from_utf8(const char *ptr, size_t size) { - if (!StrHelp_utf8_valid(ptr, size)) { - DIE_INVALID_UTF8(ptr, size); - } - return CB_new_from_trusted_utf8(ptr, size); -} - -CharBuf* -CB_new_from_trusted_utf8(const char *ptr, size_t size) { - CharBuf *self = (CharBuf*)Class_Make_Obj(CHARBUF); - - // Derive. - self->ptr = (char*)MALLOCATE(size + 1); - - // Copy. - memcpy(self->ptr, ptr, size); - - // Assign. - self->size = size; - self->cap = size + 1; - self->ptr[size] = '\0'; // Null terminate. - - return self; -} - -CharBuf* -CB_newf(const char *pattern, ...) { - CharBuf *self = CB_new(strlen(pattern)); - va_list args; - va_start(args, pattern); - CB_VCatF(self, pattern, args); - va_end(args); - return self; -} - void CB_Destroy_IMP(CharBuf *self) { FREEMEM(self->ptr); SUPER_DESTROY(self, CHARBUF); } -char* +void CB_Grow_IMP(CharBuf *self, size_t size) { if (size >= self->cap) { self->cap = size + 1; self->ptr = (char*)REALLOCATE(self->ptr, self->cap); } - return self->ptr; } static void @@ -318,44 +276,14 @@ CB_Cat_Char_IMP(CharBuf *self, int32_t code_point) { CharBuf* CB_Clone_IMP(CharBuf *self) { - return CB_new_from_trusted_utf8(self->ptr, self->size); -} + size_t size = self->size; + CharBuf *clone = CB_new(size); -static CFISH_INLINE void -SI_mimic_utf8(CharBuf *self, const char* ptr, size_t size) { - if (size >= self->cap) { CB_Grow(self, size); } - memmove(self->ptr, ptr, size); - self->size = size; - self->ptr[size] = '\0'; -} + clone->size = size; + memcpy(clone->ptr, self->ptr, size); + clone->ptr[size] = '\0'; -void -CB_Mimic_Utf8_IMP(CharBuf *self, const char* ptr, size_t size) { - if (!StrHelp_utf8_valid(ptr, size)) { - DIE_INVALID_UTF8(ptr, size); - } - SI_mimic_utf8(self, ptr, size); -} - -void -CB_Mimic_IMP(CharBuf *self, Obj *other) { - const char *ptr; - size_t size; - if (Obj_is_a(other, CHARBUF)) { - CharBuf *twin = (CharBuf*)other; - ptr = twin->ptr; - size = twin->size; - } - else if (Obj_is_a(other, STRING)) { - String *twin = (String*)other; - ptr = twin->ptr; - size = twin->size; - } - else { - THROW(ERR, "CharBuf can't mimic %o", Obj_get_class_name(other)); - return; // unreachable - } - SI_mimic_utf8(self, ptr, size); + return clone; } static CFISH_INLINE void @@ -393,23 +321,9 @@ CB_Clear_IMP(CharBuf *self) { self->size = 0; } -void -CB_Set_Size_IMP(CharBuf *self, size_t size) { - if (size >= self->cap) { - THROW(ERR, "Can't set size of CharBuf beyond capacity"); - return; // unreachable - } - self->size = size; -} - size_t CB_Get_Size_IMP(CharBuf *self) { return self->size; } -char* -CB_Get_Ptr8_IMP(CharBuf *self) { - return self->ptr; -} - diff --git a/runtime/core/Clownfish/CharBuf.cfh b/runtime/core/Clownfish/CharBuf.cfh index 0112ae80..7714443f 100644 --- a/runtime/core/Clownfish/CharBuf.cfh +++ b/runtime/core/Clownfish/CharBuf.cfh @@ -33,38 +33,6 @@ final class Clownfish::CharBuf nickname CB inert CharBuf* init(CharBuf *self, size_t size); - /** Return a new CharBuf which holds a copy of the passed-in String. - */ - inert incremented CharBuf* - new_from_str(String *string); - - /** Return a new CharBuf which holds a copy of the passed-in string. - * Check for UTF-8 validity. - */ - inert incremented CharBuf* - new_from_utf8(const char *utf8, size_t size); - - /** Return a new CharBuf which holds a copy of the passed-in string. No - * validity checking is performed. - */ - inert incremented CharBuf* - new_from_trusted_utf8(const char *utf8, size_t size); - - /** Return a pointer to a new CharBuf which contains formatted data - * expanded according to CB_VCatF. - * - * Note: a user-supplied `pattern` string is a security hole - * and must not be allowed. - */ - inert incremented CharBuf* - newf(const char *pattern, ...); - - public void - Mimic(CharBuf *self, Obj *other); - - void - Mimic_Utf8(CharBuf *self, const char *ptr, size_t size); - /** Concatenate the passed-in string onto the end of the CharBuf. */ void @@ -111,10 +79,8 @@ final class Clownfish::CharBuf nickname CB /** Assign more memory to the CharBuf, if it doesn't already have enough * room to hold a string of `size` bytes. Cannot shrink the * allocation. - * - * @return a pointer to the raw buffer. */ - char* + void Grow(CharBuf *self, size_t size); /** Clear the CharBuf. @@ -122,22 +88,11 @@ final class Clownfish::CharBuf nickname CB void Clear(CharBuf *self); - /** Set the CharBuf's `size` attribute. - */ - void - Set_Size(CharBuf *self, size_t size); - /** Get the CharBuf's `size` attribute. */ size_t Get_Size(CharBuf *self); - /** Return the internal backing array for the CharBuf if its internal - * encoding is UTF-8. If it is not encoded as UTF-8 throw an exception. - */ - char* - Get_Ptr8(CharBuf *self); - public incremented CharBuf* Clone(CharBuf *self); diff --git a/runtime/core/Clownfish/Err.c b/runtime/core/Clownfish/Err.c index 8463e0d7..dd398e75 100644 --- a/runtime/core/Clownfish/Err.c +++ b/runtime/core/Clownfish/Err.c @@ -154,7 +154,8 @@ Err_Get_Mess_IMP(Err *self) { void Err_Add_Frame_IMP(Err *self, const char *file, int line, const char *func) { - CharBuf *buf = CB_new_from_str(self->mess); + CharBuf *buf = CB_new(0); + CB_Cat(buf, self->mess); if (!Str_Ends_With_Utf8(self->mess, "\n", 1)) { CB_Cat_Char(buf, '\n'); diff --git a/runtime/core/Clownfish/Test/TestCharBuf.c b/runtime/core/Clownfish/Test/TestCharBuf.c index 5763e99a..744c4f4f 100644 --- a/runtime/core/Clownfish/Test/TestCharBuf.c +++ b/runtime/core/Clownfish/Test/TestCharBuf.c @@ -42,7 +42,9 @@ TestCB_new() { static CharBuf* S_get_cb(const char *string) { - return CB_new_from_utf8(string, strlen(string)); + CharBuf *cb = CB_new(0); + CB_Cat_Utf8(cb, string, strlen(string)); + return cb; } static String* @@ -58,25 +60,6 @@ S_cb_equals(CharBuf *cb, String *other) { return retval; } -static void -test_new(TestBatchRunner *runner) { - { - String *str = Str_newf("CharBuf from String"); - CharBuf *cb = CB_new_from_str(str); - TEST_TRUE(runner, S_cb_equals(cb, str), "CB_new_from_str"); - DECREF(str); - DECREF(cb); - } - - { - CharBuf *cb = CB_newf("%i32 %s", 99, "Luftballons"); - String *wanted = Str_newf("99 Luftballons"); - TEST_TRUE(runner, S_cb_equals(cb, wanted), "CB_newf"); - DECREF(cb); - DECREF(wanted); - } -} - static void test_Cat(TestBatchRunner *runner) { String *wanted = Str_newf("a%s", smiley); @@ -105,62 +88,16 @@ test_Cat(TestBatchRunner *runner) { } static void -test_Mimic_and_Clone(TestBatchRunner *runner) { +test_Clone(TestBatchRunner *runner) { String *wanted = S_get_str("foo"); CharBuf *wanted_cb = S_get_cb("foo"); - CharBuf *got = S_get_cb("bar"); - - CB_Mimic(got, (Obj*)wanted); - TEST_TRUE(runner, S_cb_equals(got, wanted), "Mimic String"); - DECREF(got); - - got = S_get_cb("bar"); - CB_Mimic(got, (Obj*)wanted_cb); - TEST_TRUE(runner, S_cb_equals(got, wanted), "Mimic CharBuf"); - DECREF(got); - - got = S_get_cb("bar"); - CB_Mimic_Utf8(got, "foo", 3); - TEST_TRUE(runner, S_cb_equals(got, wanted), "Mimic_Utf8"); - DECREF(got); - - got = CB_Clone(wanted_cb); + CharBuf *got = CB_Clone(wanted_cb); TEST_TRUE(runner, S_cb_equals(got, wanted), "Clone"); DECREF(got); - DECREF(wanted); DECREF(wanted_cb); } -static void -test_Get_Ptr8(TestBatchRunner *runner) { - CharBuf *cb = CB_new(64); - - char *ptr8 = CB_Get_Ptr8(cb); - strcpy(ptr8, "0123456789"); - CB_Set_Size(cb, 10); - - TEST_INT_EQ(runner, CB_Get_Size(cb), 10, "Set_Size/Get_Size"); - - String *wanted = S_get_str("0123456789"); - TEST_TRUE(runner, S_cb_equals(cb, wanted), "Get_Ptr8"); - - DECREF(cb); - DECREF(wanted); -} - -/* -static void -test_Truncate(TestBatchRunner *runner) { - String *wanted = Str_newf("a%s", smiley); - CharBuf *got = CB_newf("a%s%sb%sc", smiley, smiley, smiley); - CB_Truncate(got, 2); - TEST_TRUE(runner, S_cb_equals(got, wanted), "Truncate"); - DECREF(wanted); - DECREF(got); -} -*/ - static void test_vcatf_percent(TestBatchRunner *runner) { String *wanted = S_get_str("foo % bar"); @@ -336,8 +273,7 @@ test_Clear(TestBatchRunner *runner) { void TestCB_Run_IMP(TestCharBuf *self, TestBatchRunner *runner) { - TestBatchRunner_Plan(runner, (TestBatch*)self, 27); - test_new(runner); + TestBatchRunner_Plan(runner, (TestBatch*)self, 20); test_vcatf_percent(runner); test_vcatf_s(runner); test_vcatf_null_string(runner); @@ -353,8 +289,7 @@ TestCB_Run_IMP(TestCharBuf *self, TestBatchRunner *runner) { test_vcatf_f64(runner); test_vcatf_x32(runner); test_Cat(runner); - test_Mimic_and_Clone(runner); - test_Get_Ptr8(runner); + test_Clone(runner); test_Clear(runner); } From a86123544460abf33637d3ed308995ef1c76b8bf Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 12 Nov 2015 14:51:30 +0100 Subject: [PATCH 2/6] Make CharBuf API public --- runtime/core/Clownfish/CharBuf.cfh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/runtime/core/Clownfish/CharBuf.cfh b/runtime/core/Clownfish/CharBuf.cfh index 7714443f..c007cff8 100644 --- a/runtime/core/Clownfish/CharBuf.cfh +++ b/runtime/core/Clownfish/CharBuf.cfh @@ -20,34 +20,34 @@ parcel Clownfish; * Growable buffer holding Unicode characters. */ -final class Clownfish::CharBuf nickname CB +public final class Clownfish::CharBuf nickname CB inherits Clownfish::Obj { char *ptr; size_t size; size_t cap; /* allocated bytes, including terminating null */ - inert incremented CharBuf* + public inert incremented CharBuf* new(size_t size); - inert CharBuf* + public inert CharBuf* init(CharBuf *self, size_t size); /** Concatenate the passed-in string onto the end of the CharBuf. */ - void + public void Cat_Utf8(CharBuf *self, const char *ptr, size_t size); /** Concatenate the supplied text onto the end of the CharBuf. Don't * check for UTF-8 validity. */ - void + public void Cat_Trusted_Utf8(CharBuf *self, const char *ptr, size_t size); /** Concatenate the contents of `string` onto the end of the * caller. */ - void + public void Cat(CharBuf *self, String *string); /** Concatenate formatted arguments. Similar to the printf family, but @@ -62,35 +62,35 @@ final class Clownfish::CharBuf nickname CB * Note that all Clownfish Objects, including CharBufs, are printed via * %o (which invokes [](Obj.To_String)). */ - void + public void VCatF(CharBuf *self, const char *pattern, va_list args); /** Invokes CB_VCatF to concatenate formatted arguments. Note that this * is only a function and not a method. */ - inert void + public inert void catf(CharBuf *self, const char *pattern, ...); /** Concatenate one Unicode character onto the end of the CharBuf. */ - void + public void Cat_Char(CharBuf *self, int32_t code_point); /** Assign more memory to the CharBuf, if it doesn't already have enough * room to hold a string of `size` bytes. Cannot shrink the * allocation. */ - void + public void Grow(CharBuf *self, size_t size); /** Clear the CharBuf. */ - void + public void Clear(CharBuf *self); /** Get the CharBuf's `size` attribute. */ - size_t + public size_t Get_Size(CharBuf *self); public incremented CharBuf* From 641250dd1b067c291a5d794184298dc74eb5856c Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 12 Nov 2015 15:05:51 +0100 Subject: [PATCH 3/6] Cease null-terminating internal CharBuf buffer The internal buffer is inaccessible now. --- runtime/core/Clownfish/CharBuf.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/runtime/core/Clownfish/CharBuf.c b/runtime/core/Clownfish/CharBuf.c index bd388b88..0f1b7c33 100644 --- a/runtime/core/Clownfish/CharBuf.c +++ b/runtime/core/Clownfish/CharBuf.c @@ -56,14 +56,11 @@ CB_new(size_t size) { CharBuf* CB_init(CharBuf *self, size_t size) { // Derive. - self->ptr = (char*)MALLOCATE(size + 1); - - // Init. - *self->ptr = '\0'; // Empty string. + self->ptr = (char*)MALLOCATE(size); // Assign. self->size = 0; - self->cap = size + 1; + self->cap = size; return self; } @@ -76,9 +73,9 @@ CB_Destroy_IMP(CharBuf *self) { void CB_Grow_IMP(CharBuf *self, size_t size) { - if (size >= self->cap) { - self->cap = size + 1; - self->ptr = (char*)REALLOCATE(self->ptr, self->cap); + if (size > self->cap) { + self->cap = size; + self->ptr = (char*)REALLOCATE(self->ptr, size); } } @@ -264,14 +261,13 @@ CB_Yield_String_IMP(CharBuf *self) { void CB_Cat_Char_IMP(CharBuf *self, int32_t code_point) { const size_t MAX_UTF8_BYTES = 4; - if (self->size + MAX_UTF8_BYTES >= self->cap) { + if (self->size + MAX_UTF8_BYTES > self->cap) { CB_Grow(self, Memory_oversize(self->size + MAX_UTF8_BYTES, sizeof(char))); } char *end = self->ptr + self->size; size_t count = StrHelp_encode_utf8_char(code_point, (uint8_t*)end); self->size += count; - *(end + count) = '\0'; } CharBuf* @@ -281,7 +277,6 @@ CB_Clone_IMP(CharBuf *self) { clone->size = size; memcpy(clone->ptr, self->ptr, size); - clone->ptr[size] = '\0'; return clone; } @@ -289,13 +284,12 @@ CB_Clone_IMP(CharBuf *self) { static CFISH_INLINE void SI_cat_utf8(CharBuf *self, const char* ptr, size_t size) { const size_t new_size = self->size + size; - if (new_size >= self->cap) { + if (new_size > self->cap) { size_t amount = Memory_oversize(new_size, sizeof(char)); CB_Grow(self, amount); } memcpy(self->ptr + self->size, ptr, size); self->size = new_size; - self->ptr[new_size] = '\0'; } void From 6e1d5fd1a687eae61dc0609806c5269ba1e045fb Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 12 Nov 2015 15:35:33 +0100 Subject: [PATCH 4/6] Rework oversizing of CharBufs Don't call Memory_oversize, but oversize by custom amount of 25%. Check for integer overflow. This should only matter on exotic platforms, but it doesn't cost much. --- runtime/core/Clownfish/CharBuf.c | 69 ++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/runtime/core/Clownfish/CharBuf.c b/runtime/core/Clownfish/CharBuf.c index 0f1b7c33..fa7a2b3a 100644 --- a/runtime/core/Clownfish/CharBuf.c +++ b/runtime/core/Clownfish/CharBuf.c @@ -33,6 +33,22 @@ #include "Clownfish/Util/StringHelper.h" #include "Clownfish/Class.h" +// Ensure that the CharBuf's capacity is at least (size + extra). +// If the buffer must be grown, oversize the allocation. +static CFISH_INLINE void +SI_add_grow_and_oversize(CharBuf *self, size_t size, size_t extra); + +// Compilers tend to inline this function although this is the unlikely +// slow path. If we ever add cross-platform support for the noinline +// attribute, it should be marked as such to reduce code size. +static void +S_grow_and_oversize(CharBuf *self, size_t min_size); + +// Not inlining the THROW macro reduces code size and complexity of +// SI_add_grow_and_oversize. +static void +S_overflow_error(); + // Helper function for throwing invalid UTF-8 error. Since THROW uses // a String internally, calling THROW with invalid UTF-8 would create an // infinite loop -- so we fwrite some of the bogus text to stderr and @@ -261,11 +277,9 @@ CB_Yield_String_IMP(CharBuf *self) { void CB_Cat_Char_IMP(CharBuf *self, int32_t code_point) { const size_t MAX_UTF8_BYTES = 4; - if (self->size + MAX_UTF8_BYTES > self->cap) { - CB_Grow(self, Memory_oversize(self->size + MAX_UTF8_BYTES, - sizeof(char))); - } - char *end = self->ptr + self->size; + size_t old_size = self->size; + SI_add_grow_and_oversize(self, old_size, MAX_UTF8_BYTES); + char *end = self->ptr + old_size; size_t count = StrHelp_encode_utf8_char(code_point, (uint8_t*)end); self->size += count; } @@ -283,13 +297,10 @@ CB_Clone_IMP(CharBuf *self) { static CFISH_INLINE void SI_cat_utf8(CharBuf *self, const char* ptr, size_t size) { - const size_t new_size = self->size + size; - if (new_size > self->cap) { - size_t amount = Memory_oversize(new_size, sizeof(char)); - CB_Grow(self, amount); - } - memcpy(self->ptr + self->size, ptr, size); - self->size = new_size; + size_t old_size = self->size; + SI_add_grow_and_oversize(self, old_size, size); + memcpy(self->ptr + old_size, ptr, size); + self->size = old_size + size; } void @@ -320,4 +331,38 @@ CB_Get_Size_IMP(CharBuf *self) { return self->size; } +static CFISH_INLINE void +SI_add_grow_and_oversize(CharBuf *self, size_t size, size_t extra) { + size_t min_size = size + extra; + if (min_size < size) { + S_overflow_error(); + return; + } + + if (min_size > self->cap) { + S_grow_and_oversize(self, min_size); + } +} + +static void +S_grow_and_oversize(CharBuf *self, size_t min_size) { + // Oversize by 25%, but at least eight bytes. + size_t extra = min_size / 4; + // Round up to next multiple of eight. + extra = (extra + 7) & ~7; + + size_t capacity = min_size + extra; + if (capacity < min_size) { + capacity = SIZE_MAX; + } + + self->cap = capacity; + self->ptr = (char*)REALLOCATE(self->ptr, capacity); +} + +static void +S_overflow_error() { + THROW(ERR, "CharBuf buffer overflow"); +} + From 5477135819d6f37bc8052f2450a4dfcd2acc2d6f Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 12 Nov 2015 16:03:33 +0100 Subject: [PATCH 5/6] Non-inline helper to append to CharBufs Reduces code size of CB_VCatF and makes it a little faster. --- runtime/core/Clownfish/CharBuf.c | 49 ++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/runtime/core/Clownfish/CharBuf.c b/runtime/core/Clownfish/CharBuf.c index fa7a2b3a..53541c22 100644 --- a/runtime/core/Clownfish/CharBuf.c +++ b/runtime/core/Clownfish/CharBuf.c @@ -33,6 +33,14 @@ #include "Clownfish/Util/StringHelper.h" #include "Clownfish/Class.h" +// Append trusted UTF-8 to the CharBuf. +static void +S_cat_utf8(CharBuf *self, const char* ptr, size_t size); + +// Inline version of S_cat_utf8. +static CFISH_INLINE void +SI_cat_utf8(CharBuf *self, const char* ptr, size_t size); + // Ensure that the CharBuf's capacity is at least (size + extra). // If the buffer must be grown, oversize the allocation. static CFISH_INLINE void @@ -136,7 +144,7 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list args) { while (slice_end < pattern_end && *slice_end != '%') { slice_end++; } if (pattern != slice_end) { size_t size = slice_end - pattern; - CB_Cat_Trusted_Utf8(self, pattern, size); + S_cat_utf8(self, pattern, size); pattern = slice_end; } @@ -145,13 +153,13 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list args) { switch (*pattern) { case '%': { - CB_Cat_Trusted_Utf8(self, "%", 1); + S_cat_utf8(self, "%", 1); } break; case 'o': { Obj *obj = va_arg(args, Obj*); if (!obj) { - CB_Cat_Trusted_Utf8(self, "[NULL]", 6); + S_cat_utf8(self, "[NULL]", 6); } else if (Obj_is_a(obj, STRING)) { CB_Cat(self, (String*)obj); @@ -182,7 +190,7 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list args) { S_die_invalid_pattern(pattern_start); } size = sprintf(buf, "%" PRId64, val); - CB_Cat_Trusted_Utf8(self, buf, size); + S_cat_utf8(self, buf, size); } break; case 'u': { @@ -204,7 +212,7 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list args) { S_die_invalid_pattern(pattern_start); } size = sprintf(buf, "%" PRIu64, val); - CB_Cat_Trusted_Utf8(self, buf, size); + S_cat_utf8(self, buf, size); } break; case 'f': { @@ -212,7 +220,7 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list args) { double num = va_arg(args, double); char bigbuf[512]; size_t size = sprintf(bigbuf, "%g", num); - CB_Cat_Trusted_Utf8(self, bigbuf, size); + S_cat_utf8(self, bigbuf, size); pattern += 2; } else { @@ -224,7 +232,7 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list args) { if (pattern[1] == '3' && pattern[2] == '2') { unsigned long val = va_arg(args, uint32_t); size_t size = sprintf(buf, "%.8lx", val); - CB_Cat_Trusted_Utf8(self, buf, size); + S_cat_utf8(self, buf, size); pattern += 2; } else { @@ -235,15 +243,15 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list args) { case 's': { char *string = va_arg(args, char*); if (string == NULL) { - CB_Cat_Trusted_Utf8(self, "[NULL]", 6); + S_cat_utf8(self, "[NULL]", 6); } else { size_t size = strlen(string); if (StrHelp_utf8_valid(string, size)) { - CB_Cat_Trusted_Utf8(self, string, size); + S_cat_utf8(self, string, size); } else { - CB_Cat_Trusted_Utf8(self, "[INVALID UTF8]", 14); + S_cat_utf8(self, "[INVALID UTF8]", 14); } } } @@ -295,14 +303,6 @@ CB_Clone_IMP(CharBuf *self) { return clone; } -static CFISH_INLINE void -SI_cat_utf8(CharBuf *self, const char* ptr, size_t size) { - size_t old_size = self->size; - SI_add_grow_and_oversize(self, old_size, size); - memcpy(self->ptr + old_size, ptr, size); - self->size = old_size + size; -} - void CB_Cat_Utf8_IMP(CharBuf *self, const char* ptr, size_t size) { if (!StrHelp_utf8_valid(ptr, size)) { @@ -331,6 +331,19 @@ CB_Get_Size_IMP(CharBuf *self) { return self->size; } +static void +S_cat_utf8(CharBuf *self, const char* ptr, size_t size) { + SI_cat_utf8(self, ptr, size); +} + +static CFISH_INLINE void +SI_cat_utf8(CharBuf *self, const char* ptr, size_t size) { + size_t old_size = self->size; + SI_add_grow_and_oversize(self, old_size, size); + memcpy(self->ptr + old_size, ptr, size); + self->size = old_size + size; +} + static CFISH_INLINE void SI_add_grow_and_oversize(CharBuf *self, size_t size, size_t extra) { size_t min_size = size + extra; From 8c8780a7d485d901f70bddcfe893947f5fd400af Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 12 Nov 2015 16:46:07 +0100 Subject: [PATCH 6/6] Adjust Go bindings for CharBuf changes --- runtime/go/clownfish/charbuf_test.go | 30 ++++++++-------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/runtime/go/clownfish/charbuf_test.go b/runtime/go/clownfish/charbuf_test.go index 27c2b031..ec89e520 100644 --- a/runtime/go/clownfish/charbuf_test.go +++ b/runtime/go/clownfish/charbuf_test.go @@ -20,17 +20,7 @@ import "testing" func TestCharBufCat(t *testing.T) { cb := NewCharBuf(0) - cb.cat("foo") - if got := cb.ToString(); got != "foo" { - t.Errorf("Expected foo, got %v", got) - } -} - -func TestCharBufMimic(t *testing.T) { - cb := NewCharBuf(0) - other := NewCharBuf(0) - other.cat("foo") - cb.Mimic(other) + cb.Cat("foo") if got := cb.ToString(); got != "foo" { t.Errorf("Expected foo, got %v", got) } @@ -38,27 +28,23 @@ func TestCharBufMimic(t *testing.T) { func TestCharBufCatChar(t *testing.T) { cb := NewCharBuf(0) - cb.catChar('x') + cb.CatChar('x') if got := cb.ToString(); got != "x" { t.Errorf("Expected x, got %v", got) } } -func TestCharBufSetSizeGetSize(t *testing.T) { +func TestCharBufGetSize(t *testing.T) { cb := NewCharBuf(0) - cb.cat("abc") - cb.setSize(2) - if got := cb.getSize(); got != 2 { - t.Errorf("Size should be 2 but got %d", got) - } - if got := cb.ToString(); got != "ab" { - t.Errorf("Expected ab, got %v", got) + cb.Cat("abc") + if got := cb.GetSize(); got != 3 { + t.Errorf("Size should be 3 but got %d", got) } } func TestCharBufClone(t *testing.T) { cb := NewCharBuf(0) - cb.cat("foo") + cb.Cat("foo") clone := cb.Clone() if got := clone.ToString(); got != "foo" { t.Errorf("Expected foo, got %v", got) @@ -67,7 +53,7 @@ func TestCharBufClone(t *testing.T) { func TestCharBufYieldString(t *testing.T) { cb := NewCharBuf(0) - cb.cat("foo") + cb.Cat("foo") if got := cb.YieldString(); got != "foo" { t.Errorf("Should yield foo, got %v", got) }