diff --git a/http/http_response.c b/http/http_response.c
index ec85013..fe4f57d 100644
--- a/http/http_response.c
+++ b/http/http_response.c
@@ -20,124 +20,73 @@ s_http_response * http_response_buf_parse (s_http_response *response,
{
sw content_length = -1;
s_str content_length_str = {0};
- s_tag default_messages = {0};
- s_ident ident = {0};
s_tag *key = NULL;
- const s_list *l = NULL;
+ s_list **l = NULL;
sw r = 0;
- sw result = 0;
+ s_buf_save save;
+ s_str str;
s_tag tag_code = {0};
- s_tag tag_message = {0};
s_http_response tmp = {0};
+ s_tuple *tuple = NULL;
s_tag *value = NULL;
assert(response);
assert(buf);
- if ((r = buf_read_until_1_into_str(buf, ' ', &tmp.protocol)) < 0)
- return r;
- result += r;
- tag_code.type = TAG_U16;
- tag_code.data.u16 = response->code;
- if (! tag_code.data.u16)
- tag_code.data.u16 = 200;
+ buf_save_init(buf, &save);
+ if (! buf_read_until_1_into_str(buf, " ", &tmp.protocol))
+ goto clean;
+ if (! buf_parse_tag_u16(buf, &tag_code))
+ goto restore;
if (tag_code.data.u16 < 100 || tag_code.data.u16 > 999) {
- err_puts("http_response_buf_write: invalid response code");
- return -1;
+ err_puts("http_response_buf_parse: invalid response code");
+ goto restore;
}
- if ((r = buf_inspect_u16_decimal(buf, &tag_code.data.u16)) < 0)
- return r;
- result += r;
- if ((r = buf_write_1(buf, " ")) < 0)
- return r;
- result += r;
- if (! response->message.size) {
- ident_init(&ident, sym_1("HTTP.Response"), sym_1("default_messages"));
- ident_get(&ident, &default_messages);
- if (! tag_is_alist(&default_messages)) {
- err_puts("http_response_buf_write: invalid default_messages:"
- " not an AList");
- tag_clean(&default_messages);
- return -1;
- }
- if (alist_get((const s_list * const *) &default_messages.data.list,
- &tag_code, &tag_message)) {
- if (tag_message.type != TAG_STR) {
- err_puts("http_response_buf_write: invalid default message:"
- " not a Str");
- tag_clean(&tag_message);
- tag_clean(&default_messages);
- return -1;
- }
- }
- }
- else {
- tag_message.type = TAG_STR;
- tag_message.data.str = response->message;
- tag_message.data.str.free.p = NULL;
- }
- if ((r = buf_write_str(buf, &tag_message.data.str)) < 0) {
- tag_clean(&tag_message);
- tag_clean(&default_messages);
- return r;
- }
- result += r;
- tag_clean(&tag_message);
- tag_clean(&default_messages);
- if ((r = buf_write_1(buf, "\r\n")) < 0)
- return r;
- result += r;
- str_init_1(&content_length_str, NULL, "Content-Length");
- l = response->headers;
- while (l) {
- if (l->tag.type != TAG_TUPLE ||
- l->tag.data.tuple.count != 2) {
- err_puts("http_response_buf_write: invalid header: not a Tuple");
- return -1;
- }
- key = l->tag.data.tuple.tag;
- value = key + 1;
- if (key->type != TAG_STR || value->type != TAG_STR) {
- err_puts("http_response_buf_write: invalid header: not a Str");
- return -1;
- }
- if (! compare_str(&content_length_str, &key->data.str))
+ if ((r = buf_read_1(buf, " ")) <= 0)
+ goto restore;
+ if (! buf_read_until_1_into_str(buf, "\r\n", &tmp.message))
+ goto restore;
+ str_init_1(&content_length_str, NULL, "content-length");
+ l = &tmp.headers;
+ while (1) {
+ if ((r = buf_read_1(buf, "\r\n")) < 0)
+ goto restore;
+ if (r > 0)
+ break;
+ *l = list_new_tuple(2, NULL);
+ if (! *l)
+ goto restore;
+ tuple = &(*l)->tag.data.tuple;
+ key = tuple->tag;
+ value = tuple->tag + 1;
+ key->type = TAG_STR;
+ if (! buf_read_until_1_into_str(buf, ":", &key->data.str))
+ goto restore;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ value->type = TAG_STR;
+ if (! buf_read_until_1_into_str(buf, "\r\n", &value->data.str))
+ goto restore;
+ if (! str_init_to_lower(&str, &key->data.str))
+ goto restore;
+ if (! compare_str(&content_length_str, &str))
sw_init_str(&content_length, &value->data.str);
- if ((r = buf_write_str(buf, &key->data.str)) < 0)
- return r;
- result += r;
- if ((r = buf_write_1(buf, ": ")) < 0)
- return r;
- result += r;
- if ((r = buf_write_str(buf, &value->data.str)) < 0)
- return r;
- result += r;
- if ((r = buf_write_1(buf, "\r\n")) < 0)
- return r;
- result += r;
- l = list_next(l);
- }
- if (content_length < 0) {
- if ((r = buf_write_str(buf, &content_length_str)) < 0)
- return r;
- result += r;
- if ((r = buf_write_1(buf, ": ")) < 0)
- return r;
- result += r;
- if ((r = buf_inspect_uw_decimal(buf, &response->body.size)) < 0)
- return r;
- result += r;
- if ((r = buf_write_1(buf, "\r\n")) < 0)
- return r;
- result += r;
+ str_clean(&str);
+ l = &(*l)->next.data.list;
}
- if ((r = buf_write_1(buf, "\r\n")) < 0)
- return r;
- result += r;
- if (send_body) {
- if ((r = buf_write_str(buf, &response->body)) < 0)
- return r;
- result += r;
- }
- return result;
+ if (! parse_body)
+ goto ok;
+ if (content_length < 0)
+ goto restore;
+ if (! buf_read(buf, content_length, &response->body))
+ goto restore;
+ ok:
+ buf_save_clean(buf, &save);
+ *response = tmp;
+ return response;
+ restore:
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ return NULL;
}
sw http_response_buf_write (const s_http_response *response,
diff --git a/json/json.c b/json/json.c
index a67aa6a..f681ee0 100644
--- a/json/json.c
+++ b/json/json.c
@@ -251,7 +251,7 @@ sw json_buf_inspect_tag_number_size (s_pretty *pretty, const s_tag *tag)
sw json_buf_inspect_void (s_buf *buf)
{
- assert(pretty);
+ assert(buf);
return buf_write_1(buf, "null");
}
diff --git a/libkc3/buf.c b/libkc3/buf.c
index 48883d4..36bb815 100644
--- a/libkc3/buf.c
+++ b/libkc3/buf.c
@@ -644,6 +644,33 @@ sw buf_peek_u64 (s_buf *buf, u64 *p)
return size;
}
+s_str * buf_read (s_buf *buf, uw size, s_str *dest)
+{
+ char *p;
+ sw r;
+ s_str tmp = {0};
+ assert(buf);
+ if (! size)
+ return str_init_empty(dest);
+ if (buf->rpos > buf->wpos)
+ return NULL;
+ if (buf->rpos + size > buf->wpos &&
+ (r = buf_refill(buf, size)) < (sw) size)
+ return NULL;
+ if (buf->rpos + size > buf->wpos) {
+ assert(! "buffer overflow");
+ return NULL;
+ }
+ p = alloc(size);
+ if (! p)
+ return NULL;
+ str_init(&tmp, p, size, p);
+ memcpy(p, buf->ptr.ps8 + buf->rpos, size);
+ buf->rpos += size;
+ *dest = tmp;
+ return dest;
+}
+
sw buf_read_1 (s_buf *buf, const char *p)
{
s_str str;
diff --git a/libkc3/buf.h b/libkc3/buf.h
index 57f6ca1..180383a 100644
--- a/libkc3/buf.h
+++ b/libkc3/buf.h
@@ -69,6 +69,7 @@ sw buf_peek_u32 (s_buf *buf, u32 *p);
sw buf_peek_u64 (s_buf *buf, u64 *p);
sw buf_read_integer (s_buf *buf, s_integer *dst);
sw buf_read_character_utf8 (s_buf *buf, character *p);
+s_str * buf_read (s_buf *buf, uw size, s_str *dest);
sw buf_read_1 (s_buf *buf, const char *p);
sw buf_read_f32 (s_buf *buf, f32 *p);
sw buf_read_f64 (s_buf *buf, f64 *p);
diff --git a/libkc3/buf_parse.c b/libkc3/buf_parse.c
index 3abdfdc..bbd316e 100644
--- a/libkc3/buf_parse.c
+++ b/libkc3/buf_parse.c
@@ -4204,29 +4204,6 @@ sw buf_parse_tag_tuple (s_buf *buf, s_tag *dest)
return r;
}
-s_tag * buf_parse_tag_u16 (s_buf *buf, s_tag *dest)
-{
- sw r;
- s_buf_save save;
- s_tag tag;
- const s_sym *type = &g_sym_U16;
- u16 u;
- assert(buf);
- assert(dest);
- buf_save_init(buf, &save);
- r = buf_parse_tag_integer(buf, &tag);
- if (r > 0) {
- if (! u16_init_cast(&u, &type, &tag))
- goto restore;
- buf_save_clean(buf, &save);
- return tag_init_u16(dest, u);
- }
- restore:
- buf_save_restore_rpos(buf, &save);
- buf_save_clean(buf, &save);
- return NULL;
-}
-
sw buf_parse_tag_unquote (s_buf *buf, s_tag *dest)
{
sw r;
diff --git a/libkc3/buf_parse_s.c.in b/libkc3/buf_parse_s.c.in
index 5c5a767..41796b9 100644
--- a/libkc3/buf_parse_s.c.in
+++ b/libkc3/buf_parse_s.c.in
@@ -164,3 +164,25 @@ sw buf_parse_s_bits$_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_s_bits$ (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S_BITS$;
+ if (buf_parse_s_bits$(buf, &tmp.data.s_bits$) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_s_bits$_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S_BITS$;
+ if (buf_parse_s_bits$_base(buf, base, negative,
+ &tmp.data.s_bits$) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_s.h.in b/libkc3/buf_parse_s.h.in
index 1e2ed86..af03b56 100644
--- a/libkc3/buf_parse_s.h.in
+++ b/libkc3/buf_parse_s.h.in
@@ -19,5 +19,8 @@
sw buf_parse_s_bits$ (s_buf *buf, s_bits$ *dest);
sw buf_parse_s_bits$_base (s_buf *buf, const s_str *base,
bool negative, s_bits$ *dest);
+s_tag * buf_parse_tag_s_bits$ (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_s_bits$_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_S_BITS$_H */
diff --git a/libkc3/buf_parse_s16.c b/libkc3/buf_parse_s16.c
index 710b38b..d78063b 100644
--- a/libkc3/buf_parse_s16.c
+++ b/libkc3/buf_parse_s16.c
@@ -164,3 +164,25 @@ sw buf_parse_s16_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_s16 (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S16;
+ if (buf_parse_s16(buf, &tmp.data.s16) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_s16_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S16;
+ if (buf_parse_s16_base(buf, base, negative,
+ &tmp.data.s16) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_s16.h b/libkc3/buf_parse_s16.h
index 1e9b96f..a08f167 100644
--- a/libkc3/buf_parse_s16.h
+++ b/libkc3/buf_parse_s16.h
@@ -19,5 +19,8 @@
sw buf_parse_s16 (s_buf *buf, s16 *dest);
sw buf_parse_s16_base (s_buf *buf, const s_str *base,
bool negative, s16 *dest);
+s_tag * buf_parse_tag_s16 (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_s16_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_S16_H */
diff --git a/libkc3/buf_parse_s32.c b/libkc3/buf_parse_s32.c
index 266976a..0df894c 100644
--- a/libkc3/buf_parse_s32.c
+++ b/libkc3/buf_parse_s32.c
@@ -164,3 +164,25 @@ sw buf_parse_s32_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_s32 (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S32;
+ if (buf_parse_s32(buf, &tmp.data.s32) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_s32_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S32;
+ if (buf_parse_s32_base(buf, base, negative,
+ &tmp.data.s32) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_s32.h b/libkc3/buf_parse_s32.h
index 7b97813..71c5f45 100644
--- a/libkc3/buf_parse_s32.h
+++ b/libkc3/buf_parse_s32.h
@@ -19,5 +19,8 @@
sw buf_parse_s32 (s_buf *buf, s32 *dest);
sw buf_parse_s32_base (s_buf *buf, const s_str *base,
bool negative, s32 *dest);
+s_tag * buf_parse_tag_s32 (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_s32_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_S32_H */
diff --git a/libkc3/buf_parse_s64.c b/libkc3/buf_parse_s64.c
index c9813d8..a7466d0 100644
--- a/libkc3/buf_parse_s64.c
+++ b/libkc3/buf_parse_s64.c
@@ -164,3 +164,25 @@ sw buf_parse_s64_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_s64 (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S64;
+ if (buf_parse_s64(buf, &tmp.data.s64) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_s64_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S64;
+ if (buf_parse_s64_base(buf, base, negative,
+ &tmp.data.s64) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_s64.h b/libkc3/buf_parse_s64.h
index 235249f..4317103 100644
--- a/libkc3/buf_parse_s64.h
+++ b/libkc3/buf_parse_s64.h
@@ -19,5 +19,8 @@
sw buf_parse_s64 (s_buf *buf, s64 *dest);
sw buf_parse_s64_base (s_buf *buf, const s_str *base,
bool negative, s64 *dest);
+s_tag * buf_parse_tag_s64 (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_s64_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_S64_H */
diff --git a/libkc3/buf_parse_s8.c b/libkc3/buf_parse_s8.c
index 0873e8f..ba256cd 100644
--- a/libkc3/buf_parse_s8.c
+++ b/libkc3/buf_parse_s8.c
@@ -164,3 +164,25 @@ sw buf_parse_s8_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_s8 (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S8;
+ if (buf_parse_s8(buf, &tmp.data.s8) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_s8_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_S8;
+ if (buf_parse_s8_base(buf, base, negative,
+ &tmp.data.s8) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_s8.h b/libkc3/buf_parse_s8.h
index f533eb5..c7ed0c6 100644
--- a/libkc3/buf_parse_s8.h
+++ b/libkc3/buf_parse_s8.h
@@ -19,5 +19,8 @@
sw buf_parse_s8 (s_buf *buf, s8 *dest);
sw buf_parse_s8_base (s_buf *buf, const s_str *base,
bool negative, s8 *dest);
+s_tag * buf_parse_tag_s8 (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_s8_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_S8_H */
diff --git a/libkc3/buf_parse_sw.c b/libkc3/buf_parse_sw.c
index 5852ce8..42b5f61 100644
--- a/libkc3/buf_parse_sw.c
+++ b/libkc3/buf_parse_sw.c
@@ -164,3 +164,25 @@ sw buf_parse_sw_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_sw (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_SW;
+ if (buf_parse_sw(buf, &tmp.data.sw) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_sw_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_SW;
+ if (buf_parse_sw_base(buf, base, negative,
+ &tmp.data.sw) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_sw.h b/libkc3/buf_parse_sw.h
index c2933ee..29e1d3f 100644
--- a/libkc3/buf_parse_sw.h
+++ b/libkc3/buf_parse_sw.h
@@ -19,5 +19,8 @@
sw buf_parse_sw (s_buf *buf, sw *dest);
sw buf_parse_sw_base (s_buf *buf, const s_str *base,
bool negative, sw *dest);
+s_tag * buf_parse_tag_sw (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_sw_base (s_buf *buf, const s_str *base,
+ bool negative, s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_SW_H */
diff --git a/libkc3/buf_parse_u.c.in b/libkc3/buf_parse_u.c.in
index 1d95e72..edacd21 100644
--- a/libkc3/buf_parse_u.c.in
+++ b/libkc3/buf_parse_u.c.in
@@ -154,3 +154,24 @@ sw buf_parse_u_bits$_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_u_bits$ (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U_BITS$;
+ if (buf_parse_u_bits$(buf, &tmp.data.u_bits$) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_u_bits$_base (s_buf *buf, const s_str *base,
+ s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U_BITS$;
+ if (buf_parse_u_bits$_base(buf, base, &tmp.data.u_bits$) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_u.h.in b/libkc3/buf_parse_u.h.in
index d2e7178..fee8d12 100644
--- a/libkc3/buf_parse_u.h.in
+++ b/libkc3/buf_parse_u.h.in
@@ -19,5 +19,8 @@
sw buf_parse_u_bits$ (s_buf *buf, u_bits$ *dest);
sw buf_parse_u_bits$_base (s_buf *buf, const s_str *base,
u_bits$ *dest);
+s_tag * buf_parse_tag_u_bits$ (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_u_bits$_base (s_buf *buf, const s_str *base,
+ s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_U_BITS$_H */
diff --git a/libkc3/buf_parse_u16.c b/libkc3/buf_parse_u16.c
index 83f2aa3..fce9b62 100644
--- a/libkc3/buf_parse_u16.c
+++ b/libkc3/buf_parse_u16.c
@@ -154,3 +154,24 @@ sw buf_parse_u16_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_u16 (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U16;
+ if (buf_parse_u16(buf, &tmp.data.u16) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_u16_base (s_buf *buf, const s_str *base,
+ s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U16;
+ if (buf_parse_u16_base(buf, base, &tmp.data.u16) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_u16.h b/libkc3/buf_parse_u16.h
index a965513..4ab68da 100644
--- a/libkc3/buf_parse_u16.h
+++ b/libkc3/buf_parse_u16.h
@@ -19,5 +19,8 @@
sw buf_parse_u16 (s_buf *buf, u16 *dest);
sw buf_parse_u16_base (s_buf *buf, const s_str *base,
u16 *dest);
+s_tag * buf_parse_tag_u16 (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_u16_base (s_buf *buf, const s_str *base,
+ s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_U16_H */
diff --git a/libkc3/buf_parse_u32.c b/libkc3/buf_parse_u32.c
index 9f34216..d3e771b 100644
--- a/libkc3/buf_parse_u32.c
+++ b/libkc3/buf_parse_u32.c
@@ -154,3 +154,24 @@ sw buf_parse_u32_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_u32 (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U32;
+ if (buf_parse_u32(buf, &tmp.data.u32) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_u32_base (s_buf *buf, const s_str *base,
+ s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U32;
+ if (buf_parse_u32_base(buf, base, &tmp.data.u32) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_u32.h b/libkc3/buf_parse_u32.h
index b0e14df..8fbc6c8 100644
--- a/libkc3/buf_parse_u32.h
+++ b/libkc3/buf_parse_u32.h
@@ -19,5 +19,8 @@
sw buf_parse_u32 (s_buf *buf, u32 *dest);
sw buf_parse_u32_base (s_buf *buf, const s_str *base,
u32 *dest);
+s_tag * buf_parse_tag_u32 (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_u32_base (s_buf *buf, const s_str *base,
+ s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_U32_H */
diff --git a/libkc3/buf_parse_u64.c b/libkc3/buf_parse_u64.c
index bd53f7e..c27df5d 100644
--- a/libkc3/buf_parse_u64.c
+++ b/libkc3/buf_parse_u64.c
@@ -154,3 +154,24 @@ sw buf_parse_u64_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_u64 (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U64;
+ if (buf_parse_u64(buf, &tmp.data.u64) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_u64_base (s_buf *buf, const s_str *base,
+ s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U64;
+ if (buf_parse_u64_base(buf, base, &tmp.data.u64) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_u64.h b/libkc3/buf_parse_u64.h
index a4f9a4c..3c5468e 100644
--- a/libkc3/buf_parse_u64.h
+++ b/libkc3/buf_parse_u64.h
@@ -19,5 +19,8 @@
sw buf_parse_u64 (s_buf *buf, u64 *dest);
sw buf_parse_u64_base (s_buf *buf, const s_str *base,
u64 *dest);
+s_tag * buf_parse_tag_u64 (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_u64_base (s_buf *buf, const s_str *base,
+ s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_U64_H */
diff --git a/libkc3/buf_parse_u8.c b/libkc3/buf_parse_u8.c
index 279290b..c339e05 100644
--- a/libkc3/buf_parse_u8.c
+++ b/libkc3/buf_parse_u8.c
@@ -154,3 +154,24 @@ sw buf_parse_u8_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_u8 (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U8;
+ if (buf_parse_u8(buf, &tmp.data.u8) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_u8_base (s_buf *buf, const s_str *base,
+ s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_U8;
+ if (buf_parse_u8_base(buf, base, &tmp.data.u8) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_u8.h b/libkc3/buf_parse_u8.h
index 48b2957..fd23a59 100644
--- a/libkc3/buf_parse_u8.h
+++ b/libkc3/buf_parse_u8.h
@@ -19,5 +19,8 @@
sw buf_parse_u8 (s_buf *buf, u8 *dest);
sw buf_parse_u8_base (s_buf *buf, const s_str *base,
u8 *dest);
+s_tag * buf_parse_tag_u8 (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_u8_base (s_buf *buf, const s_str *base,
+ s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_U8_H */
diff --git a/libkc3/buf_parse_uw.c b/libkc3/buf_parse_uw.c
index 0621cd7..43d9b9a 100644
--- a/libkc3/buf_parse_uw.c
+++ b/libkc3/buf_parse_uw.c
@@ -154,3 +154,24 @@ sw buf_parse_uw_base (s_buf *buf, const s_str *base,
buf_save_clean(buf, &save);
return r;
}
+
+s_tag * buf_parse_tag_uw (s_buf *buf, s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_UW;
+ if (buf_parse_uw(buf, &tmp.data.uw) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * buf_parse_tag_uw_base (s_buf *buf, const s_str *base,
+ s_tag *dest)
+{
+ s_tag tmp = {0};
+ tmp.type = TAG_UW;
+ if (buf_parse_uw_base(buf, base, &tmp.data.uw) <= 0)
+ return NULL;
+ *dest = tmp;
+ return dest;
+}
diff --git a/libkc3/buf_parse_uw.h b/libkc3/buf_parse_uw.h
index cb0b6f4..c1c0b7c 100644
--- a/libkc3/buf_parse_uw.h
+++ b/libkc3/buf_parse_uw.h
@@ -19,5 +19,8 @@
sw buf_parse_uw (s_buf *buf, uw *dest);
sw buf_parse_uw_base (s_buf *buf, const s_str *base,
uw *dest);
+s_tag * buf_parse_tag_uw (s_buf *buf, s_tag *dest);
+s_tag * buf_parse_tag_uw_base (s_buf *buf, const s_str *base,
+ s_tag *dest);
#endif /* LIBKC3_BUF_PARSE_UW_H */
diff --git a/libkc3/str.c b/libkc3/str.c
index ddbfe24..8ff58d1 100644
--- a/libkc3/str.c
+++ b/libkc3/str.c
@@ -566,6 +566,40 @@ s_str * str_init_slice (s_str *str, const s_str *src, sw start, sw end)
return str;
}
+s_str * str_init_to_lower (s_str *str, const s_str *src)
+{
+ s_buf buf;
+ character c;
+ s_str i_src;
+ assert(str);
+ assert(src);
+ if (! buf_init_alloc(&buf, src->size))
+ return NULL;
+ i_src = *src;
+ while (str_read_character_utf8(&i_src, &c) > 0) {
+ c = character_to_lower(c);
+ buf_write_character_utf8(&buf, c);
+ }
+ return buf_read_to_str(&buf, str);
+}
+
+s_str * str_init_to_upper (s_str *str, const s_str *src)
+{
+ s_buf buf;
+ character c;
+ s_str i_src;
+ assert(str);
+ assert(src);
+ if (! buf_init_alloc(&buf, src->size))
+ return NULL;
+ i_src = *src;
+ while (str_read_character_utf8(&i_src, &c) > 0) {
+ c = character_to_upper(c);
+ buf_write_character_utf8(&buf, c);
+ }
+ return buf_read_to_str(&buf, str);
+}
+
DEF_STR_INIT_STRUCT(tuple)
DEF_STR_INIT_INT(u8)
DEF_STR_INIT_INT(u16)
diff --git a/libkc3/str.h b/libkc3/str.h
index a9b6c6b..589affc 100644
--- a/libkc3/str.h
+++ b/libkc3/str.h
@@ -68,6 +68,8 @@ s_str * str_init_slice_utf8 (s_str *str, const s_str *src, sw start,
sw end);
PROTOTYPE_STR_INIT_STRUCT(struct);
PROTOTYPE_STR_INIT_INT(sw);
+s_str * str_init_to_lower (s_str *str, const s_str *src);
+s_str * str_init_to_upper (s_str *str, const s_str *src);
PROTOTYPE_STR_INIT_STRUCT(tuple);
PROTOTYPE_STR_INIT_INT(u8);
PROTOTYPE_STR_INIT_INT(u16);