Line data Source code
1 : #include "SLIPParser.hpp" 2 : 3 : template <class Callback> 4 284 : size_t SLIPParser::parse(uint8_t c, Callback callback) { 5 : using namespace SLIP_Constants; 6 : /* 7 : * handle bytestuffing if necessary 8 : */ 9 284 : switch (c) { 10 : /* 11 : * if it's an END character then we're done with 12 : * the packet 13 : */ 14 : case END: { 15 : /* 16 : * a minor optimization: if there is no 17 : * data in the packet, ignore it. This is 18 : * meant to avoid bothering IP with all 19 : * the empty packets generated by the 20 : * duplicate END characters which are in 21 : * turn sent to try to detect line noise. 22 : */ 23 30 : auto packetLen = write - buffer; 24 30 : escape = false; 25 30 : reset(); 26 30 : if (packetLen) 27 15 : return packetLen; 28 30 : } break; 29 : 30 : /* 31 : * if it's the same code as an ESC character, wait 32 : * and get another character and then figure out 33 : * what to store in the packet based on that. 34 : */ 35 : case ESC: { 36 38 : escape = true; 37 38 : } break; 38 : 39 : /* 40 : * here we fall into the default handler and let 41 : * it store the character for us 42 : */ 43 : default: { 44 216 : if (escape) { 45 : /* 46 : * if "c" is not one of these two, then we 47 : * have a protocol violation. The best bet 48 : * seems to be to leave the byte alone and 49 : * just stuff it into the packet 50 : */ 51 38 : switch (c) { 52 20 : case ESC_END: c = END; break; 53 18 : case ESC_ESC: c = ESC; break; 54 : default: break; // LCOV_EXCL_LINE (protocol violation) 55 : } 56 38 : escape = false; 57 38 : } 58 432 : auto writeSize = reinterpret_cast<uintptr_t>(write) - 59 216 : reinterpret_cast<uintptr_t>(buffer); 60 216 : callback(c, writeSize + truncated); 61 216 : if (writeSize == 0) // first byte of packet 62 15 : truncated = 0; 63 216 : if (writeSize < bufferSize) { 64 205 : *write++ = c; 65 205 : } else { 66 11 : truncated++; 67 : } 68 216 : } 69 216 : } 70 269 : return 0; 71 284 : }