Branch
Hash :
b1336c44
Author :
Thomas de Grivel
Date :
2025-09-01T00:41:17
rpc with structured data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
/* kc3
* Copyright from 2022 to 2025 kmx.io <contact@kmx.io>
*
* Permission is hereby granted to use this software granted the above
* copyright notice and this permission paragraph are included in all
* copies and substantial portions of this software.
*
* THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
* PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
* AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
* THIS SOFTWARE.
*/
#include "assert.h"
#include "rpc.h"
#include "buf.h"
#include "env.h"
#include "eval.h"
#include "str.h"
#include "struct.h"
#include "sym.h"
#include "tag.h"
s_tag * rpc_request (const s_str *input, s_tag *dest)
{
s_env *env;
s_buf *env_err;
s_buf *env_out;
s_buf err_buf;
char err_buf_data[BUF_SIZE];
s_buf out_buf;
char out_buf_data[BUF_SIZE];
s_tag input_tag;
s_rpc_response *response;
s_tag tmp = {0};
assert(input);
assert(dest);
env = env_global();
assert(env);
env_err = env->err;
buf_init(&err_buf, false, sizeof(err_buf_data), err_buf_data);
env->err = &err_buf;
env_out = env->out;
buf_init(&out_buf, false, sizeof(out_buf_data), out_buf_data);
env->out = &out_buf;
if (! tag_init_from_str(&input_tag, input)) {
env->err = env_err;
env->out = env_out;
err_puts("rpc_request: invalid input");
assert(! "rpc_request: invalid input");
return NULL;
}
if (! tag_init_pstruct(&tmp, &g_sym_RPC_Response)) {
env->err = env_err;
env->out = env_out;
err_puts("rpc_request: tag_init_pstruct %RPC.Response{}");
assert(! "rpc_request: tag_init_pstruct %RPC.Response{}");
tag_clean(&input_tag);
return NULL;
}
if (! struct_allocate(tmp.data.pstruct)) {
env->err = env_err;
env->out = env_out;
err_puts("rpc_request: struct_allocate");
assert(! "rpc_request: struct_allocate");
tag_clean(&tmp);
tag_clean(&input_tag);
return NULL;
}
response = tmp.data.pstruct->data;
eval_tag(&input_tag, &response->result);
if (buf_read_to_str(&err_buf, &response->err) < 0 ||
buf_read_to_str(&out_buf, &response->out) < 0) {
env->err = env_err;
env->out = env_out;
err_puts("rpc_request: buf_read_to_str");
assert(! "rpc_request: buf_read_to_str");
tag_clean(&tmp);
tag_clean(&input_tag);
return NULL;
}
tag_clean(&input_tag);
env->err = env_err;
env->out = env_out;
*dest = tmp;
return dest;
}
void rpc_response_clean (s_rpc_response *response)
{
assert(response);
str_clean(&response->err);
str_clean(&response->out);
tag_clean(&response->result);
}