From 08b4a34a8ece5917baf25d2b594f03d43aa1c437 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Thu, 28 Nov 2013 14:48:46 -0600 Subject: [PATCH] Add jv string utility functions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit jv_string_empty() -> return an empty string with given allocated length (for fast appends) jv_string_append_codepoint -> append a single codepoint (int) to the given string jv_string_explode -> return an array of codepoints making up a string jv_string_implode -> return the UTF-8 encoding of an array of codepoint numbers --- jv.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ jv.h | 4 ++++ 2 files changed, 57 insertions(+) diff --git a/jv.c b/jv.c index 7182445..92c4860 100644 --- a/jv.c +++ b/jv.c @@ -417,6 +417,14 @@ static jv_nontrivial jvp_string_new(const char* data, uint32_t length) { return r; } +static jv_nontrivial jvp_string_empty_new(uint32_t length) { + jvp_string* s = jvp_string_alloc(length); + s->length_hashed = 0; + memset(s->data, 0, length); + jv_nontrivial r = {&s->refcnt, {0,0}}; + return r; +} + static void jvp_string_free(jv_nontrivial* s) { if (jvp_refcnt_dec(s)) { jvp_string* str = jvp_string_ptr(s); @@ -560,6 +568,13 @@ jv jv_string_sized(const char* str, int len) { return j; } +jv jv_string_empty(int len) { + jv j; + j.kind = JV_KIND_STRING; + j.val.nontrivial = jvp_string_empty_new(len); + return j; +} + jv jv_string(const char* str) { return jv_string_sized(str, strlen(str)); } @@ -581,6 +596,37 @@ int jv_string_length_codepoints(jv j) { return len; } +jv jv_string_explode(jv j) { + assert(jv_get_kind(j) == JV_KIND_STRING); + const char* i = jv_string_value(j); + int len = jv_string_length_bytes(jv_copy(j)); + const char* end = i + len; + jv a = jv_array_sized(len); + int c; + while ((i = jvp_utf8_next(i, end, &c))) + a = jv_array_append(a, jv_number(c)); + jv_free(j); + return a; +} + +jv jv_string_implode(jv j) { + assert(jv_get_kind(j) == JV_KIND_ARRAY); + int len = jv_array_length(jv_copy(j)); + jv s = jv_string_empty(len); + int i; + + assert(len >= 0); + + for (i = 0; i < len; i++) { + jv n = jv_array_get(j, i); + assert(jv_get_kind(n) == JV_KIND_NUMBER); + s = jv_string_append_codepoint(s, jv_number_value(n)); + } + + jv_free(j); + return s; +} + unsigned long jv_string_hash(jv j) { assert(jv_get_kind(j) == JV_KIND_STRING); uint32_t hash = jvp_string_hash(jvp_string_ptr(&j.val.nontrivial)); @@ -612,6 +658,13 @@ jv jv_string_append_buf(jv a, const char* buf, int len) { return a; } +jv jv_string_append_codepoint(jv a, int c) { + char buf[5]; + int len = jvp_utf8_encode(c, buf); + jvp_string_append(&a.val.nontrivial, buf, len); + return a; +} + jv jv_string_append_str(jv a, const char* str) { return jv_string_append_buf(a, str, strlen(str)); } diff --git a/jv.h b/jv.h index 0f50359..50efbe6 100644 --- a/jv.h +++ b/jv.h @@ -75,14 +75,18 @@ jv jv_array_slice(jv, int, int); jv jv_string(const char*); jv jv_string_sized(const char*, int); +jv jv_string_empty(int len); int jv_string_length_bytes(jv); int jv_string_length_codepoints(jv); unsigned long jv_string_hash(jv); const char* jv_string_value(jv); jv jv_string_concat(jv, jv); jv jv_string_fmt(const char*, ...); +jv jv_string_append_codepoint(jv a, int c); jv jv_string_append_buf(jv a, const char* buf, int len); jv jv_string_append_str(jv a, const char* str); +jv jv_string_explode(jv j); +jv jv_string_implode(jv j); jv jv_object(); jv jv_object_get(jv object, jv key); -- 2.40.0