forked from tofu702/tofu702_varz_daemon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
input_parser.c
145 lines (119 loc) · 3.92 KB
/
input_parser.c
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <stdio.h>
#include <string.h>
#include "input_parser.h"
#include "random.h"
/***** STATIC HELPER PROTOTYPES *****/
static enum VARZOperationType opNameToType(char *name);
static int getNextWord(char *in_string, char *dest, int dest_len);
void MHTCounterParse(char *cmd_remainder, struct VARZOperationDescription *dest);
void MHTSampleParse(char *cmd_remainder, struct VARZOperationDescription *dest);
/***** INTERFACE IMPLEMENTATION *****/
struct VARZOperationDescription VARZOpCmdParse(char *cmd, int cmd_len) {
// TODO: This whole function is sorta ugly & hackish, refactor it into something nicer
struct VARZOperationDescription desc;
char cmd_copy[cmd_len+1], op[VARZ_MAX_OP_LEN];
int op_len, var_name_len;
// Copy (We could potentially do this destructively instead)
strncpy(cmd_copy, cmd, cmd_len);
cmd_copy[cmd_len] = '\0';
// Check for trailing ';'
if (cmd_copy[cmd_len-1] != ';') {
desc.op = VARZOP_INVALID;
return desc;
}
// Otherwise it will be combined with the last string element
cmd_copy[cmd_len-1] = '\0';
// Parse out the op
op_len = getNextWord(cmd_copy, op, VARZ_MAX_OP_LEN);
if (op_len < 0) {
desc.op = VARZOP_INVALID;
return desc;
}
desc.op = opNameToType(op);
// Parse out the name
char *var_name_pos = cmd_copy + op_len + 1;
var_name_len = getNextWord(var_name_pos, desc.variable_name, VARZ_HASHTABLE_MAX_NAME_LEN);
if (var_name_len < 0) {
desc.op = VARZOP_INVALID;
return desc;
}
char *sub_command_pos = var_name_pos + var_name_len + 1;
switch (desc.op) {
case VARZOP_MHT_COUNTER_ADD:
MHTCounterParse(sub_command_pos, &desc);
break;
case VARZOP_MHT_SAMPLE_ADD:
MHTSampleParse(sub_command_pos, &desc);
break;
case VARZOP_ALL_DUMP_JSON:
break;
case VARZOP_ALL_LIST_JSON:
break;
case VARZOP_ALL_FLUSH:
break;
case VARZOP_MHT_COUNTER_GET:
break;
default:
desc.op = VARZOP_INVALID;
}
return desc;
}
/***** STATIC HELPERS *****/
static enum VARZOperationType opNameToType(char *name) {
if (!strcmp(VARZ_MHT_COUNTER_ADD_OP_NAME, name)) {
return VARZOP_MHT_COUNTER_ADD;
} else if (!strcmp(VARZ_MHT_COUNTER_GET_OP_NAME, name)) {
return VARZOP_MHT_COUNTER_GET;
} else if(!strcmp(VARZ_MHT_SAMPLE_ADD_OP_NAME, name)) {
return VARZOP_MHT_SAMPLE_ADD;
} else if(!strcmp(VARZ_ALL_DUMP_JSON_OP_NAME, name)) {
return VARZOP_ALL_DUMP_JSON;
} else if(!strcmp(VARZ_ALL_LIST_JSON_OP_NAME, name)) {
return VARZOP_ALL_LIST_JSON;
} else if(!strcmp(VARZ_ALL_FLUSH_OP_NAME, name)) {
return VARZOP_ALL_FLUSH;
} else {
return VARZOP_INVALID;
}
}
// Read the input up to the next space and copy the contents into dest.
// Returns the number of characters read
// If we don't find a space copies the remaining characters in the string
static int getNextWord(char *in_string, char *dest, int dest_len) {
char *loc;
int word_len;
loc = strchr(in_string, ' ');
if (!loc) {
loc = in_string + strlen(in_string);
}
if (!loc) {
dest[0] = '\0';
return -1;
}
word_len = (loc - in_string);
if(word_len > dest_len) {
dest[0] = '\0';
return -1;
}
strncpy(dest, in_string, word_len);
dest[word_len] = '\0';
return word_len;
}
void MHTCounterParse(char *cmd_remainder, struct VARZOperationDescription *dest) {
struct VARZMHTCounterAddOp *add_op = &(dest->op_data.counter_add_op);
// TODO: Some sanity checking
int rv = sscanf(cmd_remainder, "%lu %u", &(add_op->time), &(add_op->amt));
if (rv != 2) {
dest->op = VARZOP_INVALID;
}
}
void MHTSampleParse(char *cmd_remainder, struct VARZOperationDescription *dest) {
struct VARZMHTSamplerAddOp *sampler_op = &(dest->op_data.sampler_add_op);
int rv = sscanf(cmd_remainder, "%lu %lu", &(sampler_op->time), &(sampler_op->value));
if (rv != 2) {
dest->op = VARZOP_INVALID;
return;
}
sampler_op->random_vals[0] = VARZRand64();
sampler_op->random_vals[1] = VARZRand64();
}