示例#1
0
void nv_get_nvObj(nvObj_t *nv)
{
	if (nv->index >= nv_index_max()) { return; }	// sanity

	index_t tmp = nv->index;
	nv_reset_nv(nv);
	nv->index = tmp;

	strcpy_P(nv->token, cfgArray[nv->index].token); // token field is always terminated
	strcpy_P(nv->group, cfgArray[nv->index].group); // group field is always terminated

	// special processing for system groups and stripping tokens for groups
	if (nv->group[0] != NUL) {
		if (GET_TABLE_BYTE(flags) & F_NOSTRIP) {
			nv->group[0] = NUL;
		} else {
			strcpy(nv->token, &nv->token[strlen(nv->group)]); // strip group from the token
		}
	}
	((fptrCmd)GET_TABLE_WORD(get))(nv);		// populate the value
}
示例#2
0
static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth)
{
	uint8_t i;
	char *tmp;
	char leaders[] = {"{,\""};      // open curly, quote and leading comma
	char separators[] = {":\""};    // colon and quote
	char terminators[] = {"},\""};  // close curly, comma and quote
	char value[] = {"{\".-+"};      // open curly, quote, period, minus and plus

	nv_reset_nv(nv);                // wipes the object and sets the depth

	// --- Process name part ---
	// Find, terminate and set pointers for the name. Allow for leading and trailing name quotes.
	char * name = *pstr;
	for (i=0; true; i++, (*pstr)++) {
		if (strchr(leaders, (int)**pstr) == NULL) { 		// find leading character of name
			name = (*pstr)++;
			break;
		}
		if (i == MAX_PAD_CHARS) return (STAT_JSON_SYNTAX_ERROR);
	}

	// Find the end of name, NUL terminate and copy token
	for (i=0; true; i++, (*pstr)++) {
		if (strchr(separators, (int)**pstr) != NULL) {
			*(*pstr)++ = NUL;
			strncpy(nv->token, name, TOKEN_LEN+1);			// copy the string to the token
			break;
		}
		if (i == MAX_NAME_CHARS) return (STAT_JSON_SYNTAX_ERROR);
	}

	// --- Process value part ---  (organized from most to least frequently encountered)

	// Find the start of the value part
	for (i=0; true; i++, (*pstr)++) {
		if (isalnum((int)**pstr)) break;
		if (strchr(value, (int)**pstr) != NULL) break;
		if (i == MAX_PAD_CHARS) return (STAT_JSON_SYNTAX_ERROR);
	}

	// nulls (gets)
	if ((**pstr == 'n') || ((**pstr == '\"') && (*(*pstr+1) == '\"'))) { // process null value
		nv->valuetype = TYPE_NULL;
		nv->value = TYPE_NULL;

	// numbers
	} else if (isdigit(**pstr) || (**pstr == '-')) {// value is a number
		nv->value = (float)strtod(*pstr, &tmp);	// tmp is the end pointer
		if(tmp == *pstr) { return (STAT_BAD_NUMBER_FORMAT);}
		nv->valuetype = TYPE_FLOAT;

	// object parent
	} else if (**pstr == '{') {
		nv->valuetype = TYPE_PARENT;
//		*depth += 1;							// nv_reset_nv() sets the next object's level so this is redundant
		(*pstr)++;
		return(STAT_EAGAIN);					// signal that there is more to parse

	// strings
	} else if (**pstr == '\"') { 				// value is a string
		(*pstr)++;
		nv->valuetype = TYPE_STRING;
		if ((tmp = strchr(*pstr, '\"')) == NULL) { return (STAT_JSON_SYNTAX_ERROR);} // find the end of the string
		*tmp = NUL;

		// if string begins with 0x it might be data, needs to be at least 3 chars long
		if( strlen(*pstr)>=3 && (*pstr)[0]=='0' && (*pstr)[1]=='x')
		{
			uint32_t *v = (uint32_t*)&nv->value;
			*v = strtoul((const char *)*pstr, 0L, 0);
			nv->valuetype = TYPE_DATA;
		} else {
			ritorno(nv_copy_string(nv, *pstr));
		}
		*pstr = ++tmp;

	// boolean true/false
	} else if (**pstr == 't') {
		nv->valuetype = TYPE_BOOL;
		nv->value = true;
	} else if (**pstr == 'f') {
		nv->valuetype = TYPE_BOOL;
		nv->value = false;

	// arrays
	} else if (**pstr == '[') {
		nv->valuetype = TYPE_ARRAY;
		ritorno(nv_copy_string(nv, *pstr));		// copy array into string for error displays
		return (STAT_INPUT_VALUE_UNSUPPORTED);	// return error as the parser doesn't do input arrays yet

	// general error condition
	} else { return (STAT_JSON_SYNTAX_ERROR); }	// ill-formed JSON

	// process comma separators and end curlies
	if ((*pstr = strpbrk(*pstr, terminators)) == NULL) { // advance to terminator or err out
		return (STAT_JSON_SYNTAX_ERROR);
	}
	if (**pstr == '}') {
		*depth -= 1;							// pop up a nesting level
		(*pstr)++;								// advance to comma or whatever follows
	}
	if (**pstr == ',') { return (STAT_EAGAIN);}	// signal that there is more to parse

	(*pstr)++;
	return (STAT_OK);							// signal that parsing is complete
}