statemachines.C 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * statemachines.C
  3. *
  4. * Created on: Jan 31, 2013
  5. * Author: xaxaxa
  6. */
  7. /*
  8. This program is free software: you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation, either version 3 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. * */
  19. //state machines for asynchronously processing input streams
  20. #include <tuple>
  21. #include <functional>
  22. #include <stdint.h>
  23. #include <tuple>
  24. #include <string>
  25. #include <string.h>
  26. #include "include/statemachines.H"
  27. #include <stdio.h>
  28. using namespace std;
  29. namespace CP
  30. {
  31. void* memcpymove(uint8_t* dst, const uint8_t* src, size_t n) {
  32. if ((dst >= src + n) || (src >= dst + n)) {
  33. //not overlapping
  34. return memcpy(dst, src, n);
  35. } else return memmove(dst, src, n);
  36. }
  37. struct streamReader
  38. {
  39. //you must allocate memory for this struct such that there is (bufferSize) bytes of allocated space
  40. //right after this struct.
  41. //ex.
  42. //streamReader* sr=(streamReader*)malloc(sizeof(streamReader)+4096);
  43. //new (sr) streamReader(4096);
  44. //user specified
  45. // data len delimReached
  46. Delegate<void(uint8_t*, int, bool)> output;
  47. void* buffer;
  48. int bufferCapacity;
  49. //internal
  50. int bufferLen;
  51. int bufferPos;
  52. int state; //0: none; 1: readUntilString; 2: readUntilChar
  53. const char* delim1;
  54. int delim1len;
  55. char delim2;
  56. //bool delayProcessing;
  57. //bool delayedProcessing;
  58. inline void reset() {
  59. bufferPos = 0;
  60. bufferLen = 0;
  61. state = 0;
  62. //delayProcessing = false;
  63. }
  64. streamReader(void* buffer, int capacity) {
  65. this->buffer = buffer;
  66. bufferCapacity = capacity;
  67. reset();
  68. }
  69. streamReader(int capacity) {
  70. this->buffer = (void*) (this + 1);
  71. bufferCapacity = capacity;
  72. reset();
  73. }
  74. inline uint8_t* getBuffer() {
  75. return (uint8_t*) buffer;
  76. }
  77. inline void setCallback(const Delegate<void(uint8_t*, int, bool)>& cb) {
  78. output = cb;
  79. }
  80. void process() {
  81. /*if (delayProcessing) {
  82. delayedProcessing = true;
  83. return;
  84. }*/
  85. if (bufferPos >= bufferLen) {
  86. bufferPos = bufferLen = 0;
  87. return;
  88. }
  89. switch (state) {
  90. case 0:
  91. break;
  92. case 1:
  93. {
  94. uint8_t* buf = getBuffer();
  95. if (bufferLen - bufferPos < (int) delim1len && bufferPos > 0) {
  96. asdfg: memmove(buf, buf + bufferPos, bufferLen - bufferPos);
  97. bufferLen -= bufferPos;
  98. bufferPos = 0;
  99. return;
  100. }
  101. //printf("%i\n",bufferLen - bufferPos);
  102. uint8_t* tmp = (uint8_t*) memmem(buf + bufferPos, bufferLen - bufferPos, delim1,
  103. delim1len);
  104. if (tmp == NULL) {
  105. //delayProcessing = true;
  106. //if (bufferLen - bufferPos - delim1len + 1 <= 0) break;
  107. output(buf + bufferPos, bufferLen - bufferPos - delim1len + 1, false);
  108. //delayProcessing = false;
  109. //memmove(buf, buf + bufferLen - delim1.length(), delim1.length());
  110. bufferPos = bufferLen - delim1len + 1;
  111. goto asdfg;
  112. } else {
  113. int oldPos = bufferPos;
  114. int newPos = tmp - buf;
  115. bufferPos = newPos + delim1len;
  116. if (bufferPos >= bufferLen) {
  117. bufferLen = bufferPos = 0;
  118. }
  119. state = 0;
  120. output(buf + oldPos, newPos - oldPos, true);
  121. }
  122. break;
  123. }
  124. case 2:
  125. {
  126. uint8_t* buf = getBuffer();
  127. uint8_t* tmp = (uint8_t*) memchr(buf + bufferPos, delim2, bufferLen - bufferPos);
  128. int oldPos = bufferPos;
  129. if (tmp == NULL) {
  130. int oldLen = bufferLen;
  131. bufferLen = bufferPos = 0;
  132. output(buf + oldPos, oldLen - oldPos, false);
  133. } else {
  134. int newPos = tmp - buf;
  135. bufferPos = newPos + 1;
  136. if (bufferPos >= bufferLen) {
  137. bufferLen = bufferPos = 0;
  138. }
  139. state = 0;
  140. output(buf + oldPos, newPos - oldPos, true);
  141. }
  142. break;
  143. }
  144. }
  145. //if (delayedProcessing) goto reprocess;
  146. }
  147. inline void readUntilString(const char* delim, int delimLen) {
  148. state = 1;
  149. delim1 = delim;
  150. delim1len = delimLen;
  151. //printf("%i\n",delim.length());
  152. process();
  153. }
  154. inline void readUntilChar(char delim) {
  155. state = 2;
  156. delim2 = delim;
  157. process();
  158. }
  159. // buf length
  160. inline tuple<uint8_t*, int> beginPutData() {
  161. //printf("%i %i\n",bufferLen, bufferCapacity - bufferLen);
  162. return make_tuple(getBuffer() + bufferLen, bufferCapacity - bufferLen);
  163. }
  164. //len <= length returned from beginPutData()
  165. inline void endPutData(int len) {
  166. //printf("%i\n",len);
  167. bufferLen += len;
  168. if (len > 0) process();
  169. }
  170. inline tuple<uint8_t*, int> getBufferData() {
  171. return make_tuple(getBuffer() + bufferPos, bufferLen - bufferPos);
  172. }
  173. inline void skip(int i) {
  174. bufferPos += i;
  175. }
  176. };
  177. int streamReader_getSize() {
  178. return sizeof(streamReader);
  179. }
  180. void streamReader_init(streamReader* sr, int capacity) {
  181. new (sr) streamReader(capacity);
  182. }
  183. void streamReader_init(streamReader* sr, void* buffer, int capacity) {
  184. new (sr) streamReader(buffer, capacity);
  185. }
  186. void streamReader_deinit(streamReader* sr) {
  187. sr->~streamReader();
  188. }
  189. tuple<uint8_t*, int> streamReader_beginPutData(streamReader* sr) {
  190. return sr->beginPutData();
  191. }
  192. void streamReader_endPutData(streamReader* sr, int len) {
  193. sr->endPutData(len);
  194. }
  195. void streamReader_readUntilString(streamReader* sr, const char* delim, int delimLen) {
  196. sr->readUntilString(delim, delimLen);
  197. }
  198. void streamReader_readUntilChar(streamReader* sr, char delim) {
  199. sr->readUntilChar(delim);
  200. }
  201. void streamReader_setCallback(streamReader* sr, const Delegate<void(uint8_t*, int, bool)>& cb) {
  202. sr->setCallback(cb);
  203. }
  204. tuple<uint8_t*, int> streamReader_getBufferData(streamReader* sr) {
  205. return sr->getBufferData();
  206. }
  207. void streamReader_reset(streamReader* sr) {
  208. sr->reset();
  209. }
  210. void streamReader_skip(streamReader* sr, int i) {
  211. sr->skip(i);
  212. }
  213. }