//this function is a state machine that processes the tweet search json one byte at a time. It works ont he global searchParser structure //it looks for a tag, and then grabs the tag value into a buffer. //does OK with escape, removes XMLentities from the text completely, this could be improved. unsigned char tagSearch(unsigned char inBuf, struct _jsonParser *P ){ #define SEARCHING_FOR_TAG 0 #define GRABBING_TAG 1 switch(P->foundTag){ case SEARCHING_FOR_TAG://search for tag //compare current byte to next byte in tag //if no match, need to check one more time to see if the beginning of a new sequence if( (P->tagCharMatchCnt==0) || (inBuf!=P->searchTag[P->tagCharMatchCnt]) ){ P->tagCharMatchCnt=0; //no match, reset if(inBuf!=P->searchTag[0]) break; //no match, break } P->tagCharMatchCnt++; //match, increment counter if(P->tagCharMatchCnt==P->searchTagLength){//whole tag matches P->tagCharMatchCnt=0; //reset the match counter P->foundTag=GRABBING_TAG; P->xmlencode=0; P->escape=0; P->UTF=0; P->valueBufferCounter=0; } break; case GRABBING_TAG://tag found, get value //discard UTF characters, could decode and do a few umlouts and other international characters the LCD can display if(P->UTF>0){//ignore UTF8 characters (LCD can't display, PIC char can't handle) P->UTF--; break; } if(P->xmlencode==1){ //already saw &, suck down the code if(inBuf==';'){//; is end of code, process and clean up P->xmlencode=0; //done grabbing encoded character inBuf=XMLdecode(P->xmlenchar[0], P->xmlenchar[1]); //decode it, reuse inBuf character if(inBuf!=0){//if 0, error, just skip it, else add to valueBuffer addValueByte(inBuf, P);//add character to the value buffer } break; }else{ //if not end of xmlencode, get another character if(P->xmlencharcnt<2){ //we only need the first 2 character to identify the ecoding P->xmlenchar[P->xmlencharcnt]=inBuf; } P->xmlencharcnt++; if(P->xmlencharcnt>5){//quit if it goes over the max of 5 characters P->xmlencode=0; //quit encoding, there was an error, resume normal on next character } break; //don't save byte } } if(P->escape==1){ //ESCAPED, check for /\" and UTF8 P->escape=0; //clear escape if(inBuf=='u' || inBuf=='U'){//only escape /\", add a \ back to buffer otherwise P->UTF=4; //next 4 bytes are UFT encoded characters, ignore break; }else if(inBuf=='n' || inBuf=='N'){ //\n is line break, ignore.... break; } }else{ //NOT ESCAPED, check for end and escape if(inBuf==P->valueEndChar){ //end on value end character P->foundTag=SEARCHING_FOR_TAG; return 1; //tag complete //break; }else if(inBuf==0x5c){ //if this is escape char and escape not set, then set escape and break (0x5c= '\') P->escape=1; break; }else if(inBuf=='&'){ //begin XML encoded character P->xmlencode=1; //set flag P->xmlencharcnt=0; //clear encoded character counter break; //don't save this character } } if(inBuf>=0x20 && inBuf<=0x7e){//only allow standard ASCII characters, otherwise ignore addValueByte(inBuf, P);//add character to the value buffer } break; } return 0; //tag not complete
//this function is a state machine that processes the tweet search json one byte at a time. It works ont he global searchParser structure //it looks for a tag, and then grabs the tag value into a buffer. //does OK with escape, removes XMLentities from the text completely, this could be improved. void procSearch(unsigned char inBuf){ switch(searchParser.foundTag){ case 0://search for tag //compare current byte to next byte in tag //if no match, need to check one more time to see if the beginning of a new sequence if( (searchParser.tagCharMatchCnt==0) || (inBuf!=jsonSearchTag[searchParser.tagCharMatchCnt]) ){ searchParser.tagCharMatchCnt=0; //no match, reset #if defined(__18CXX)//there's something about the C18 compiler that wants this or the next instruction is always false.. Nop(); #endif if(inBuf!=jsonSearchTag[0]) break; //no match, break } searchParser.tagCharMatchCnt++; //match, increment counter if(searchParser.tagCharMatchCnt==(sizeof(jsonSearchTag)-1)){//whole tag matches searchParser.tagCharMatchCnt=0; //reset the match counter searchParser.tagTotalCnt++; //increment the total tag counter searchParser.foundTag=1; searchParser.xmlencode=0; searchParser.escape=0; searchParser.UTF=0; addToSearchBuffer(' '); } break; case 1://tag found, get value //discard UTF characters, could decode and do a few umlouts and other international characters the LCD can display if(searchParser.UTF>0){//ignore UTF8 characters (LCD can't display, PIC char can't handle) searchParser.UTF--; break; } if(searchParser.xmlencode==1){ //already saw &, suck down the code if(inBuf==';'){//; is end of code, process and clean up searchParser.xmlencode=0; //done grabbing encoded character inBuf=XMLdecode(searchParser.xmlenchar[0], searchParser.xmlenchar[1]); //decode it, reuse inBuf character if(inBuf!=0) addToSearchBuffer(inBuf); //if 0, error, just skip it, else add to searchBuffer break; }else{ //if not end of xmlencode, get another character if(searchParser.xmlencharcnt<2){ //we only need the first 2 character to identify the ecoding searchParser.xmlenchar[searchParser.xmlencharcnt]=inBuf; } searchParser.xmlencharcnt++; if(searchParser.xmlencharcnt>5){//quit if it goes over the max of 5 characters searchParser.xmlencode=0; //quit encoding, there was an error, resume normal on next character } break; //don't save byte } } if(searchParser.escape==1){ //ESCAPED, check for /\" and UTF8 searchParser.escape=0; //clear escape if(inBuf=='u' || inBuf=='U'){//only escape /\", add a \ back to buffer otherwise searchParser.UTF=4; //next 4 bytes are UFT encoded characters, ignore break; }else if(inBuf=='n' || inBuf=='N'){ //\n is line break, ignore.... break; } //don't need this, escape character is always escaped //else if(!(inBuf=='/' || inBuf==0x5c || inBuf=='"')){//only escape /\", add a \ back to buffer otherwise // addToSearchBuffer('|'); //continue as normal, add current byte to searchbuffer at the end... //} }else{ //NOT ESCAPED, check for end and escape if(inBuf=='"'){ //end on " if not escaped //add block between entries addToSearchBuffer(' '); addToSearchBuffer(0xff); searchParser.foundTag=0; break; }else if(inBuf==0x5c){ //if this is escape char and escape not set, then set escape and break (0x5c= '\') searchParser.escape=1; break; }else if(inBuf=='&'){ //begin XML encoded character searchParser.xmlencode=1; //set flag searchParser.xmlencharcnt=0; //clear encoded character counter break; //don't save this character } } if(inBuf>=0x20 && inBuf<=0x7e){//only allow standard ASCII characters, otherwise ignore if(inBuf==0x5c) inBuf='|'; //LCD has no '\', use | if(inBuf=='~') inBuf='-'; //LCD has no "~", use - addToSearchBuffer(inBuf); //add character to output buffer } break; } }