Skip to content

Commit

Permalink
queue
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-jentzsch committed Jul 11, 2020
1 parent 632e889 commit 31870d0
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 85 deletions.
129 changes: 75 additions & 54 deletions c/src/cmd/in3/recorder.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,31 @@
#include "../../core/client/keys.h"
#include <math.h>
#include <stdio.h>
static void die(char* msg) {
fprintf(stderr, COLORT_RED "Error: %s" COLORT_RESET "\n", msg);
exit(EXIT_FAILURE);
}

typedef struct recorder_entry {
char* name;
char** args;
int argl;
sb_t content;
struct recorder_entry* next;

} recorder_entry_t;

typedef struct {
char* file;
in3_transport_send transport;
FILE* f;
in3_storage_handler_t* cache;
uint64_t time;
recorder_entry_t* queue;
} recorder_t;

typedef struct {
char* name;
char** args;
int argl;

} recorder_entry_t;

static recorder_t rec = {
.file = NULL,
.transport = NULL,
.f = NULL,
.cache = NULL,
.queue = NULL,
.time = 0};

static int rand_out(void* s) {
Expand All @@ -38,64 +38,89 @@ static int rand_out(void* s) {
return r;
}

recorder_entry_t read_entry(sb_t* sb) {
recorder_entry_t entry = {0};
static inline bool match(recorder_entry_t* entry, const char* type, const char* first_arg) {
return entry && entry->name && strcmp(type, entry->name) == 0 && (first_arg == NULL || (entry->argl && strcmp(entry->args[0], first_arg) == 0));
}

char buffer[1024];
static recorder_entry_t* read_one_entry() {
recorder_entry_t* entry = NULL;
char buffer[1024];
while (fgets(buffer, 1023, rec.f)) {
int l = strlen(buffer);
if (buffer[l - 1] == '\n')
buffer[--l] = 0;
if (!l) break;
if (!entry.name) {
char* ptr = strtok(buffer + 3, " ");
entry.name = _strdupn(ptr, -1);
if (!entry) {
entry = _calloc(sizeof(recorder_entry_t), 1);
char* ptr = strtok(buffer + 3, " ");
entry->name = _strdupn(ptr, -1);
while ((ptr = strtok(NULL, " "))) {
entry.args = entry.argl ? _realloc(entry.args, sizeof(char*) * (entry.argl + 1), sizeof(char*) * entry.argl) : _malloc(sizeof(char*));
entry.args[entry.argl++] = _strdupn(ptr, -1);
entry->args = entry->argl ? _realloc(entry->args, sizeof(char*) * (entry->argl + 1), sizeof(char*) * entry->argl) : _malloc(sizeof(char*));
entry->args[entry->argl++] = _strdupn(ptr, -1);
}
} else
sb_add_chars(sb, buffer);
sb_add_chars(&entry->content, buffer);
}

return entry;
}
static void entry_free(recorder_entry_t* e, sb_t* sb) {

recorder_entry_t* next_entry(const char* type, const char* firs_arg) {

recorder_entry_t *last = rec.queue, *end = NULL;
for (recorder_entry_t* n = last; n; last = n, n = n->next) {
if (match((end = n), type, firs_arg)) {
if (last == n)
rec.queue = n->next;
else
last->next = n->next;
return n;
}
}

do {
if (match((last = read_one_entry()), type, firs_arg))
return last;
if (!last) {
fprintf(stderr, COLORT_RED "Error: expected entry %s %s but did not find it!" COLORT_RESET "\n", type, firs_arg ? firs_arg : "");
exit(EXIT_FAILURE);
}
if (end)
end->next = last;
else
rec.queue = last;
end = last;

} while (true);
}

static void entry_free(recorder_entry_t* e) {
if (e->name) _free(e->name);
for (int i = 0; i < e->argl; i++) _free(e->args[i]);
_free(e->args);
if (sb && sb->data) _free(sb->data);
if (sb) *sb = (sb_t){0};
if (e->content.data) _free(e->content.data);
_free(e);
}
static int rand_in(void* s) {
UNUSED_VAR(s);
sb_t sb = {0};
recorder_entry_t entry = read_entry(&sb);
if (!entry.name || strcmp(entry.name, "rand")) die("expected rand in recorder!");
if (entry.argl != 1) die("expect one arg for random");
int r = atoi(entry.args[0]);
entry_free(&entry, &sb);

recorder_entry_t* entry = next_entry("rand", NULL);
int r = atoi(entry->args[0]);
entry_free(entry);
return r;
}

static in3_ret_t recorder_transport_in(in3_request_t* req) {
sb_t sb = {0};
recorder_entry_t entry = {0};

if (req->action == REQ_ACTION_SEND) {
entry = read_entry(&sb);
if (!entry.name || strcmp(entry.name, "request")) die("expected request in recorder!");
entry_free(&entry, &sb);
entry_free(next_entry("requqest", NULL));
req->cptr = &rec;
}
if (req->action != REQ_ACTION_CLEANUP) {
entry = read_entry(&sb);
if (!entry.name || strcmp(entry.name, "response")) die("expected response in recorder!");
in3_response_t* r = req->ctx->raw_response + atoi(entry.args[0]);
sb_add_chars(&r->data, sb.data);
r->state = atoi(entry.args[3]);
r->time = atoi(entry.args[4]);
entry_free(&entry, &sb);
recorder_entry_t* entry = next_entry("response", NULL);
in3_response_t* r = req->ctx->raw_response + atoi(entry->args[0]);
sb_add_chars(&r->data, entry->content.data);
r->state = atoi(entry->args[3]);
r->time = atoi(entry->args[4]);
entry_free(entry);
}

return 0;
Expand Down Expand Up @@ -130,13 +155,10 @@ static in3_ret_t recorder_transport_out(in3_request_t* req) {
bytes_t* rec_get_item_in(void* cptr, const char* key) {
UNUSED_VAR(cptr);
UNUSED_VAR(key);
sb_t sb = {0};
recorder_entry_t entry = read_entry(&sb);
if (!entry.name || strcmp(entry.name, "cache")) die("expected cache in recorder!");
if (entry.argl != 2) die("expect 2 args for cache");
if (strcmp(key, entry.args[0])) die("wrong cache key");
bytes_t* found = atoi(entry.args[1]) ? hex_to_new_bytes(sb.data, sb.len) : NULL;
entry_free(&entry, &sb);
sb_t sb = {0};
recorder_entry_t* entry = next_entry("cache", key);
bytes_t* found = atoi(entry->args[1]) ? hex_to_new_bytes(sb.data, sb.len) : NULL;
entry_free(entry);

return found;
}
Expand Down Expand Up @@ -195,9 +217,8 @@ void recorder_read_start(in3_t* c, char* file) {
rec.f = fopen(file, "r");
in3_set_func_rand(rand_in);
in3_set_storage_handler(c, rec_get_item_in, rec_set_item_in, rec_clear_in, &rec);
sb_t sb = {0};
recorder_entry_t entry = read_entry(&sb);
rec.time = entry.argl >= 1 ? atoll(entry.args[0]) : 0;
entry_free(&entry, &sb);
recorder_entry_t* entry = next_entry("time", NULL);
rec.time = entry->argl >= 1 ? atoll(entry->args[0]) : 0;
entry_free(entry);
in3_set_func_time(static_time);
}
12 changes: 7 additions & 5 deletions c/src/core/client/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,13 @@ char* ctx_get_error_data(in3_ctx_t* ctx) {
}

char* ctx_get_response_data(in3_ctx_t* ctx) {
str_range_t rr = d_to_json(ctx->responses[0]), rin3;
if ((ctx->client->flags & FLAGS_KEEP_IN3) == 0 && (rin3 = d_to_json(d_get(ctx->responses[0], K_IN3))).data) {
while (*rin3.data != ',' && rin3.data > rr.data) rin3.data--;
*rin3.data = '}';
rr.len = rin3.data - rr.data + 1;
str_range_t rr = d_to_json(ctx->responses[0]);
char* start = NULL;
if ((ctx->client->flags & FLAGS_KEEP_IN3) == 0 && (start = d_to_json(d_get(ctx->responses[0], K_IN3)).data) && start < rr.data + rr.len) {
while (*start != ',' && start > rr.data) start--;
char* res = _strdupn(rr.data, start - rr.data + 1);
res[start - rr.data] = '}';
return res;
}
return _strdupn(rr.data, rr.len);
}
Expand Down
44 changes: 18 additions & 26 deletions c/src/core/util/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,38 +127,30 @@ const char* u64_to_str(uint64_t value, char* buffer, int buffer_len) {
#endif

int hex_to_bytes(const char* buf, int len, uint8_t* out, int outbuf_size) {
if (!buf && len) return -1;
if (len == -1) {
len = strlen(buf);
if (len >= 2 && *buf == '0' && buf[1] == 'x') {
buf += 2;
len -= 2;
}
if (!buf || len < -1) return len == 0 ? 0 : -1;
if (len == -1) len = strlen(buf);
if (buf[0] == '0' && buf[1] == 'x') {
buf += 2;
len -= 2;
}
int i = len - 1;
int out_len = (len & 1) ? (len + 1) / 2 : len / 2;
int j = out_len - 1;

if (j > outbuf_size)
return -1; /* Output buffer is smaller than need */

while (i >= 0) {
out[j] = hexchar_to_int(buf[i--]);
if (i >= 0) {
out[j--] |= hexchar_to_int(buf[i--]) << 4;
}
if (len == 0) return 0;
int bytes_len = (len + 1) / 2, i = 0, j = 0;
if (bytes_len > outbuf_size) return -1;
if (len & 1) {
out[0] = hexchar_to_int(buf[0]);
j = i = 1;
}

return out_len;
for (; i < len; i += 2, ++j)
out[j] = (hexchar_to_int(buf[i]) << 4) | hexchar_to_int(buf[i + 1]);

return bytes_len;
}
bytes_t* hex_to_new_bytes(const char* buf, int len) {
int bytes_len = (len & 1) ? (len + 1) / 2 : len / 2;

uint8_t* b = _malloc(bytes_len);
bytes_t* bytes = _malloc(sizeof(bytes_t));
hex_to_bytes(buf, len, b, bytes_len);
bytes->data = b;
bytes->len = bytes_len;
bytes->len = (len + 1) / 2;
bytes->data = _malloc(bytes->len);
hex_to_bytes(buf, len, bytes->data, bytes->len);
return bytes;
}

Expand Down

0 comments on commit 31870d0

Please sign in to comment.