Permalink
Browse files

last version

  • Loading branch information...
1 parent c9a9d14 commit 2125a0176526301b27440f7ffd676066254fbbc0 @jcw committed Oct 3, 2012
Showing with 114 additions and 26 deletions.
  1. +72 −13 EmBencode.cpp
  2. +10 −9 EmBencode.h
  3. +32 −4 examples/serialReceive/serialReceive.ino
View
@@ -3,16 +3,27 @@
#include "EmBencode.h"
+enum { EMB_ANY, EMB_LEN, EMB_INT, EMB_STR };
+
+uint8_t EmBdecode::reset () {
+ count = next;
+ level = next = 0;
+ state = EMB_ANY;
+ return count;
+}
+
uint8_t EmBdecode::process (char ch) {
- bufPtr[next++] = ch;
switch (state) {
case EMB_ANY:
if (ch < '0' || ch > '9') {
- if (ch == 'i')
+ if (ch == 'i') {
+ AddToBuf(T_NUMBER);
state = EMB_INT;
- else if (ch == 'd' || ch == 'l')
+ } else if (ch == 'd' || ch == 'l') {
+ AddToBuf(ch == 'd' ? T_DICT : T_LIST);
++level;
- else if (ch == 'e') {
+ } else if (ch == 'e') {
+ AddToBuf(T_POP);
--level;
break; // end of dict or list
}
@@ -22,27 +33,75 @@ uint8_t EmBdecode::process (char ch) {
count = 0;
// fall through
case EMB_LEN:
- case EMB_INT:
- if ('0' <= ch && ch <= '9')
- count = 10 * count + (ch - '0');
- else if (ch == '-')
- ;
- else if (state == EMB_LEN) {
- if (count == 0)
+ if (ch == ':') {
+ AddToBuf(T_STRING + count);
+ if (count == 0) {
+ AddToBuf(0);
break; // empty string
+ }
state = EMB_STR;
} else
- break; // end of int
+ count = 10 * count + (ch - '0');
return 0;
case EMB_STR:
- if (--count == 0)
+ AddToBuf(ch);
+ if (--count == 0) {
+ AddToBuf(0);
break; // end of string
+ }
+ return 0;
+ case EMB_INT:
+ if (ch == 'e') {
+ AddToBuf(0);
+ break; // end of int
+ }
+ AddToBuf(ch);
return 0;
}
// end of an item reached
if (level > 0) {
state = EMB_ANY;
return 0;
}
+ AddToBuf(T_END);
return reset(); // not in dict or list, data is complete
}
+
+void EmBdecode::AddToBuf (char ch) {
+ if (next >= bufLen)
+ bufPtr[0] = T_END; // mark entire buffer as empty
+ else
+ bufPtr[next++] = ch;
+}
+
+uint8_t EmBdecode::nextToken () {
+ uint8_t ch = bufPtr[next++];
+ last = next;
+ switch (ch) {
+ default: // string
+ next += ch + 1;
+ return T_STRING;
+ case T_NUMBER:
+ while (bufPtr[next++] != 0)
+ ;
+ break;
+ case T_END:
+ --next; // don't advance past end token
+ // fall through
+ case T_DICT:
+ case T_LIST:
+ case T_POP:
+ break;
+ }
+ return ch;
+}
+
+const char* EmBdecode::asString (uint8_t* plen) {
+ if (plen != 0)
+ *plen = next - last - 1;
+ return bufPtr + last;
+}
+
+long EmBdecode::asNumber () {
+ return atol(bufPtr + last);
+}
View
@@ -65,21 +65,22 @@ class EmBencode {
class EmBdecode {
public:
+ enum { T_STRING = 0, T_NUMBER = 251, T_DICT, T_LIST, T_POP, T_END };
+
EmBdecode (char* buf, uint8_t len)
: bufPtr (buf), bufLen (len) { reset(); }
- uint8_t reset () {
- count = next;
- level = next = 0;
- state = EMB_ANY;
- return count;
- }
+ uint8_t reset ();
uint8_t process (char ch);
+
+ uint8_t nextToken ();
+ const char* asString (uint8_t* plen =0);
+ long asNumber ();
protected:
- enum { EMB_ANY, EMB_LEN, EMB_INT, EMB_STR };
+ void AddToBuf (char ch);
- char level, *bufPtr;
- uint8_t bufLen, count, next, state;
+ char level, *bufPtr;
+ uint8_t bufLen, count, next, last, state;
};
@@ -16,10 +16,38 @@ void setup () {
void loop () {
if (Serial.available() > 0) {
- uint8_t bytes = decode.process(Serial.read());
+ char ch = Serial.read();
+ Serial.write(ch);
+ uint8_t bytes = decode.process(ch);
if (bytes > 0) {
- embuf[bytes] = 0;
- Serial.println(embuf);
+ Serial.print(" => ");
+ Serial.print((int) bytes);
+ Serial.println(" bytes");
+ for (;;) {
+ uint8_t token = decode.nextToken();
+ if (token == EmBdecode::T_END)
+ break;
+ switch (token) {
+ case EmBdecode::T_STRING:
+ Serial.print(" string: ");
+ Serial.println(decode.asString());
+ break;
+ case EmBdecode::T_NUMBER:
+ Serial.print(" number: ");
+ Serial.println(decode.asNumber());
+ break;
+ case EmBdecode::T_DICT:
+ Serial.println(" > dict");
+ break;
+ case EmBdecode::T_LIST:
+ Serial.println(" > list");
+ break;
+ case EmBdecode::T_POP:
+ Serial.println(" < pop");
+ break;
+ }
+ }
+ decode.reset();
}
}
-}
+}

0 comments on commit 2125a01

Please sign in to comment.