OSCL_EXPORT_REF bool RTSPParser::registerDataBufferWritten(uint32 sizeWritten) { // take care of entity bodies and stuff if (IS_LOOKING_FOR_END_OF_REQUEST == internalState) { // the memory being filled out is Parser's mainBufferSpace += sizeWritten; continueProcessing(); return true; } else if (IS_CONTINUING_TO_FILL_OUT_ENTITY_BODY == internalState || IS_CONTINUING_TO_FILL_OUT_EMBEDDED_DATA == internalState ) { // the memory being filled out is Engine's entity body ebCurrentOffset += sizeWritten; ebSizeCoveredSoFar += sizeWritten; if (ebSizeCoveredSoFar == ebFullSizeExpected) { eorptr = mainBufferEntry; if (internalState == IS_CONTINUING_TO_FILL_OUT_ENTITY_BODY) { internalState = IS_ENTITY_BODY_IS_READY; } else // internalState=IS_CONTINUING_TO_FILL_OUT_EMBEDDED_DATA { internalState = IS_EMBEDDED_DATA_IS_READY; } } return true; } else if (IS_SKIPPING_OVER_ENTITY_BODY == internalState) { mainBufferSpace += sizeWritten; continueProcessing(); } else if (IS_START_LOOKING_FOR_RESYNC == internalState || IS_LOOKING_FOR_RESYNC == internalState ) { mainBufferSpace += sizeWritten; continueProcessing(); } else { // some kind of error on Engine's part, or Parser's internal inconsistency return false; } return false; // to appease compiler }
OSCL_EXPORT_REF bool RTSPParser::registerEmbeddedDataMemory(RTSPEntityBody * newBody) { if (IS_WAITING_FOR_EMBEDDED_DATA_MEMORY != internalState) { return false; } entityBody = newBody; if (NULL == entityBody) { internalState = IS_SKIPPING_OVER_EMBEDDED_DATA; ebSizeCoveredSoFar = 0; ebCurrentIndex = 0; ebCurrentOffset = 0; } else { internalState = IS_STARTING_TO_FILL_OUT_EMBEDDED_DATA; ebSizeCoveredSoFar = 0; ebCurrentIndex = 0; ebCurrentOffset = 0; } continueProcessing(); return true; }
void RTSPParser::lookForResync() { bool found = false; for (; eorptr < mainBufferSpace - 1; ++eorptr) { if (CHAR_LF == *eorptr || CHAR_CR == *eorptr) { if (*eorptr == *(eorptr + 1)) { found = true; eorptr += 2; break; } else if ((eorptr <= mainBufferSpace - 4) && (CHAR_CR == *(eorptr)) && (CHAR_LF == *(eorptr + 1)) && (CHAR_CR == *(eorptr + 2)) && (CHAR_LF == *(eorptr + 3)) ) { found = true; eorptr += 4; break; } } } if (found) { mainBufferEntry = eorptr; if (mainBufferEntry == mainBufferSpace) { mainBufferEntry = mainBuffer; eorptr = mainBufferEntry; mainBufferSpace = mainBufferEntry; } internalState = IS_WAITING_FOR_REQUEST_MEMORY; continueProcessing(); } else { int sizeToMove = (RTSP_RESYNC_PRESERVE_SIZE < (mainBufferSpace - mainBufferEntry)) ? RTSP_RESYNC_PRESERVE_SIZE : (mainBufferSpace - mainBufferEntry); oscl_memmove(mainBuffer, mainBufferSpace - sizeToMove, sizeToMove); mainBufferEntry = mainBuffer; mainBufferSpace = mainBufferEntry + sizeToMove; eorptr = mainBuffer; } return; }
OSCL_EXPORT_REF bool RTSPParser::registerNewRequestStruct(RTSPIncomingMessage * newRequestStruct) { if (IS_WAITING_FOR_REQUEST_MEMORY != internalState) { return false; } requestStruct = newRequestStruct; internalState = IS_LOOKING_FOR_END_OF_REQUEST; continueProcessing(); return true; }
void AclEngine::Implementation::ChannelList::Channel::Receive::receive(const HCIACLPDU &pdu) { switch (state) { case IDLE: // Not waiting for any more acl packets to form an l2cap packet state = idle(pdu); break; break; case PROCESSING: // Part way through receiving an l2cap packet state = continueProcessing(pdu); break; break; default: // The state machine has become corrupted assert(0); break; } }
OSCL_EXPORT_REF RTSPParser::ParserState RTSPParser::getState() { ParserState stateToReturn; switch (internalState) { case IS_WAITING_FOR_REQUEST_MEMORY: stateToReturn = WAITING_FOR_REQUEST_MEMORY; break; case IS_LOOKING_FOR_END_OF_REQUEST: case IS_CONTINUING_TO_FILL_OUT_ENTITY_BODY: case IS_SKIPPING_OVER_ENTITY_BODY: case IS_LOOKING_FOR_RESYNC: case IS_CONTINUING_TO_FILL_OUT_EMBEDDED_DATA: case IS_SKIPPING_OVER_EMBEDDED_DATA: stateToReturn = WAITING_FOR_DATA; break; case IS_START_LOOKING_FOR_RESYNC: stateToReturn = ERROR_REQUEST_TOO_BIG; internalState = IS_LOOKING_FOR_RESYNC; break; case IS_WAITING_FOR_ENTITY_BODY_MEMORY: stateToReturn = WAITING_FOR_ENTITY_BODY_MEMORY; break; case IS_WAITING_FOR_EMBEDDED_DATA_MEMORY: stateToReturn = WAITING_FOR_EMBEDDED_DATA_MEMORY; break; case IS_ERROR_REQUEST_TOO_BIG: case IS_REQUEST_IS_READY: // both states are processed the same way, // except that the state returned is different // stateToReturn = (IS_REQUEST_IS_READY == internalState) ? REQUEST_IS_READY : ERROR_REQUEST_TOO_BIG; // take care of the entity bodies if (0 == ebFullSizeExpected) { // no eb expected internalState = IS_WAITING_FOR_REQUEST_MEMORY; } else { // check to see the nature of the entity body. if it // is embedded data, change internal state appropriately if (requestStruct->method != METHOD_BINARY_DATA) { internalState = IS_WAITING_FOR_ENTITY_BODY_MEMORY; } else { internalState = IS_WAITING_FOR_EMBEDDED_DATA_MEMORY; } } continueProcessing(); break; case IS_ENTITY_BODY_IS_READY: stateToReturn = ENTITY_BODY_IS_READY; internalState = IS_WAITING_FOR_REQUEST_MEMORY; break; case IS_EMBEDDED_DATA_IS_READY: stateToReturn = EMBEDDED_DATA_IS_READY; internalState = IS_WAITING_FOR_REQUEST_MEMORY; break; default: // now, this is an internal error internalState = IS_INTERNAL_ERROR; stateToReturn = INTERNAL_ERROR; } return stateToReturn; }
void RTSPParser::lookForEndOfRequest() { // eorptr = mainBufferEntry; uint32 newMessageSize; *mainBufferSpace = CHAR_NULL; bool shouldMoveOverToBeginning = false; // now, it's either a binary data thing, or a regular message thing if (CHAR_DOLLAR == *mainBufferEntry) { // interesting, could be it if (mainBufferSpace - mainBufferEntry < 4) { // not a complete message shouldMoveOverToBeginning = true; } else { // it is a complete thing! requestStruct->msgType = RTSPRequestMsg; requestStruct->method = METHOD_BINARY_DATA; requestStruct->contentLength = ((static_cast<uint16>( (*(reinterpret_cast<unsigned char*>(mainBufferEntry + 2)) ))) << 8) + static_cast<uint16>( *(reinterpret_cast<unsigned char*>(mainBufferEntry + 3)) ); requestStruct->contentLengthIsSet = true; *(mainBufferEntry + 2) = CHAR_NULL; requestStruct->contentType = mainBufferEntry + 1; requestStruct->contentTypeIsSet = true; requestStruct->channelID = static_cast<uint8>( *(reinterpret_cast<unsigned char*>(mainBufferEntry + 1))); mainBufferEntry += 4; eorptr = mainBufferEntry; ebFullSizeExpected = requestStruct->contentLength; internalState = IS_REQUEST_IS_READY; return; } } else { // it's a normal message bool found = false; for (/*eorptr = mainBufferEntry*/; eorptr < mainBufferSpace - 1; ++eorptr) { if (CHAR_LF == *eorptr || CHAR_CR == *eorptr) { // it's a possible // is it two newlines? if (*eorptr == *(eorptr + 1)) { // yes, CR-CR or LF-LF format found = true; eorptr += 2; break; } else if ((eorptr <= mainBufferSpace - 4) && (CHAR_CR == *(eorptr)) && (CHAR_LF == *(eorptr + 1)) && (CHAR_CR == *(eorptr + 2)) && (CHAR_LF == *(eorptr + 3)) ) { // yes, MS-WINDOWS format found = true; eorptr += 4; break; } // else, continue on } } if (found) { // transfer the buffer, if necessary newMessageSize = eorptr - mainBufferEntry; // quickly take a peek at content-length char * cl = ci_local_strstr(mainBufferEntry, newMessageSize, RtspRecognizedFieldContentLength); if (NULL == cl) { // nothing visible ebFullSizeExpected = 0; } else if (cl >= mainBufferEntry + newMessageSize) { // it's not part of this particular message ebFullSizeExpected = 0; } else { cl += oscl_strlen(RtspRecognizedFieldContentLength); while (cl < eorptr && (isspaceNotNL(*cl) || (CHAR_COLON == *cl))) { ++cl; } uint32 atoi_tmp; PV_atoi(cl, 'd', atoi_tmp); ebFullSizeExpected = atoi_tmp; // fflush(stdout); } // now, on with the moving around ... if (RTSP_MAX_FULL_REQUEST_SIZE < newMessageSize) { // request too big oscl_memcpy(requestStruct->secondaryBuffer, mainBufferEntry, RTSP_MAX_FULL_REQUEST_SIZE); requestStruct->secondaryBuffer[RTSP_MAX_FULL_REQUEST_SIZE] = CHAR_NULL; requestStruct->secondaryBufferSizeUsed = newMessageSize; requestStruct->amMalformed = RTSPErrorTooBig; mainBufferEntry += newMessageSize; eorptr = mainBufferEntry; internalState = IS_ERROR_REQUEST_TOO_BIG; } else { // everything is peachy oscl_memcpy(requestStruct->secondaryBuffer, mainBufferEntry, newMessageSize); requestStruct->secondaryBuffer[ newMessageSize ] = CHAR_NULL; requestStruct->secondaryBufferSizeUsed = newMessageSize; mainBufferEntry += newMessageSize; eorptr = mainBufferEntry; internalState = IS_REQUEST_IS_READY; } dealWithLineContinuations(requestStruct); requestStruct->parseFirstFields(); } else { shouldMoveOverToBeginning = true; } } if (shouldMoveOverToBeginning) { // i.e. end of request was not found int sizeUsedSoFar = mainBufferSpace - mainBufferEntry; if (RTSP_PARSER_BUFFER_SIZE == sizeUsedSoFar) { // we hit the parser's buffer size internalState = IS_START_LOOKING_FOR_RESYNC; continueProcessing(); // xxx return; } if (mainBufferEntry != mainBuffer) { oscl_memmove(mainBuffer, mainBufferEntry, sizeUsedSoFar); mainBufferEntry = mainBuffer; eorptr = mainBufferEntry; mainBufferSpace = mainBufferEntry + sizeUsedSoFar; } else { // rewind eorptr eorptr -= 4; eorptr = (eorptr < mainBufferEntry) ? mainBufferEntry : eorptr; } } }