int test_simple() { const char *js; int r; jsmn_parser p; jsmntok_t tokens[10]; js = "{\"a\": 0}"; jsmn_init(&p); r = jsmn_parse(&p, js, tokens, 10); check(r == JSMN_SUCCESS); check(TOKEN_EQ(tokens[0], 0, 8, JSMN_OBJECT)); check(TOKEN_EQ(tokens[1], 2, 3, JSMN_STRING)); check(TOKEN_EQ(tokens[2], 6, 7, JSMN_PRIMITIVE)); check(TOKEN_STRING(js, tokens[0], js)); check(TOKEN_STRING(js, tokens[1], "a")); check(TOKEN_STRING(js, tokens[2], "0")); jsmn_init(&p); js = "[\"a\":{},\"b\":{}]"; r = jsmn_parse(&p, js, tokens, 10); check(r == JSMN_SUCCESS); jsmn_init(&p); js = "{\n \"Day\": 26,\n \"Month\": 9,\n \"Year\": 12\n }"; r = jsmn_parse(&p, js, tokens, 10); check(r == JSMN_SUCCESS); return 0; }
bool json_parse_sprinkler_configuration(const char* json_buffer, Sprinkler* sprinkler) { int current_token_index; TokenVector *tokens = token_vector_new(); jsmntok_t* current_token; size_t number_of_tokens; bool ret = true; // Parse json string if (!json_parse(json_buffer, tokens)) { add_to_log("json_parse_sprinkler_configuration: Could not parse json.", ERROR); token_vector_destroy(tokens); return false; } current_token = token_vector_get_pointer(tokens, 0); number_of_tokens = current_token->size; if (number_of_tokens <= 0 || current_token->type != JSMN_OBJECT) { add_to_log("json_parse_sprinkler_configuration: Could not parse json.", ERROR); token_vector_destroy(tokens); return false; } // iterate of all tokens, try to load configuration values current_token++; for ( current_token_index = 0; current_token_index < number_of_tokens ; ) { // Lets find out what to do with the key- if (TOKEN_STRING(json_buffer, *current_token, ID_TAG)) { // Id tag if (!token_to_int(json_buffer, (current_token+1), &sprinkler->id)) { ret = false; break; } } else if (TOKEN_STRING(json_buffer, *current_token, REFRESH_RATE_TAG)) { // Port index tag if (!token_to_uint(json_buffer, (current_token+1), &sprinkler->refresh_rate)) { ret = false; break; } } else if (TOKEN_STRING(json_buffer, *current_token, MAIN_VALF_DELAY_TAG)) { // Port index tag if (!token_to_int(json_buffer, (current_token+1), &sprinkler->main_valf_delay)) { ret = false; break; } } else if (TOKEN_STRING(json_buffer, *current_token, MAIN_VALF_TAG)) { // Port index tag if (!token_to_int(json_buffer, (current_token+1), &sprinkler->main_valf)) { ret = false; break; } } // else - ignore this key. current_token_index += 2; current_token += 2; } token_vector_destroy(tokens); return ret; }
bool parse_sprinkler_configuration(const char* json_buffer, Sprinkler& sprinkler) { int current_token_index; Vector<jsmntok_t> tokens; jsmntok_t* current_token; size_t number_of_tokens; Parser parser; bool ret = true; // Parse json string if (parser.Parse(json_buffer, tokens) != JSON::JSMN_SUCCESS) { Logger::AddLine("json_parse_sprinkler_nfiguration: Could not parse json.", Logger::ERROR); return false; } current_token = &tokens[0]; number_of_tokens = current_token->size; if (number_of_tokens <= 0 || current_token->type != JSMN_OBJECT) { Logger::AddLine("json_parse_sprinkler_configuration: Could not parse json.", Logger::ERROR); return false; } // iterate of all tokens, try to load configuration values current_token++; for ( current_token_index = 0; current_token_index < number_of_tokens ; ) { // Lets find out what to do with the key- if (TOKEN_STRING(json_buffer, *current_token, ID_TAG)) { // Id tag if (!token_to_int(json_buffer, (current_token+1), sprinkler.id)) { return false; } } else if (TOKEN_STRING(json_buffer, *current_token, REFRESH_RATE_TAG)) { // Port index tag if (!token_to_uint(json_buffer, (current_token+1), sprinkler.refresh_rate)) { return false; } } else if (TOKEN_STRING(json_buffer, *current_token, MAIN_VALF_DELAY_TAG)) { // Port index tag if (!token_to_int(json_buffer, (current_token+1), sprinkler.main_valf_delay)) { // return false; sprinkler.main_valf_delay = 0; } } else if (TOKEN_STRING(json_buffer, *current_token, MAIN_VALF_TAG)) { // Port index tag if (!token_to_int(json_buffer, (current_token+1), sprinkler.main_valf)) { // return false; sprinkler.main_valf = -1; } } // else - ignore this key. current_token_index += 2; current_token += 2; } return ret; }
int test_primitive() { #ifndef JSMN_STRICT int r; jsmn_parser p; jsmntok_t tok[10]; const char *js; js = "\"boolVar\" : true"; jsmn_init(&p); r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_PRIMITIVE); check(TOKEN_STRING(js, tok[0], "boolVar")); check(TOKEN_STRING(js, tok[1], "true")); js = "\"boolVar\" : false"; jsmn_init(&p); r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_PRIMITIVE); check(TOKEN_STRING(js, tok[0], "boolVar")); check(TOKEN_STRING(js, tok[1], "false")); js = "\"intVar\" : 12345"; jsmn_init(&p); r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_PRIMITIVE); check(TOKEN_STRING(js, tok[0], "intVar")); check(TOKEN_STRING(js, tok[1], "12345")); js = "\"floatVar\" : 12.345"; jsmn_init(&p); r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_PRIMITIVE); check(TOKEN_STRING(js, tok[0], "floatVar")); check(TOKEN_STRING(js, tok[1], "12.345")); js = "\"nullVar\" : null"; jsmn_init(&p); r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_PRIMITIVE); check(TOKEN_STRING(js, tok[0], "nullVar")); check(TOKEN_STRING(js, tok[1], "null")); #endif return 0; }
int test_input_length() { const char *js; int r; jsmn_parser p; jsmntok_t tokens[10]; js = "{\"a\": 0}garbage"; jsmn_init(&p); r = jsmn_parse(&p, js, 8, tokens, 10); check(r == 3); check(TOKEN_STRING(js, tokens[0], "{\"a\": 0}")); check(TOKEN_STRING(js, tokens[1], "a")); check(TOKEN_STRING(js, tokens[2], "0")); return 0; }
void SkynetClient::processSkynet(char *data, char *ack) { jsmn_parser p; jsmntok_t tok[MAX_PARSE_OBJECTS]; jsmn_init(&p); int r = jsmn_parse(&p, data, tok, MAX_PARSE_OBJECTS); if (r != 0){ DBGCS("parse failed: "); DBGCN(r); return; } if (TOKEN_STRING(data, tok[2], IDENTIFY )) { DBGCSN(IDENTIFY); processIdentify(data, tok); } else if (TOKEN_STRING(data, tok[2], READY )) { DBGCSN(READY); processReady(data, tok); } else if (TOKEN_STRING(data, tok[2], NOTREADY )) { DBGCSN(NOTREADY); processNotReady(data, tok); } else if (TOKEN_STRING(data, tok[2], BIND )) { DBGCSN(BIND); processBind(data, tok, ack); } else if (TOKEN_STRING(data, tok[2], MESSAGE )) { DBGCSN(MESSAGE); processMessage(data, tok); } else { DBGCS("Unknown:"); } }
//Got credentials back, store if necessary void SkynetClient::processReady(char *data, jsmntok_t *tok) { DBGCSN("Skynet Connect"); char temp[UUIDSIZE]; status = 1; getUuid(temp); //if uuid has been refreshed, save it if (!TOKEN_STRING(data, tok[13], temp )) { DBGCSN("uuid refresh"); strncpy(temp, data + tok[13].start, tok[13].end - tok[13].start); DBGCS("new: "); DBGCN(temp); setUuid(temp); }else { DBGCSN("no uuid refresh necessary"); } getToken(temp); //if token has been refreshed, save it if (!TOKEN_STRING(data, tok[15], temp )) { DBGCSN("token refresh"); strncpy(temp, data + tok[15].start, tok[15].end - tok[15].start); DBGCS("new: "); DBGCN(temp); setToken(temp); }else { DBGCSN("no token refresh necessary"); } }
int test_nonstrict() { const char *js; int r; jsmn_parser p; jsmntok_t tokens[10]; js = "a: 0garbage"; jsmn_init(&p); r = jsmn_parse(&p, js, 4, tokens, 10); check(r == 2); check(TOKEN_STRING(js, tokens[0], "a")); check(TOKEN_STRING(js, tokens[1], "0")); js = "Day : 26\nMonth : Sep\n\nYear: 12"; jsmn_init(&p); r = jsmn_parse(&p, js, strlen(js), tokens, 10); check(r == 6); return 0; }
int test_unquoted_keys() { #ifndef JSMN_STRICT int r; jsmn_parser p; jsmntok_t tok[10]; const char *js; jsmn_init(&p); js = "key1: \"value\"\nkey2 : 123"; r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_PRIMITIVE && tok[1].type == JSMN_STRING && tok[2].type == JSMN_PRIMITIVE && tok[3].type == JSMN_PRIMITIVE); check(TOKEN_STRING(js, tok[0], "key1")); check(TOKEN_STRING(js, tok[1], "value")); check(TOKEN_STRING(js, tok[2], "key2")); check(TOKEN_STRING(js, tok[3], "123")); #endif return 0; }
int test_string() { int r; jsmn_parser p; jsmntok_t tok[10]; const char *js; js = "\"strVar\" : \"hello world\""; jsmn_init(&p); r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "strVar")); check(TOKEN_STRING(js, tok[1], "hello world")); js = "\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\""; jsmn_init(&p); r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "strVar")); check(TOKEN_STRING(js, tok[1], "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\")); js = "\"strVar\" : \"\""; jsmn_init(&p); r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "strVar")); check(TOKEN_STRING(js, tok[1], "")); return 0; }
int test_partial_string() { int r; jsmn_parser p; jsmntok_t tok[10]; const char *js; jsmn_init(&p); js = "\"x\": \"va"; r = jsmn_parse(&p, js, strlen(js), tok, 10); check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "x")); check(p.toknext == 1); jsmn_init(&p); char js_slash[9] = "\"x\": \"va\\"; r = jsmn_parse(&p, js_slash, sizeof(js_slash), tok, 10); check(r == JSMN_ERROR_PART); jsmn_init(&p); char js_unicode[10] = "\"x\": \"va\\u"; r = jsmn_parse(&p, js_unicode, sizeof(js_unicode), tok, 10); check(r == JSMN_ERROR_PART); js = "\"x\": \"valu"; r = jsmn_parse(&p, js, strlen(js), tok, 10); check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "x")); check(p.toknext == 1); js = "\"x\": \"value\""; r = jsmn_parse(&p, js, strlen(js), tok, 10); check(r >= 0 && tok[0].type == JSMN_STRING && tok[1].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "x")); check(TOKEN_STRING(js, tok[1], "value")); js = "\"x\": \"value\", \"y\": \"value y\""; r = jsmn_parse(&p, js, strlen(js), tok, 10); check(r >= 0 && tok[0].type == JSMN_STRING && tok[1].type == JSMN_STRING && tok[2].type == JSMN_STRING && tok[3].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "x")); check(TOKEN_STRING(js, tok[1], "value")); check(TOKEN_STRING(js, tok[2], "y")); check(TOKEN_STRING(js, tok[3], "value y")); return 0; }
int find_json_array_token(Vector<jsmntok_t> &tokens, const char* json_buffer, const char* token_key) { size_t current_token_index, found_token_index; const size_t number_of_tokens = tokens.size(); jsmntok_t* current_token = &tokens[0]; for (current_token_index = 0; current_token_index < number_of_tokens; current_token_index++, current_token++) { if (current_token->type == JSMN_STRING && TOKEN_STRING(json_buffer, *current_token, token_key)) { found_token_index = current_token_index + 1; if ((current_token+1)->type != JSMN_ARRAY) return -1; else return found_token_index; } } return -1; }
int test_partial_string() { int r; jsmn_parser p; jsmntok_t tok[10]; const char *js; jsmn_init(&p); js = "\"x\": \"va"; r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "x")); check(p.toknext == 1); js = "\"x\": \"valu"; r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "x")); check(p.toknext == 1); js = "\"x\": \"value\""; r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "x")); check(TOKEN_STRING(js, tok[1], "value")); js = "\"x\": \"value\", \"y\": \"value y\""; r = jsmn_parse(&p, js, tok, 10); check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING && tok[1].type == JSMN_STRING && tok[2].type == JSMN_STRING && tok[3].type == JSMN_STRING); check(TOKEN_STRING(js, tok[0], "x")); check(TOKEN_STRING(js, tok[1], "value")); check(TOKEN_STRING(js, tok[2], "y")); check(TOKEN_STRING(js, tok[3], "value y")); return 0; }
bool parse_time(const char* json_buffer, unsigned int &time) { int current_token_index; Vector<jsmntok_t> tokens; jsmntok_t* current_token; size_t number_of_tokens; Parser parser; bool ret = true; // Parse json string if (parser.Parse(json_buffer, tokens) != JSON::JSMN_SUCCESS) { Logger::AddLine("json_parse_time: Could not parse json.", Logger::ERROR); return false; } current_token = &tokens[0]; number_of_tokens = current_token->size; if (number_of_tokens <= 0 || current_token->type != JSMN_OBJECT) { Logger::AddLine("json_parse_time: Could not parse json.", Logger::ERROR); return false; } // iterate of all tokens, try to load configuration values current_token++; for ( current_token_index = 0; current_token_index < number_of_tokens ; ) { // Lets find out what to do with the key- if (TOKEN_STRING(json_buffer, *current_token, TIME_TAG)) { // Id tag if (!token_to_uint(json_buffer, (current_token+1), time)) { return true; } } // else - ignore this key. current_token_index += 2; current_token += 2; } return ret; }
bool parse_alarms_internal(Vector<jsmntok_t>& tokens_vector, const char* json_buffer, Vector<SensorPtr>& sensors) { int alarm_token_index, current_token_index, alarm_index; jsmntok_t* tokens = &tokens_vector[0]; if (sensors.empty()) return true; alarm_token_index = find_json_array_token(tokens_vector, json_buffer, ALARM_TAG); if (alarm_token_index < 0) { // No alarms, should not be a problem. return true; } if(tokens[alarm_token_index].type != JSMN_ARRAY) return false; // Build sensor hash table - port_index to sensor; unsigned int max_port_index = 0; const unsigned int number_of_sensors = sensors.size(); for (unsigned int sensor_index = 0 ; sensor_index < number_of_sensors ; sensor_index++) { SensorPtr sensor = sensors[sensor_index]; if (sensor->port_index < 0) return false; // invalid if (sensor->port_index > max_port_index) max_port_index = sensor->port_index; } SensorPtr* sensors_hash = new SensorPtr[max_port_index + 1]; for (unsigned int sensor_index = 0 ; sensor_index < number_of_sensors ; sensor_index++) { sensors_hash[sensors[sensor_index]->port_index] = sensors[sensor_index]; } // iterate of all tokens, try to build alarms for (current_token_index = alarm_token_index + 1, alarm_index = 0; alarm_index < tokens[alarm_token_index].size; alarm_index++ ) { int port_index = -1; double alarm_value = -9999; Alarm::AlarmType alarm_type = Alarm::INVALID; const size_t number_of_object_tokens = tokens[current_token_index].size; const size_t next_alarm_token_index = current_token_index + number_of_object_tokens; // We're expecting something like - {"port_index":1,"alarm_value":5.0,"condition_type":"greater_than"} if (tokens[current_token_index].type != JSMN_OBJECT || number_of_object_tokens < 6) { current_token_index = next_alarm_token_index; continue; // TODO - add logs } current_token_index++; // First token is the key, the second is the value while (current_token_index < next_alarm_token_index) { const unsigned int next_object_token_index = current_token_index + tokens[current_token_index].size + 1; if (tokens[current_token_index].type != JSMN_STRING) {// Must be an error... current_token_index = next_object_token_index; continue; } if (tokens[current_token_index + 1].type != JSMN_PRIMITIVE && tokens[current_token_index + 1].type != JSMN_STRING) {// Must be an error... current_token_index = next_object_token_index; continue; } if (TOKEN_STRING(json_buffer, tokens[current_token_index], ALARM_VALUE_TAG)) { // alarm value tag if (!token_to_double(json_buffer, &tokens[current_token_index + 1], alarm_value)) { current_token_index = next_alarm_token_index; break; } } else if (TOKEN_STRING(json_buffer, tokens[current_token_index], PORT_INDEX_TAG)) { // Port index tag if (!token_to_int(json_buffer, &tokens[current_token_index + 1], port_index)) { current_token_index = next_alarm_token_index; break; } } else if (TOKEN_STRING(json_buffer, tokens[current_token_index], CONDITION_TYPE_TAG)) { // Condition type tag if (!token_to_alarm_type(json_buffer, &tokens[current_token_index + 1], alarm_type)) { current_token_index = next_alarm_token_index; break; } } // else - ignore this key. current_token_index += 2; } if (port_index >= 0 && alarm_type != Alarm::INVALID && alarm_value != -9999 && port_index <= max_port_index) { // Add alarm AlarmPtr alarm(new Alarm(alarm_value, alarm_type)); SensorPtr s = sensors_hash[port_index]; if(s.get()!=NULL) s->alarms.Add(alarm); } } delete[](sensors_hash); return true; }
bool parse_sensors_internal(Vector<jsmntok_t>& tokens_vector, const char* json_buffer, Vector<SensorPtr>& sensors) { int sensors_array_token_index, current_token_index, sensor_index; jsmntok_t* tokens = &tokens_vector[0]; // Find sensors array token: sensors_array_token_index = find_json_array_token(tokens_vector, json_buffer, SENSORS_TAG); if (sensors_array_token_index < 0) { return false; } current_token_index = sensors_array_token_index + 1; // iterate of all tokens, try to build sensors for (sensor_index = 0 ; sensor_index < tokens[sensors_array_token_index].size; sensor_index++) { int id = -1, port_index = -1, value; double sensor_value = 0; SensorType mode = MOCK; const unsigned int next_sensor_token_index = current_token_index + tokens[current_token_index].size + 1; // We're expecting something like - {"id":4,"port_index":6, "type":"water_meter", "value":8.0} if (tokens[current_token_index].type != JSMN_OBJECT || tokens[current_token_index].size < 4) { current_token_index = next_sensor_token_index; continue; } current_token_index++; // First token is the key, the second is the value while (current_token_index < next_sensor_token_index) { const unsigned int next_object_token_index = current_token_index + tokens[current_token_index].size + 1; if (tokens[current_token_index].type != JSMN_STRING) { // Must be an error... current_token_index = next_object_token_index; continue; } if (tokens[current_token_index + 1].type == JSMN_STRING) { // probably type if (TOKEN_STRING(json_buffer, tokens[current_token_index], SENSOR_TYPE_TAG)) { if (TOKEN_STRING(json_buffer, tokens[current_token_index + 1], SENSOR_TYPE_WATER)) { mode = WATER_READER; } else if (TOKEN_STRING(json_buffer, tokens[current_token_index + 1], SENSOR_TYPE_BATTERY)) { mode = BATTERY; } // TODO - add other sensor types. // TODO - what to do in case of an error? - currently ignore. } // else - ignore this key. } else if (tokens[current_token_index + 1].type == JSMN_PRIMITIVE) { // Read the value if (TOKEN_STRING(json_buffer, tokens[current_token_index], VALUE_TAG)) { // Value tag if (!token_to_double(json_buffer, &tokens[current_token_index + 1], sensor_value)) { current_token_index = next_object_token_index; continue; } } if (!token_to_int(json_buffer, &tokens[current_token_index + 1], value)) { current_token_index = next_object_token_index; continue; } if (TOKEN_STRING(json_buffer, tokens[current_token_index], ID_TAG)) { // Id tag id = value; } else if (TOKEN_STRING(json_buffer, tokens[current_token_index], PORT_INDEX_TAG)) { // Port index tag port_index = value; } // else - ignore this key. } current_token_index += 2; } if (id >= 0 && port_index >= 0) { // Add sensor SensorPtr sensor(SensorFactory::CreateSensor(mode, id, port_index, sensor_value)); sensors.Add(sensor); } } return true; }
bool parse_irrigations(const char* json_buffer, Vector<Irrigation>& irrigations) { Vector<jsmntok_t> tokens; jsmntok_t* current_token; size_t number_of_tokens; int current_token_index; int irrigation_index; Parser parser; // Parse json string if (parser.Parse(json_buffer, tokens) != JSON::JSMN_SUCCESS) { Logger::AddLine("json_parse_irrigations: Could not parse json.", Logger::ERROR); return false; } // expected json : [{"start_time":1350339360,"valf_id":4,"irrigation_mode":"time","amount":2}] current_token = &tokens[0]; number_of_tokens = current_token->size; if (current_token->type != JSMN_ARRAY) { Logger::AddLine("json_parse_irrigations: Could not parse json.", Logger::ERROR); return false; } current_token++; current_token_index = 1; // iterate of all tokens, try to build valves for (irrigation_index = 0 ; irrigation_index < number_of_tokens; irrigation_index++) { const int next_irrigation_token_index = current_token_index+current_token->size; int number_of_processed_tokens = 0; size_t start_time=0; int valf_id=-1; Irrigation::IrrigationModes mode = Irrigation::TIME; size_t amount = 0; if(current_token->type != JSMN_OBJECT ) { // Not an object, skip to the next token. current_token += current_token->size + 1; continue; } current_token_index++; current_token++; while(current_token_index < next_irrigation_token_index) { const int next_object_token = current_token_index + current_token->size+1; if (current_token->type != JSMN_STRING) {// Must be an error... current_token_index = next_object_token; current_token = &tokens[current_token_index]; continue; } if ((current_token+1)->type == JSMN_PRIMITIVE) { size_t value; // Read the value if (!token_to_uint(json_buffer, current_token+1, value)) { // Error current_token_index = next_object_token; current_token = &tokens[current_token_index]; continue; } if (TOKEN_STRING(json_buffer, *current_token, START_TIME_TAG)) { start_time = value; number_of_processed_tokens++; } else if (TOKEN_STRING(json_buffer, *current_token, VALF_ID_TAG)) { valf_id = (int)value; number_of_processed_tokens++; } else if (TOKEN_STRING(json_buffer, *current_token, AMOUNT_TAG)) { amount = value; number_of_processed_tokens++; } // else - ignore this key. } else if ((current_token+1)->type == JSMN_STRING) { if (TOKEN_STRING(json_buffer, *current_token, IRRIGATION_MODE_TAG)) { if (TOKEN_STRING(json_buffer, *(current_token+1), IRRIGATION_MODE_TIME)) { mode = Irrigation::TIME; number_of_processed_tokens++; } else if (TOKEN_STRING(json_buffer, *(current_token+1), IRRIGATION_MODE_VOLUME)) { mode = Irrigation::VOLUME; number_of_processed_tokens++; } // TODO - what to do in case of an error? - currently ignore. } // else - ignore this key. } else { // Error current_token_index = next_object_token; current_token = &tokens[current_token_index]; continue; } current_token_index += 2; current_token += 2; } if(number_of_processed_tokens >= 4) { // Create valf Irrigation i; i.amount = amount; i.mode = mode; i.start_time = start_time; i.valf_id = valf_id; irrigations.Add(i); } } return true; }
bool parse_valves(const char* json_buffer, Vector<ValfPtr>& valves) { Vector<jsmntok_t> tokens; jsmntok_t* current_token; size_t number_of_tokens; int current_token_index; int valf_index; Parser parser; // Parse json string if (parser.Parse(json_buffer, tokens) != JSON::JSMN_SUCCESS) { Logger::AddLine("json_parse_valves: Could not parse json.", Logger::ERROR); return false; } // expected json : [{"id":4,"port_index":1},{"id":6,"port_index":2},{"id":5,"port_index":4}] current_token = &tokens[0]; number_of_tokens = current_token->size; if (number_of_tokens <= 0 || current_token->type != JSMN_ARRAY) { Logger::AddLine("json_parse_valves: Could not parse json.", Logger::ERROR); return false; } current_token++; current_token_index = 1; // iterate of all tokens, try to build valves for (valf_index = 0 ; valf_index < number_of_tokens; valf_index++) { const int next_valf_token_index = current_token_index+current_token->size; int port_index =-1, id=-1, value; if(current_token->type != JSMN_OBJECT ) { current_token += current_token->size + 1; continue; } current_token_index++; current_token++; while(current_token_index < next_valf_token_index) { const int next_object_token = current_token_index + current_token->size+1; if (current_token->type != JSMN_STRING) {// Must be an error... current_token_index = next_object_token; current_token = &tokens[current_token_index]; continue; } if ((current_token+1)->type != JSMN_PRIMITIVE) {// Must be an error... current_token_index = next_object_token; current_token = &tokens[current_token_index]; continue; } // Read the value if (!token_to_int(json_buffer, current_token+1, value)) { current_token_index = next_object_token; current_token = &tokens[current_token_index]; continue; } if (TOKEN_STRING(json_buffer, *current_token, ID_TAG)) { // Id tag id = value; } else if (TOKEN_STRING(json_buffer, *current_token, PORT_INDEX_TAG)) { // Port index tag port_index = value; } // else - ignore this key. current_token_index += 2; current_token += 2; } if(id>=0 && port_index>=0) { // Create valf ValfPtr v(new Valf(id, port_index)); valves.Add(v); } } return true; }
bool json_parse_valves(const char* json_buffer, ListElement* valves) { TokenVector *tokens = token_vector_new(); jsmntok_t* current_token; size_t number_of_tokens; int current_token_index; int valf_index; // Parse json string if (!json_parse(json_buffer, tokens)) { add_to_log("json_parse_valves: Could not parse json.", ERROR); token_vector_destroy(tokens); return false; } // expected json : [{"id":4,"port_index":1},{"id":6,"port_index":2},{"id":5,"port_index":4}] current_token = token_vector_get_pointer(tokens, 0); number_of_tokens = current_token->size; if (number_of_tokens <= 0 || current_token->type != JSMN_ARRAY) { add_to_log("json_parse_valves: Could not parse json.", ERROR); token_vector_destroy(tokens); return false; } current_token++; current_token_index = 1; // iterate of all tokens, try to build valves for (valf_index = 0 ; valf_index < number_of_tokens; valf_index++) { const int next_valf_token_index = current_token_index+current_token->size; int port_index =-1, id=-1, value; if(current_token->type != JSMN_OBJECT ) { current_token += current_token->size + 1; continue; } current_token_index++; current_token++; while(current_token_index < next_valf_token_index) { const int next_object_token = current_token_index + current_token->size+1; if (current_token->type != JSMN_STRING) {// Must be an error... current_token_index = next_object_token; current_token = token_vector_get_pointer(tokens, current_token_index); continue; } if ((current_token+1)->type != JSMN_PRIMITIVE) {// Must be an error... current_token_index = next_object_token; current_token = token_vector_get_pointer(tokens, current_token_index); continue; } // Read the value if (!token_to_int(json_buffer, current_token+1, &value)) { current_token_index = next_object_token; current_token = token_vector_get_pointer(tokens, current_token_index); continue; } if (TOKEN_STRING(json_buffer, *current_token, ID_TAG)) { // Id tag id = value; } else if (TOKEN_STRING(json_buffer, *current_token, PORT_INDEX_TAG)) { // Port index tag port_index = value; } // else - ignore this key. current_token_index += 2; current_token += 2; } if(id>=0 && port_index>=0) { // Create valf Valf* v = valf_create(id, port_index); list_add(valves, v); } } token_vector_destroy(tokens); return true; }
bool json_parse_irrigations(const char* json_buffer, ListElement* irrigations) { TokenVector *tokens = token_vector_new(); jsmntok_t* current_token; size_t number_of_tokens; int current_token_index; int irrigation_index; // Parse json string if (!json_parse(json_buffer, tokens)) { add_to_log("json_parse_irrigations: Could not parse json.", ERROR); token_vector_destroy(tokens); return false; } // expected json : [{"start_time":1350339360,"valf_id":4,"irrigation_mode":"time","amount":2}] current_token = token_vector_get_pointer(tokens, 0); number_of_tokens = current_token->size; if (number_of_tokens <= 0 || current_token->type != JSMN_ARRAY) { add_to_log("json_parse_irrigations: Could not parse json.", ERROR); token_vector_destroy(tokens); return false; } current_token++; current_token_index = 1; // iterate of all tokens, try to build valves for (irrigation_index = 0 ; irrigation_index < number_of_tokens; irrigation_index++) { const int next_irrigation_token_index = current_token_index+current_token->size; int number_of_processed_tokens = 0; time_t start_time=0; int valf_id=-1; enum IrrigationModes mode = TIME; size_t amount; if(current_token->type != JSMN_OBJECT ) { // Not an object, skip to the next token. current_token += current_token->size + 1; continue; } current_token_index++; current_token++; while(current_token_index < next_irrigation_token_index) { const int next_object_token = current_token_index + current_token->size+1; if (current_token->type != JSMN_STRING) {// Must be an error... current_token_index = next_object_token; current_token = token_vector_get_pointer(tokens, current_token_index); continue; } if ((current_token+1)->type == JSMN_PRIMITIVE) { int value; // Read the value if (!token_to_int(json_buffer, current_token+1, &value)) { // Error current_token_index = next_object_token; current_token = token_vector_get_pointer(tokens, current_token_index); continue; } if (TOKEN_STRING(json_buffer, *current_token, START_TIME_TAG)) { start_time = value; number_of_processed_tokens++; } else if (TOKEN_STRING(json_buffer, *current_token, VALF_ID_TAG)) { valf_id = value; number_of_processed_tokens++; } else if (TOKEN_STRING(json_buffer, *current_token, AMOUNT_TAG)) { amount = value; number_of_processed_tokens++; } // else - ignore this key. } else if ((current_token+1)->type == JSMN_STRING) { if (TOKEN_STRING(json_buffer, *current_token, IRRIGATION_MODE_TAG)) { if (TOKEN_STRING(json_buffer, *(current_token+1), IRRIGATION_MODE_TIME)) { mode = TIME; number_of_processed_tokens++; } else if (TOKEN_STRING(json_buffer, *(current_token+1), IRRIGATION_MODE_VOLUME)) { mode = VOLUME; number_of_processed_tokens++; } // TODO - what to do in case of an error? - currently ignore. } // else - ignore this key. } else { // Error current_token_index = next_object_token; current_token = token_vector_get_pointer(tokens, current_token_index); continue; } current_token_index += 2; current_token += 2; } if(number_of_processed_tokens >= 4) { // Create valf Irrigation* i = irrigation_create(); i->amount = amount; i->mode = mode; i->start_time = start_time; i->valf_id = valf_id; list_add(irrigations, i); } } token_vector_destroy(tokens); return true; }
bool json_parse_sensors_internal(TokenVector* tokens_vector, const char* json_buffer, ListElement* sensors) { int sensors_array_token_index, current_token_index, sensor_index; jsmntok_t* tokens = token_vector_get_pointer(tokens_vector, 0); // Find sensors array token: sensors_array_token_index = find_json_array_token(tokens_vector, json_buffer, SENSORS_TAG); if (sensors_array_token_index < 0) { return false; } current_token_index = sensors_array_token_index + 1; // iterate of all tokens, try to build sensors for (sensor_index = 0 ; sensor_index < tokens[sensors_array_token_index].size; sensor_index++) { int id = -1, port_index = -1, value; const unsigned int next_sensor_token_index = current_token_index + tokens[current_token_index].size + 1; // We're expecting something like - {"id":4,"port_index":6} if (tokens[current_token_index].type != JSMN_OBJECT || tokens[current_token_index].size < 4) { current_token_index = next_sensor_token_index; continue; } current_token_index++; // First token is the key, the second is the value while (current_token_index < next_sensor_token_index) { const unsigned int next_object_token_index = current_token_index + tokens[current_token_index].size + 1; if (tokens[current_token_index].type != JSMN_STRING) { // Must be an error... current_token_index = next_object_token_index; continue; } if (tokens[current_token_index + 1].type != JSMN_PRIMITIVE) { // Must be an error... current_token_index = next_object_token_index; continue; } // Read the value if (!token_to_int(json_buffer, &tokens[current_token_index + 1], &value)) { current_token_index = next_object_token_index; continue; } if (TOKEN_STRING(json_buffer, tokens[current_token_index], ID_TAG)) { // Id tag id = value; } else if (TOKEN_STRING(json_buffer, tokens[current_token_index], PORT_INDEX_TAG)) { // Port index tag port_index = value; } // else - ignore this key. current_token_index += 2; } if (id >= 0 && port_index >= 0) { // Add sensor Sensor* sensor = sensor_create(); sensor->id = id; sensor->port_index = port_index; list_add(sensors, sensor); } } return true; }
bool json_parse_alarms_internal(TokenVector* tokens_vector, const char* json_buffer, ListElement* sensors) { int max_port_index = 0; int alarm_token_index, current_token_index, alarm_index; Sensor** sensors_hash; ListElement* root_sensors; int sensor_index; jsmntok_t* tokens = token_vector_get_pointer(tokens_vector, 0); if (list_empty(sensors)) return true; alarm_token_index = find_json_array_token(tokens_vector, json_buffer, ALARM_TAG); if (alarm_token_index < 0) { // No alarms, should not be a problem. return true; } if(tokens[alarm_token_index].type != JSMN_ARRAY) return false; // Build sensor hash table - port_index to sensor; for (root_sensors = sensors->next; root_sensors != NULL; root_sensors = root_sensors->next) { Sensor* sensor = (Sensor*)root_sensors->node; if (sensor->port_index < 0) return false; // invalid if (sensor->port_index > max_port_index) max_port_index = sensor->port_index; } sensors_hash = (Sensor**) calloc(sizeof (Sensor*), max_port_index + 1); for (sensor_index = 0; sensor_index <= max_port_index; sensor_index++) // Zero all pointers, could be memset. sensors_hash[sensor_index] = NULL; for (root_sensors = sensors->next; root_sensors != NULL; root_sensors = root_sensors->next) { Sensor* sensor = (Sensor*)root_sensors->node; sensors_hash[sensor->port_index] = sensor; } // iterate of all tokens, try to build alarms for (current_token_index = alarm_token_index + 1, alarm_index = 0; alarm_index < tokens[alarm_token_index].size; alarm_index++ ) { int port_index = -1; double alarm_value = -9999; enum AlarmType alarm_type = INVALID; const size_t number_of_object_tokens = tokens[current_token_index].size; const size_t next_alarm_token_index = current_token_index + number_of_object_tokens; // We're expecting something like - {"port_index":1,"alarm_value":5.0,"condition_type":"greater_than"} if (tokens[current_token_index].type != JSMN_OBJECT || number_of_object_tokens < 6) { current_token_index = next_alarm_token_index; continue; // TODO - add logs } current_token_index++; // First token is the key, the second is the value while (current_token_index < next_alarm_token_index) { const unsigned int next_object_token_index = current_token_index + tokens[current_token_index].size + 1; if (tokens[current_token_index].type != JSMN_STRING) {// Must be an error... current_token_index = next_object_token_index; continue; } if (tokens[current_token_index + 1].type != JSMN_PRIMITIVE && tokens[current_token_index + 1].type != JSMN_STRING) {// Must be an error... current_token_index = next_object_token_index; continue; } if (TOKEN_STRING(json_buffer, tokens[current_token_index], ALARM_VALUE_TAG)) { // alarm value tag if (!token_to_double(json_buffer, &tokens[current_token_index + 1], &alarm_value)) { current_token_index = next_alarm_token_index; break; } } else if (TOKEN_STRING(json_buffer, tokens[current_token_index], PORT_INDEX_TAG)) { // Port index tag if (!token_to_int(json_buffer, &tokens[current_token_index + 1], &port_index)) { current_token_index = next_alarm_token_index; break; } } else if (TOKEN_STRING(json_buffer, tokens[current_token_index], CONDITION_TYPE_TAG)) { // Condition type tag if (!token_to_alarm_type(json_buffer, &tokens[current_token_index + 1], &alarm_type)) { current_token_index = next_alarm_token_index; break; } } // else - ignore this key. current_token_index += 2; } if (port_index >= 0 && alarm_type != INVALID && alarm_value != -9999 && port_index <= max_port_index) { // Add alarm Alarm* alarm = alarm_create(alarm_value, alarm_type); Sensor* s = sensors_hash[port_index]; if(s!=NULL) list_add(s->alarms, (void*)alarm); else alarm_delete(alarm); } } free(sensors_hash); return true; }