blob: a5b270821c2589baeed4569a896a80bf07de4099 [file] [log] [blame] [raw]
/*
Copyright: Boaz Segev, 2017
License: MIT
Feel free to copy, use and enjoy according to the license provided.
Copyright refers to the parser, not the protocol.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "fio2resp.h"
#include "fiobj.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct resp_format_s {
uint8_t *dest;
size_t *size;
size_t limit;
int err;
};
static int resp_fioformat_task(fiobj_s *obj, void *s_) {
fiobj_s *str = s_;
switch (obj->type) {
case FIOBJ_T_FALSE:
fiobj_str_write(str, "false\r\n", 7);
break;
case FIOBJ_T_TRUE:
fiobj_str_write(str, "true\r\n", 6);
break;
case FIOBJ_T_STRING:
case FIOBJ_T_SYMBOL: {
/* use this opportunity to optimize memory allocation to page boundries */
fio_cstr_s s = fiobj_obj2cstr(str);
if (fiobj_str_capa(str) <= s.len + 128 + fiobj_obj2cstr(obj).len) {
fiobj_str_resize(str, (((fiobj_str_capa(str) >> 12) + 1) << 12) - 1);
fiobj_str_resize(str, s.len);
}
}
/* fallthrough */
case FIOBJ_T_NUMBER:
case FIOBJ_T_FLOAT:
fiobj_str_join(str, obj);
fiobj_str_write(str, "\r\n", 2);
break;
case FIOBJ_T_FILE:
case FIOBJ_T_IO:
case FIOBJ_T_NULL:
fiobj_str_write(str, "$-1\r\n", 4);
return 0;
case FIOBJ_T_ARRAY:
fiobj_str_write2(str, "*%lu\r\n", (unsigned long)fiobj_ary_count(obj));
break;
case FIOBJ_T_HASH:
fiobj_str_write2(str, "*%lu\r\n", (unsigned long)fiobj_hash_count(obj));
break;
case FIOBJ_T_COUPLET:
resp_fioformat_task(fiobj_couplet2key(obj), s_);
resp_fioformat_task(fiobj_couplet2obj(obj), s_);
return 0;
}
return 0;
}
#undef safe_write_eol
#undef safe_write1
#undef safe_write2
#undef safe_write_i
fiobj_pt resp_fioformat(fiobj_pt obj) {
fiobj_pt str = fiobj_str_buf(4096);
fiobj_each2(obj, resp_fioformat_task, str);
return str;
}