OSCMessage.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. /*
  2. Written by Yotam Mann, The Center for New Music and Audio Technologies,
  3. University of California, Berkeley. Copyright (c) 2012, The Regents of
  4. the University of California (Regents).
  5. Permission to use, copy, modify, distribute, and distribute modified versions
  6. of this software and its documentation without fee and without a signed
  7. licensing agreement, is hereby granted, provided that the above copyright
  8. notice, this paragraph and the following two paragraphs appear in all copies,
  9. modifications, and distributions.
  10. IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
  11. SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
  12. OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
  13. BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
  17. HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
  18. MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  19. For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu
  20. */
  21. #include "OSCMessage.h"
  22. #include "OSCMatch.h"
  23. #include "OSCTiming.h"
  24. extern osctime_t zerotime;
  25. /*=============================================================================
  26. CONSTRUCTORS / DESTRUCTOR
  27. =============================================================================*/
  28. //constructor with address
  29. OSCMessage::OSCMessage(const char * _address){
  30. setupMessage();
  31. setAddress(_address);
  32. }
  33. //constructor with nothing
  34. //just a placeholder since the message is invalid
  35. OSCMessage::OSCMessage(){
  36. setupMessage();
  37. error = INVALID_OSC;
  38. }
  39. //variable length constructor
  40. //for example OSCMessage msg("/address", "isf", 1, "two", 3.0);
  41. /*
  42. OSCMessage::OSCMessage(const char * _address, char * types, ... ){
  43. setupMessage(_address);
  44. }
  45. */
  46. //sets up a new message
  47. void OSCMessage::setupMessage(){
  48. address = NULL;
  49. //setup the attributes
  50. dataCount = 0;
  51. error = OSC_OK;
  52. //setup the space for data
  53. data = NULL;
  54. //setup for filling the message
  55. incomingBuffer = NULL;
  56. incomingBufferSize = 0;
  57. incomingBufferFree = 0;
  58. clearIncomingBuffer();
  59. //set the decode state
  60. decodeState = STANDBY;
  61. }
  62. //DESTRUCTOR
  63. OSCMessage::~OSCMessage(){
  64. //free everything that needs to be freed
  65. //free the address
  66. free(address);
  67. //free the data
  68. empty();
  69. //free the filling buffer
  70. free(incomingBuffer);
  71. }
  72. OSCMessage& OSCMessage::empty(){
  73. error = OSC_OK;
  74. //free each of the data in the array
  75. for (int i = 0; i < dataCount; i++){
  76. OSCData * datum = getOSCData(i);
  77. //explicitly destruct the data
  78. //datum->~OSCData();
  79. delete datum;
  80. }
  81. //and free the array
  82. free(data);
  83. data = NULL;
  84. dataCount = 0;
  85. decodeState = STANDBY;
  86. clearIncomingBuffer();
  87. return *this;
  88. }
  89. //COPY
  90. OSCMessage::OSCMessage(OSCMessage * msg){
  91. //start with a message with the same address
  92. setupMessage();
  93. setAddress(msg->address);
  94. //add each of the data to the other message
  95. for (int i = 0; i < msg->dataCount; i++){
  96. add(msg->data[i]);
  97. }
  98. }
  99. /*=============================================================================
  100. GETTING DATA
  101. =============================================================================*/
  102. OSCData * OSCMessage::getOSCData(int position){
  103. if (position < dataCount){
  104. OSCData * datum = data[position];
  105. return datum;
  106. } else {
  107. error = INDEX_OUT_OF_BOUNDS;
  108. return NULL;
  109. }
  110. }
  111. int32_t OSCMessage::getInt(int position){
  112. OSCData * datum = getOSCData(position);
  113. if (!hasError()){
  114. return datum->getInt();
  115. } else {
  116. #ifndef ESPxx
  117. return (int32_t)NULL;
  118. #else
  119. return -1;
  120. #endif
  121. }
  122. }
  123. osctime_t OSCMessage::getTime(int position){
  124. OSCData * datum = getOSCData(position);
  125. if (!hasError()){
  126. return datum->getTime();
  127. } else {
  128. return zerotime;
  129. }
  130. }
  131. float OSCMessage::getFloat(int position){
  132. OSCData * datum = getOSCData(position);
  133. if (!hasError()){
  134. return datum->getFloat();
  135. } else {
  136. #ifndef ESPxx
  137. return (float)NULL;
  138. #else
  139. return -1;
  140. #endif
  141. }
  142. }
  143. double OSCMessage::getDouble(int position){
  144. OSCData * datum = getOSCData(position);
  145. if (!hasError()){
  146. return datum->getDouble();
  147. } else {
  148. #ifndef ESPxx
  149. return (double)NULL;
  150. #else
  151. return -1;
  152. #endif
  153. }
  154. }
  155. bool OSCMessage::getBoolean(int position){
  156. OSCData * datum = getOSCData(position);
  157. if (!hasError()){
  158. return datum->getBoolean();
  159. } else {
  160. #ifndef ESPxx
  161. return (bool)NULL;
  162. #else
  163. return -1;
  164. #endif
  165. }
  166. }
  167. int OSCMessage::getString(int position, char * buffer){
  168. OSCData * datum = getOSCData(position);
  169. if (!hasError()){
  170. return datum->getString(buffer, datum->bytes);
  171. } else {
  172. #ifndef ESPxx
  173. return (int)NULL;
  174. #else
  175. return -1;
  176. #endif
  177. }
  178. }
  179. int OSCMessage::getString(int position, char * buffer, int bufferSize){
  180. OSCData * datum = getOSCData(position);
  181. if (!hasError()){
  182. //the number of bytes to copy is the smaller between the buffer size and the datum's byte length
  183. int copyBytes = bufferSize < datum->bytes? bufferSize : datum->bytes;
  184. return datum->getString(buffer, copyBytes);
  185. } else {
  186. #ifndef ESPxx
  187. return 0;
  188. #else
  189. return -1;
  190. #endif
  191. }
  192. }
  193. int OSCMessage::getString(int position, char * buffer, int bufferSize, int offset, int size){
  194. OSCData * datum = getOSCData(position);
  195. if (!hasError()){
  196. //the number of bytes to copy is the smaller between the buffer size and the datum's byte length
  197. int copyBytes = bufferSize < datum->bytes? bufferSize : datum->bytes;
  198. return datum->getString(buffer, copyBytes, offset, size);
  199. } else {
  200. #ifndef ESPxx
  201. return 0;
  202. #else
  203. return -1;
  204. #endif
  205. }
  206. }
  207. int OSCMessage::getBlob(int position, uint8_t * buffer){
  208. OSCData * datum = getOSCData(position);
  209. if (!hasError()){
  210. return datum->getBlob(buffer);
  211. } else {
  212. #ifndef ESPxx
  213. return 0;
  214. #else
  215. return -1;
  216. #endif
  217. }
  218. }
  219. int OSCMessage::getBlob(int position, uint8_t * buffer, int bufferSize){
  220. OSCData * datum = getOSCData(position);
  221. if (!hasError()){
  222. return datum->getBlob(buffer, bufferSize);
  223. } else {
  224. #ifndef ESPxx
  225. return 0;
  226. #else
  227. return -1;
  228. #endif
  229. }
  230. }
  231. int OSCMessage::getBlob(int position, uint8_t * buffer, int bufferSize, int offset, int size){
  232. OSCData * datum = getOSCData(position);
  233. if (!hasError()){
  234. return datum->getBlob(buffer, bufferSize, offset, size);
  235. } else {
  236. #ifndef ESPxx
  237. return 0;
  238. #else
  239. return -1;
  240. #endif
  241. }
  242. }
  243. uint32_t OSCMessage::getBlobLength(int position)
  244. {
  245. OSCData * datum = getOSCData(position);
  246. if (!hasError()){
  247. return datum->getBlobLength();
  248. } else {
  249. #ifndef ESPxx
  250. return 0;
  251. #else
  252. return -1;
  253. #endif
  254. }
  255. }
  256. char OSCMessage::getType(int position){
  257. OSCData * datum = getOSCData(position);
  258. if (!hasError()){
  259. return datum->type;
  260. } else {
  261. #ifndef ESPxx
  262. return (int)NULL;
  263. #else
  264. return '\0';
  265. #endif
  266. }
  267. }
  268. int OSCMessage::getDataLength(int position){
  269. OSCData * datum = getOSCData(position);
  270. if (!hasError()){
  271. return datum->bytes;
  272. } else {
  273. return 0;
  274. }
  275. }
  276. /*=============================================================================
  277. TESTING DATA
  278. =============================================================================*/
  279. bool OSCMessage::testType(int position, char type){
  280. OSCData * datum = getOSCData(position);
  281. if (!hasError()){
  282. return datum->type == type;
  283. } else {
  284. return false;
  285. }
  286. }
  287. bool OSCMessage::isInt(int position){
  288. return testType(position, 'i');
  289. }
  290. bool OSCMessage::isTime(int position){
  291. return testType(position, 't');
  292. }
  293. bool OSCMessage::isFloat(int position){
  294. return testType(position, 'f');
  295. }
  296. bool OSCMessage::isBlob(int position){
  297. return testType(position, 'b');
  298. }
  299. bool OSCMessage::isChar(int position){
  300. return testType(position, 'c');
  301. }
  302. bool OSCMessage::isString(int position){
  303. return testType(position, 's');
  304. }
  305. bool OSCMessage::isDouble(int position){
  306. return testType(position, 'd');
  307. }
  308. bool OSCMessage::isBoolean(int position){
  309. return testType(position, 'T') || testType(position, 'F');
  310. }
  311. /*=============================================================================
  312. PATTERN MATCHING
  313. =============================================================================*/
  314. int OSCMessage::match(const char * pattern, int addr_offset){
  315. int pattern_offset;
  316. int address_offset;
  317. int ret = osc_match(address + addr_offset, pattern, &pattern_offset, &address_offset);
  318. char * next = (char *) (address + addr_offset + pattern_offset);
  319. if (ret==3){
  320. return pattern_offset;
  321. } else if (pattern_offset > 0 && *next == '/'){
  322. return pattern_offset;
  323. } else {
  324. return 0;
  325. }
  326. }
  327. bool OSCMessage::fullMatch( const char * pattern, int addr_offset){
  328. int pattern_offset;
  329. int address_offset;
  330. int ret = osc_match(address + addr_offset, pattern, &address_offset, &pattern_offset);
  331. return (ret==3);
  332. }
  333. bool OSCMessage::dispatch(const char * pattern, void (*callback)(OSCMessage &), int addr_offset){
  334. if (fullMatch(pattern, addr_offset)){
  335. callback(*this);
  336. return true;
  337. } else {
  338. return false;
  339. }
  340. }
  341. bool OSCMessage::route(const char * pattern, void (*callback)(OSCMessage &, int), int initial_offset){
  342. int match_offset = match(pattern, initial_offset);
  343. if (match_offset>0){
  344. callback(*this, match_offset + initial_offset);
  345. return true;
  346. } else {
  347. return false;
  348. }
  349. }
  350. /*=============================================================================
  351. ADDRESS
  352. =============================================================================*/
  353. int OSCMessage::getAddress(char * buffer, int offset){
  354. strcpy(buffer, address+offset);
  355. return strlen(buffer);
  356. }
  357. int OSCMessage::getAddress(char * buffer, int offset, int len){
  358. strncpy(buffer, address+offset, len);
  359. return strlen(buffer);
  360. }
  361. OSCMessage& OSCMessage::setAddress(const char * _address){
  362. //free the previous address
  363. free(address); // are we sure address was allocated?
  364. //copy the address
  365. char * addressMemory = (char *) malloc( (strlen(_address) + 1) * sizeof(char) );
  366. if (addressMemory == NULL){
  367. error = ALLOCFAILED;
  368. address = NULL;
  369. } else {
  370. strcpy(addressMemory, _address);
  371. address = addressMemory;
  372. }
  373. return *this;
  374. }
  375. /*=============================================================================
  376. SIZE
  377. =============================================================================*/
  378. #ifdef SLOWpadcalculation
  379. int OSCMessage::padSize(int _bytes){
  380. int space = (_bytes + 3) / 4;
  381. space *= 4;
  382. return space - _bytes;
  383. }
  384. #else
  385. static inline int padSize(int bytes) { return (4- (bytes&03))&3; }
  386. #endif
  387. //returns the number of OSCData in the OSCMessage
  388. int OSCMessage::size(){
  389. return dataCount;
  390. }
  391. int OSCMessage::bytes(){
  392. int messageSize = 0;
  393. //send the address
  394. int addrLen = strlen(address) + 1;
  395. messageSize += addrLen;
  396. //padding amount
  397. int addrPad = padSize(addrLen);
  398. messageSize += addrPad;
  399. //add the comma separator
  400. messageSize += 1;
  401. //add the types
  402. messageSize += dataCount;
  403. //pad the types
  404. int typePad = padSize(dataCount + 1); //for the comma
  405. if (typePad == 0){
  406. typePad = 4; // to make sure the type string is null terminated
  407. }
  408. messageSize+=typePad;
  409. //then the data
  410. for (int i = 0; i < dataCount; i++){
  411. OSCData * datum = getOSCData(i);
  412. messageSize+=datum->bytes;
  413. messageSize += padSize(datum->bytes);
  414. }
  415. return messageSize;
  416. }
  417. /*=============================================================================
  418. ERROR HANDLING
  419. =============================================================================*/
  420. bool OSCMessage::hasError(){
  421. bool retError = error != OSC_OK;
  422. //test each of the data
  423. for (int i = 0; i < dataCount; i++){
  424. OSCData * datum = getOSCData(i);
  425. retError |= datum->error != OSC_OK;
  426. }
  427. return retError;
  428. }
  429. OSCErrorCode OSCMessage::getError(){
  430. return error;
  431. }
  432. /*=============================================================================
  433. SENDING
  434. =============================================================================*/
  435. OSCMessage& OSCMessage::send(Print &p){
  436. //don't send a message with errors
  437. if (hasError()){
  438. return *this;
  439. }
  440. uint8_t nullChar = '\0';
  441. //send the address
  442. int addrLen = strlen(address) + 1;
  443. //padding amount
  444. int addrPad = padSize(addrLen);
  445. //write it to the stream
  446. p.write((uint8_t *) address, addrLen);
  447. //add the padding
  448. while(addrPad--){
  449. p.write(nullChar);
  450. }
  451. //add the comma separator
  452. p.write((uint8_t) ',');
  453. //add the types
  454. #ifdef PAULSSUGGESTION
  455. // Paul suggested buffering on the stack
  456. // to improve performance. The problem is this could exhaust the stack
  457. // for long complex messages
  458. {
  459. uint8_t typstr[dataCount];
  460. for (int i = 0; i < dataCount; i++){
  461. typstr[i] = getType(i);
  462. }
  463. p.write(typstr,dataCount);
  464. }
  465. #else
  466. for (int i = 0; i < dataCount; i++){
  467. p.write((uint8_t) getType(i));
  468. }
  469. #endif
  470. //pad the types
  471. int typePad = padSize(dataCount + 1); // 1 is for the comma
  472. if (typePad == 0){
  473. typePad = 4; // This is because the type string has to be null terminated
  474. }
  475. while(typePad--){
  476. p.write(nullChar);
  477. }
  478. //write the data
  479. for (int i = 0; i < dataCount; i++){
  480. OSCData * datum = getOSCData(i);
  481. if ((datum->type == 's') || (datum->type == 'b')){
  482. p.write(datum->data.b, datum->bytes);
  483. int dataPad = padSize(datum->bytes);
  484. while(dataPad--){
  485. p.write(nullChar);
  486. }
  487. } else if (datum->type == 'd'){
  488. double d = BigEndian(datum->data.d);
  489. uint8_t * ptr = (uint8_t *) &d;
  490. p.write(ptr, 8);
  491. } else if (datum->type == 't'){
  492. osctime_t time = datum->data.time;
  493. uint32_t d = BigEndian(time.seconds);
  494. uint8_t * ptr = (uint8_t *) &d;
  495. p.write(ptr, 4);
  496. d = BigEndian(time.fractionofseconds);
  497. ptr = (uint8_t *) &d;
  498. p.write(ptr, 4);
  499. } else if (datum->type == 'T' || datum->type == 'F')
  500. { }
  501. else { // float or int
  502. uint32_t i = BigEndian(datum->data.i);
  503. uint8_t * ptr = (uint8_t *) &i;
  504. p.write(ptr, datum->bytes);
  505. }
  506. }
  507. return *this;
  508. }
  509. /*=============================================================================
  510. FILLING
  511. =============================================================================*/
  512. OSCMessage& OSCMessage::fill(uint8_t incomingByte){
  513. decode(incomingByte);
  514. return *this;
  515. }
  516. OSCMessage& OSCMessage::fill(uint8_t * incomingBytes, int length){
  517. while (length--){
  518. decode(*incomingBytes++);
  519. }
  520. return *this;
  521. }
  522. /*=============================================================================
  523. DECODING
  524. =============================================================================*/
  525. void OSCMessage::decodeAddress(){
  526. setAddress((char *) incomingBuffer);
  527. //change the error from invalid message
  528. error = OSC_OK;
  529. clearIncomingBuffer();
  530. }
  531. void OSCMessage::decodeType(uint8_t incomingByte){
  532. char type = incomingByte;
  533. add(type);
  534. }
  535. void OSCMessage::decodeData(uint8_t incomingByte){
  536. //get the first OSCData to re-set
  537. for (int i = 0; i < dataCount; i++){
  538. OSCData * datum = getOSCData(i);
  539. if (datum->error == INVALID_OSC){
  540. //set the contents of datum with the data received
  541. switch (datum->type){
  542. case 'i':
  543. if (incomingBufferSize == 4){
  544. //parse the buffer as an int
  545. union {
  546. int32_t i;
  547. uint8_t b[4];
  548. } u;
  549. memcpy(u.b, incomingBuffer, 4);
  550. int32_t dataVal = BigEndian(u.i);
  551. set(i, dataVal);
  552. clearIncomingBuffer();
  553. }
  554. break;
  555. case 'f':
  556. if (incomingBufferSize == 4){
  557. //parse the buffer as a float
  558. union {
  559. float f;
  560. uint8_t b[4];
  561. } u;
  562. memcpy(u.b, incomingBuffer, 4);
  563. float dataVal = BigEndian(u.f);
  564. set(i, dataVal);
  565. clearIncomingBuffer();
  566. }
  567. break;
  568. case 'd':
  569. if (incomingBufferSize == 8){
  570. //parse the buffer as a double
  571. union {
  572. double d;
  573. uint8_t b[8];
  574. } u;
  575. memcpy(u.b, incomingBuffer, 8);
  576. double dataVal = BigEndian(u.d);
  577. set(i, dataVal);
  578. clearIncomingBuffer();
  579. }
  580. break;
  581. case 't':
  582. if (incomingBufferSize == 8){
  583. //parse the buffer as a timetag
  584. union {
  585. osctime_t t;
  586. uint8_t b[8];
  587. } u;
  588. memcpy(u.b, incomingBuffer, 8);
  589. u.t.seconds = BigEndian(u.t.seconds);
  590. u.t.fractionofseconds = BigEndian(u.t.fractionofseconds);
  591. set(i, u.t);
  592. clearIncomingBuffer();
  593. }
  594. break;
  595. case 's':
  596. if (incomingByte == 0){
  597. char * str = (char *) incomingBuffer;
  598. set(i, str);
  599. clearIncomingBuffer();
  600. decodeState = DATA_PADDING;
  601. }
  602. break;
  603. case 'b':
  604. if (incomingBufferSize > 4){
  605. //compute the expected blob size
  606. union {
  607. uint32_t i;
  608. uint8_t b[4];
  609. } u;
  610. memcpy(u.b, incomingBuffer, 4);
  611. uint32_t blobLength = BigEndian(u.i);
  612. if (incomingBufferSize == (int)(blobLength + 4)){
  613. set(i, incomingBuffer + 4, blobLength);
  614. clearIncomingBuffer();
  615. decodeState = DATA_PADDING;
  616. }
  617. }
  618. break;
  619. }
  620. //break out of the for loop once we've selected the first invalid message
  621. break;
  622. }
  623. }
  624. }
  625. //does not validate the incoming OSC for correctness
  626. void OSCMessage::decode(uint8_t incomingByte){
  627. addToIncomingBuffer(incomingByte);
  628. switch (decodeState){
  629. case STANDBY:
  630. if (incomingByte == '/'){
  631. decodeState = ADDRESS;
  632. }
  633. break;
  634. case ADDRESS:
  635. if (incomingByte == 0){
  636. //end of the address
  637. //decode the address
  638. decodeAddress();
  639. //next state
  640. decodeState = ADDRESS_PADDING;
  641. }
  642. break;
  643. case ADDRESS_PADDING:
  644. //it does not count the padding
  645. if (incomingByte==','){
  646. //next state
  647. decodeState = TYPES;
  648. clearIncomingBuffer();
  649. }
  650. break;
  651. case TYPES:
  652. if (incomingByte != 0){
  653. //next state
  654. decodeType(incomingByte);
  655. } else {
  656. decodeState = TYPES_PADDING;
  657. }
  658. //FALL THROUGH to test if it should go to the data state
  659. case TYPES_PADDING: {
  660. //compute the padding size for the types
  661. //to determine the start of the data section
  662. int typePad = padSize(dataCount + 1); // 1 is the comma
  663. if (typePad == 0){
  664. typePad = 4; // to make sure it will be null terminated
  665. }
  666. if (incomingBufferSize == (typePad + dataCount)){
  667. clearIncomingBuffer();
  668. decodeState = DATA;
  669. }
  670. }
  671. break;
  672. case DATA:
  673. decodeData(incomingByte);
  674. break;
  675. case DATA_PADDING:{
  676. //get the last valid data
  677. for (int i = dataCount - 1; i >= 0; i--){
  678. OSCData * datum = getOSCData(i);
  679. if (datum->error == OSC_OK){
  680. //compute the padding size for the data
  681. int dataPad = padSize(datum->bytes);
  682. // if there is no padding required, switch back to DATA, and don't clear the incomingBuffer because it holds next data
  683. if (dataPad == 0){
  684. decodeState = DATA;
  685. }
  686. else if (incomingBufferSize == dataPad){
  687. clearIncomingBuffer();
  688. decodeState = DATA;
  689. }
  690. break;
  691. }
  692. }
  693. }
  694. break;
  695. case DONE:
  696. break; // TODO: is this correct? - was missing from original code, it did this by default
  697. }
  698. }
  699. /*=============================================================================
  700. INCOMING BUFFER MANAGEMENT
  701. =============================================================================*/
  702. #define OSCPREALLOCATEIZE 16
  703. void OSCMessage::addToIncomingBuffer(uint8_t incomingByte){
  704. //realloc some space for the new byte and stick it on the end
  705. if(incomingBufferFree>0)
  706. {
  707. incomingBuffer[incomingBufferSize++] = incomingByte;
  708. incomingBufferFree--;
  709. }
  710. else
  711. {
  712. incomingBuffer = (uint8_t *) realloc ( incomingBuffer, incomingBufferSize + 1 + OSCPREALLOCATEIZE);
  713. if (incomingBuffer != NULL){
  714. incomingBuffer[incomingBufferSize++] = incomingByte;
  715. incomingBufferFree = OSCPREALLOCATEIZE;
  716. } else {
  717. error = ALLOCFAILED;
  718. }
  719. }
  720. }
  721. void OSCMessage::clearIncomingBuffer(){
  722. incomingBuffer = (uint8_t *) realloc ( incomingBuffer, OSCPREALLOCATEIZE);
  723. if (incomingBuffer != NULL){
  724. incomingBufferFree = OSCPREALLOCATEIZE;
  725. } else {
  726. error = ALLOCFAILED;
  727. incomingBuffer = NULL;
  728. }
  729. incomingBufferSize = 0;
  730. }