String NybbleizeString(const String & s) { String retStr; ByteBuffer inBuf; inBuf.AdoptBuffer(s.Length(), (uint8 *) s()); const status_t ret = NybbleizeData(inBuf, retStr); (void) inBuf.ReleaseBuffer(); if (ret != B_NO_ERROR) retStr.Clear(); return retStr; }
int32 PacketTunnelIOGateway :: DoInputImplementation(AbstractGatewayMessageReceiver & receiver, uint32 maxBytes) { if (_inputPacketBuffer.SetNumBytes(_maxTransferUnit, false) != B_NO_ERROR) return -1; bool firstTime = true; uint32 totalBytesRead = 0; while((totalBytesRead < maxBytes)&&((firstTime)||(IsSuggestedTimeSliceExpired() == false))) { firstTime = false; int32 bytesRead = GetDataIO()()->Read(_inputPacketBuffer.GetBuffer(), _inputPacketBuffer.GetNumBytes()); //printf(" READ " INT32_FORMAT_SPEC "/" UINT32_FORMAT_SPEC " bytes\n", bytesRead, _inputPacketBuffer.GetNumBytes()); if (bytesRead > 0) { totalBytesRead += bytesRead; IPAddressAndPort fromIAP; const PacketDataIO * packetIO = dynamic_cast<PacketDataIO *>(GetDataIO()()); if (packetIO) fromIAP = packetIO->GetSourceOfLastReadPacket(); const uint8 * p = (const uint8 *) _inputPacketBuffer.GetBuffer(); if ((_allowMiscData)&&((bytesRead < (int32)FRAGMENT_HEADER_SIZE)||(((uint32)B_LENDIAN_TO_HOST_INT32(muscleCopyIn<uint32>(p))) != _magic))) { // If we're allowed to handle miscellaneous data, we'll just pass it on through verbatim ByteBuffer temp; temp.AdoptBuffer(bytesRead, const_cast<uint8 *>(p)); HandleIncomingMessage(receiver, ByteBufferRef(&temp, false), fromIAP); (void) temp.ReleaseBuffer(); } else { const uint8 * invalidByte = p+bytesRead; while(invalidByte-p >= (int32)FRAGMENT_HEADER_SIZE) { const uint32 magic = B_LENDIAN_TO_HOST_INT32(muscleCopyIn<uint32>(&p[0*sizeof(uint32)])); const uint32 sexID = B_LENDIAN_TO_HOST_INT32(muscleCopyIn<uint32>(&p[1*sizeof(uint32)])); const uint32 messageID = B_LENDIAN_TO_HOST_INT32(muscleCopyIn<uint32>(&p[2*sizeof(uint32)])); const uint32 offset = B_LENDIAN_TO_HOST_INT32(muscleCopyIn<uint32>(&p[3*sizeof(uint32)])); const uint32 chunkSize = B_LENDIAN_TO_HOST_INT32(muscleCopyIn<uint32>(&p[4*sizeof(uint32)])); const uint32 totalSize = B_LENDIAN_TO_HOST_INT32(muscleCopyIn<uint32>(&p[5*sizeof(uint32)])); //printf(" PARSE magic=" UINT32_FORMAT_SPEC "/" UINT32_FORMAT_SPEC " sex=" UINT32_FORMAT_SPEC "/" UINT32_FORMAT_SPEC " messageID=" UINT32_FORMAT_SPEC " offset=" UINT32_FORMAT_SPEC " chunkSize=" UINT32_FORMAT_SPEC " totalSize=" UINT32_FORMAT_SPEC "\n", magic, _magic, sexID, _sexID, messageID, offset, chunkSize, totalSize); p += FRAGMENT_HEADER_SIZE; if ((magic == _magic)&&((_sexID == 0)||(_sexID != sexID))&&((invalidByte-p >= (int32)chunkSize)&&(totalSize <= _maxIncomingMessageSize))) { ReceiveState * rs = _receiveStates.Get(fromIAP); if (rs == NULL) { if (offset == 0) rs = _receiveStates.PutAndGet(fromIAP, ReceiveState(messageID)); if (rs) { rs->_buf = GetByteBufferFromPool(totalSize); if (rs->_buf() == NULL) { _receiveStates.Remove(fromIAP); rs = NULL; } } } if (rs) { if ((offset == 0)||(messageID != rs->_messageID)) { // A new message... start receiving it (but only if we are starting at the beginning) rs->_messageID = messageID; rs->_offset = 0; rs->_buf()->SetNumBytes(totalSize, false); } uint32 rsSize = rs->_buf()->GetNumBytes(); //printf(" CHECK: offset=" UINT32_FORMAT_SPEC "/" UINT32_FORMAT_SPEC " %s\n", offset, rs->_offset, (offset==rs->_offset)?"":"DISCONTINUITY!!!"); if ((messageID == rs->_messageID)&&(totalSize == rsSize)&&(offset == rs->_offset)&&(offset+chunkSize <= rsSize)) { memcpy(rs->_buf()->GetBuffer()+offset, p, chunkSize); rs->_offset += chunkSize; if (rs->_offset == rsSize) { HandleIncomingMessage(receiver, rs->_buf, fromIAP); rs->_offset = 0; rs->_buf()->Clear(rsSize > MAX_CACHE_SIZE); } } else { LogTime(MUSCLE_LOG_DEBUG, "Unknown fragment (" UINT32_FORMAT_SPEC "/" UINT32_FORMAT_SPEC "/" UINT32_FORMAT_SPEC "/" UINT32_FORMAT_SPEC ") received from %s, ignoring it.\n", messageID, offset, chunkSize, totalSize, fromIAP.ToString()()); rs->_offset = 0; rs->_buf()->Clear(rsSize > MAX_CACHE_SIZE); } } p += chunkSize; } else break; } } } else if (bytesRead < 0) return -1; else break; } return totalBytesRead; }