void FifoReadCallback::readDataAvailable(size_t len) noexcept { try { readBuffer_.postallocate(len); // Process any pending packet headers. if (pendingHeader_.packetSize() > 0) { if (readBuffer_.chainLength() < pendingHeader_.packetSize()) { return; } feedParser(pendingHeader_, readBuffer_.split(pendingHeader_.packetSize())); pendingHeader_.setPacketSize(0); } while (readBuffer_.chainLength() >= std::max(sizeof(MessageHeader), sizeof(PacketHeader))) { if (isMessageHeader(readBuffer_)) { auto msgHeader = parseMessageHeader(readBuffer_); auto fromAddr = msgHeader.getLocalAddress(); auto toAddr = msgHeader.getPeerAddress(); if (msgHeader.direction() == MessageDirection::Received) { std::swap(fromAddr, toAddr); } parserMap_.fetch(msgHeader.msgId()).setAddresses(fromAddr, toAddr); continue; } auto packetHeader = parsePacketHeader( readBuffer_.split(sizeof(PacketHeader))->coalesce()); if (packetHeader.packetSize() > readBuffer_.chainLength()) { // Wait for more data. pendingHeader_ = std::move(packetHeader); return; } feedParser(packetHeader, readBuffer_.split(packetHeader.packetSize())); } } catch (const std::exception& ex) { CHECK(false) << "Unexpected exception: " << ex.what(); } }
void FifoReadCallback::readDataAvailable(size_t len) noexcept { try { readBuffer_.postallocate(len); // Process any pending packet headers. if (pendingHeader_) { if (readBuffer_.chainLength() < pendingHeader_->packetSize()) { return; } forwardMessage(pendingHeader_.value(), readBuffer_.split(pendingHeader_->packetSize())); pendingHeader_.clear(); } while (readBuffer_.chainLength() >= kHeaderMagicSize) { if (isMessageHeader(readBuffer_)) { if (readBuffer_.chainLength() < sizeof(MessageHeader)) { // Wait for more data return; } handleMessageHeader(parseMessageHeader(readBuffer_)); } if (readBuffer_.chainLength() < sizeof(PacketHeader)) { // Wait for more data return; } auto packetHeader = parsePacketHeader(readBuffer_); if (packetHeader.packetSize() > readBuffer_.chainLength()) { // Wait for more data. pendingHeader_.assign(std::move(packetHeader)); return; } forwardMessage(packetHeader, readBuffer_.split(packetHeader.packetSize())); } } catch (const std::exception& ex) { CHECK(false) << "Unexpected exception: " << ex.what(); } }
int parse( char * data, int n ) { w32::Lock lock( &critSec ); PROFILE; //int a[512]; //int nAlive = 0; int k=0,mode=0; char * b = data; while ( k < n ) { //fprintf( stderr, "$ %d %s\n", k, &b[k] ); if ( strstr( &b[k], "#bundle" ) ) { mode = 0; /// moved, see below //listener.startBundle(); // ok, we'll skip 'all the seconds there ever were' k += 16; } else { Packet packet = {0}; k += parsePacketHeader( &b[k], packet ); //printf("p %d\t'%s'\t'%s'\t'%s'\n",packet.len,packet.head,packet.cmd,packet.pinfo); // cursor or object ? if ( ! strcmp( packet.head, "/tuio/2Dobj" ) ) { // // this hack keeps our objects alive - // we only start a bundle for objects, // sending the cursors to the current bundle: // if ( mode == 0 ) listener.startBundle(); mode = 1; } else if ( ! strcmp( packet.head, "/tuio/2Dcur" ) ) { mode = 2; } // check the cmd: if ( ! strcmp( packet.cmd, "set" ) ) { Object o = {0}; o.type = mode; k += parseSet( &b[k], &o, mode ); listener.call( o ); } else if ( ! strcmp( packet.cmd, "fseq" ) ) { int s = 0; k += getInt( &b[k], s ); if ( seq > s ) { //fprintf( stderr, "!!!seq %d > %d\n", seq,s ); } seq = s; } else if ( ! strcmp( packet.cmd, "alive" ) ) { int na = strlen(packet.pinfo) - 2; // skip ',s' if ( na > 0 ) { for ( int i=0; i<na; i++ ) { int a = 0; k += getInt( &b[k], a ); listener.call( a ); } } } } } return n; }