Simple JSON parser in C

29. Juli 2017 at 09:57
Print Friendly, PDF & Email

Die Verwendung von ArduinoJSON führte bei mir zu Problemen mit dem Speicher auf dem Arduino.
Da mein JSON string relativ einfach ist, verwende ich eine einfache Funktion in C.

Verwendung siehe hier: http://www.hoeser-medien.de/2017/07/openhab-433-mhz-sender-mit-json-format-ueber-mqtt-anbinden/

Input: {„code“:“00001″ , „device“ : „01000“, „state“:0}

Update 2.Aug.2017: Mein Sohn Raphael hat den code verbessert und kommentiert

code

 
bool json_lookup_char ( const char* cSource, const char* cToken, char cReply[]){
char *ptr;
ptr = strstr (cSource, cToken); // set pointer to 1st char in cSource matching token
if(!ptr){
Serial.print(" json_lookup_char > ");
Serial.print(cToken);
Serial.println("< not found");
return false;
}
ptr = strstr (ptr, ":"); // set pointer to :
if(!ptr){
Serial.print(" json_lookup_char > : < not found");
return false;
}
// move pointer past colon
ptr++;
// interleaving value string depth (first quotation mark hast to be first char of value)
int quotMarkDepth = 0;
// quotation mark of current depth (initialize with \0, because we'll set it later)
char lastQuotMark = '\0';
// discard all spaces incipient to the value and set the first quot mark if necessary
for(;(*ptr == ' ' || *ptr == '"' || *ptr == '\'' || *ptr == '\t') && !quotMarkDepth; ptr++){
if(*ptr == '"' || *ptr == '\''){
lastQuotMark = *ptr;
++quotMarkDepth;
}
} // for
for (int i=0, x=0;i<MAX_TOKEN_STRING+1;i++, ptr++){
switch(*ptr){
// stop at end of String, or end of value/object
case '\0':
case '}':
case ',':
// value ended -> leave parsing
i = MAX_TOKEN_STRING+1;
break;
// handle interleaving strings
case '\'':
case '"':
// Was value not wrapped in quotation marks?
if(lastQuotMark == '\0'){
cReply[x ] = *ptr; // copy quotation mark to target
x++;
}
else{
// close last String layer?
if(*ptr == lastQuotMark){
// set lastQuotMark to the opposite
lastQuotMark = lastQuotMark == '"' ? '\'' : '"';
// decrease depth
--quotMarkDepth;
// was interleaving string?
if(quotMarkDepth){
cReply[x ] = *ptr; // copy quotation mark to target
x++;
}
else{
// value ended -> leave parsing
i = MAX_TOKEN_STRING+1;
}
}
else{
// open new String Layer
// set last quotation mark
lastQuotMark = *ptr;
// increase depth
++quotMarkDepth;
}
}
break;
// copy src char to target
default:
cReply[x ] = *ptr; // copy single char to target
x++;
} // switch
cReply[x] = '\0'; // terminate String
} // for
return true;
}