From 65ce73deb4eab4ef6d83a0ad44c603d6286e964d Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 10 Sep 2012 16:16:39 +0100 Subject: [PATCH] String concatenation. --- c/builtin.c | 2 ++ c/jv.c | 21 +++++++++++++++++++++ c/jv.h | 1 + c/testdata | 8 ++++++++ 4 files changed, 32 insertions(+) diff --git a/c/builtin.c b/c/builtin.c index 45056fc..bdca254 100644 --- a/c/builtin.c +++ b/c/builtin.c @@ -22,6 +22,8 @@ static void f_plus(jv input[], jv output[]) { if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { output[0] = jv_number(jv_number_value(a) + jv_number_value(b)); + } else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) { + output[0] = jv_string_concat(a, b); } else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) { output[0] = jv_array_concat(a, b); } else if (jv_get_kind(a) == JV_KIND_OBJECT && jv_get_kind(b) == JV_KIND_OBJECT) { diff --git a/c/jv.c b/c/jv.c index 8c0c034..f8b79ce 100644 --- a/c/jv.c +++ b/c/jv.c @@ -355,6 +355,7 @@ static jv_complex jvp_string_new(const char* data, uint32_t length) { return r; } + static void jvp_string_free(jv_complex* s) { if (jvp_refcnt_dec(s)) { jvp_string* str = jvp_string_ptr(s); @@ -377,6 +378,16 @@ static uint32_t jvp_string_length(jvp_string* s) { return s->length_hashed >> 1; } +static jv_complex jvp_string_concat(jvp_string* a, jvp_string* b) { + uint32_t la = jvp_string_length(a), lb = jvp_string_length(b); + jvp_string* s = jvp_string_alloc(la + lb); + memcpy(s->data, a->data, la); + memcpy(s->data + la, b->data, lb); + s->data[la + lb] = 0; + jv_complex r = {&s->refcnt, {0,0}}; + return r; +} + static const uint32_t HASH_SEED = 0x432A9843; static uint32_t rotl32 (uint32_t x, int8_t r){ @@ -488,6 +499,16 @@ const char* jv_string_value(jv j) { return jvp_string_ptr(&j.val.complex)->data; } +jv jv_string_concat(jv a, jv b) { + jv j; + j.kind = JV_KIND_STRING; + j.val.complex = jvp_string_concat(jvp_string_ptr(&a.val.complex), + jvp_string_ptr(&b.val.complex)); + jv_free(a); + jv_free(b); + return j; +} + jv jv_string_fmt(const char* fmt, ...) { int size = 1024; while (1) { diff --git a/c/jv.h b/c/jv.h index 9aadd41..ef64816 100644 --- a/c/jv.h +++ b/c/jv.h @@ -76,6 +76,7 @@ jv jv_string_sized(const char*, int); int jv_string_length(jv); uint32_t jv_string_hash(jv); const char* jv_string_value(jv); +jv jv_string_concat(jv, jv); jv jv_string_fmt(const char*, ...); jv jv_object(); diff --git a/c/testdata b/c/testdata index 11684dd..c353dc2 100644 --- a/c/testdata +++ b/c/testdata @@ -159,6 +159,14 @@ null "asdfasdf" {"a":1, "b":2, "c":3} +"asdf" + "jkl;" + . +"some string" +"asdfjkl;some string" + +"\u0000\u0020\u0000" + . +"\u0000\u0020\u0000" +"\u0000 \u0000\u0000 \u0000" + # # User-defined functions # Oh god. -- 2.40.0