/** * Converts a byte array into a MessagePartsDescriptor * @param blockData byte array to convert * @return a MessagePartsDescriptor */ SmartPtrCMessagePartDescriptor CMessagePartDescriptor::fromArray( SmartPtrCDynamicByteArray& buffer) { CAF_CM_STATIC_FUNC("CMessagePartDescriptor", "fromArray"); CAF_CM_VALIDATE_SMARTPTR(buffer); if (buffer->getByteCount() < BLOCK_SIZE) { CAF_CM_EXCEPTION_VA1(E_INVALIDARG, "Input data block is too small - %d", buffer->getByteCount()); } if (CMessagePartsParser::getByte(buffer) != CAF_MSG_VERSION) { CAF_CM_EXCEPTION_VA0(E_INVALIDARG, "Input data block version is incorrect"); } const byte resvd = CMessagePartsParser::getByte(buffer); if (resvd != RESERVED) { CAF_CM_EXCEPTION_VA0(E_INVALIDARG, "Input data block reserved bits are incorrect"); } const uint16 attachmentNumber = CMessagePartsParser::getUint16(buffer); const uint32 partNumber = CMessagePartsParser::getUint32(buffer); const uint32 dataSize = CMessagePartsParser::getUint32(buffer); const uint32 dataOffset = CMessagePartsParser::getUint32(buffer); buffer->verify(); SmartPtrCMessagePartDescriptor messagePartsDescriptor; messagePartsDescriptor.CreateInstance(); messagePartsDescriptor->initialize( attachmentNumber, partNumber, dataSize, dataOffset); return messagePartsDescriptor; }
SmartPtrCDynamicByteArray CMessagePartDescriptor::toArray( const uint16 attachmentNumber, const uint32 partNumber, const uint32 dataSize, const uint32 dataOffset) { SmartPtrCDynamicByteArray buffer; buffer.CreateInstance(); buffer->allocateBytes(BLOCK_SIZE); CMessagePartsBuilder::put(CAF_MSG_VERSION, buffer); CMessagePartsBuilder::put(RESERVED, buffer); CMessagePartsBuilder::put(attachmentNumber, buffer); CMessagePartsBuilder::put(partNumber, buffer); CMessagePartsBuilder::put(dataSize, buffer); CMessagePartsBuilder::put(dataOffset, buffer); buffer->verify(); return buffer; }
SmartPtrIIntMessage COutgoingMessageHandler::rehydrateMultiPartMessage( const SmartPtrCMessageDeliveryRecord& deliveryRecord, const IIntMessage::SmartPtrCHeaders& addlHeaders) { CAF_CM_STATIC_FUNC_LOG("COutgoingMessageHandler", "rehydrateMultiPartMessage"); CAF_CM_VALIDATE_SMARTPTR(deliveryRecord); // addlHeaders are optional uint32 payloadSize = CMessagePartsHeader::BLOCK_SIZE; const std::deque<SmartPtrCMessagePartDescriptorSourceRecord> sourceRecords = deliveryRecord->getMessagePartSources(); for (TConstIterator<std::deque<SmartPtrCMessagePartDescriptorSourceRecord> > sourceRecordIter(sourceRecords); sourceRecordIter; sourceRecordIter++) { const SmartPtrCMessagePartDescriptorSourceRecord sourceRecord = *sourceRecordIter; payloadSize += CMessagePartDescriptor::BLOCK_SIZE + sourceRecord->getDataLength(); } SmartPtrCDynamicByteArray payload; payload.CreateInstance(); payload->allocateBytes(payloadSize); const SmartPtrCDynamicByteArray partsHeader = CMessagePartsHeader::toArray( deliveryRecord->getCorrelationId(), deliveryRecord->getNumberOfParts()); payload->memAppend(partsHeader->getPtr(), partsHeader->getByteCount()); uint32 partNumber = deliveryRecord->getStartingPartNumber(); if (CAF_CM_IS_LOG_DEBUG_ENABLED) { CAF_CM_LOG_DEBUG_VA3("[# sourceRecords=%d][payloadSize=%d][startingPartNumber=%d]", sourceRecords.size(), payloadSize, partNumber); } for (TConstIterator<std::deque<SmartPtrCMessagePartDescriptorSourceRecord> > sourceRecordIter(sourceRecords); sourceRecordIter; sourceRecordIter++) { const SmartPtrCMessagePartDescriptorSourceRecord sourceRecord = *sourceRecordIter; const SmartPtrCDynamicByteArray partDescriptor = CMessagePartDescriptor::toArray( sourceRecord->getAttachmentNumber(), partNumber++, sourceRecord->getDataLength(), sourceRecord->getDataOffset()); payload->memAppend(partDescriptor->getPtr(), partDescriptor->getByteCount()); CAF_CM_LOG_DEBUG_VA3("Reading from file - file: %s, len: %d, offset: %d", sourceRecord->getFilePath().c_str(), sourceRecord->getDataLength(), sourceRecord->getDataOffset()); std::ifstream file(sourceRecord->getFilePath().c_str(), std::ios::binary); try { if (!file.is_open()) { CAF_CM_EXCEPTION_VA1(ERROR_FILE_NOT_FOUND, "Could not open binary file - %s", sourceRecord->getFilePath().c_str()); } file.seekg(sourceRecord->getDataOffset(), std::ios::beg); file.read(reinterpret_cast<char*>(payload->getNonConstPtrAtCurrentPos()), sourceRecord->getDataLength()); payload->verify(); if (! file) { CAF_CM_EXCEPTION_VA3(ERROR_BUFFER_OVERFLOW, "Did not read full contents - file: %s, requested: %d, read: %d", sourceRecord->getFilePath().c_str(), sourceRecord->getDataLength(), file.gcount()); } payload->incrementCurrentPos(sourceRecord->getDataLength()); } CAF_CM_CATCH_ALL; file.close(); CAF_CM_LOG_CRIT_CAFEXCEPTION; CAF_CM_THROWEXCEPTION; } SmartPtrCIntMessage rc; rc.CreateInstance(); rc->initialize(payload, deliveryRecord->getMessageHeaders(), addlHeaders); return rc; }