1#include "array.h" 2 3#include <string.h> 4#include <stdio.h> 5#include <stdlib.h> 6#include <assert.h> 7 8static data_unset *data_string_copy(const data_unset *s) { 9 data_string *src = (data_string *)s; 10 data_string *ds = data_string_init(); 11 12 buffer_copy_buffer(ds->key, src->key); 13 buffer_copy_buffer(ds->value, src->value); 14 ds->is_index_key = src->is_index_key; 15 return (data_unset *)ds; 16} 17 18static void data_string_free(data_unset *d) { 19 data_string *ds = (data_string *)d; 20 21 buffer_free(ds->key); 22 buffer_free(ds->value); 23 24 free(d); 25} 26 27static void data_string_reset(data_unset *d) { 28 data_string *ds = (data_string *)d; 29 30 /* reused array elements */ 31 buffer_reset(ds->key); 32 buffer_reset(ds->value); 33} 34 35static int data_string_insert_dup(data_unset *dst, data_unset *src) { 36 data_string *ds_dst = (data_string *)dst; 37 data_string *ds_src = (data_string *)src; 38 39 if (!buffer_is_empty(ds_dst->value)) { 40 buffer_append_string_len(ds_dst->value, CONST_STR_LEN(", ")); 41 buffer_append_string_buffer(ds_dst->value, ds_src->value); 42 } else { 43 buffer_copy_buffer(ds_dst->value, ds_src->value); 44 } 45 46 src->free(src); 47 48 return 0; 49} 50 51static int data_response_insert_dup(data_unset *dst, data_unset *src) { 52 data_string *ds_dst = (data_string *)dst; 53 data_string *ds_src = (data_string *)src; 54 55 if (!buffer_is_empty(ds_dst->value)) { 56 buffer_append_string_len(ds_dst->value, CONST_STR_LEN("\r\n")); 57 buffer_append_string_buffer(ds_dst->value, ds_dst->key); 58 buffer_append_string_len(ds_dst->value, CONST_STR_LEN(": ")); 59 buffer_append_string_buffer(ds_dst->value, ds_src->value); 60 } else { 61 buffer_copy_buffer(ds_dst->value, ds_src->value); 62 } 63 64 src->free(src); 65 66 return 0; 67} 68 69 70static void data_string_print(const data_unset *d, int depth) { 71 data_string *ds = (data_string *)d; 72 size_t i, len; 73 UNUSED(depth); 74 75 /* empty and uninitialized strings */ 76 if (buffer_string_is_empty(ds->value)) { 77 fputs("\"\"", stdout); 78 return; 79 } 80 81 /* print out the string as is, except prepend " with backslash */ 82 putc('"', stdout); 83 len = buffer_string_length(ds->value); 84 for (i = 0; i < len; i++) { 85 unsigned char c = ds->value->ptr[i]; 86 if (c == '"') { 87 fputs("\\\"", stdout); 88 } else { 89 putc(c, stdout); 90 } 91 } 92 putc('"', stdout); 93} 94 95 96data_string *data_string_init(void) { 97 data_string *ds; 98 99 ds = calloc(1, sizeof(*ds)); 100 force_assert(ds); 101 102 ds->key = buffer_init(); 103 ds->value = buffer_init(); 104 105 ds->copy = data_string_copy; 106 ds->free = data_string_free; 107 ds->reset = data_string_reset; 108 ds->insert_dup = data_string_insert_dup; 109 ds->print = data_string_print; 110 ds->type = TYPE_STRING; 111 112 return ds; 113} 114 115data_string *data_response_init(void) { 116 data_string *ds; 117 118 ds = data_string_init(); 119 ds->insert_dup = data_response_insert_dup; 120 121 return ds; 122} 123