void CMessagePartsBuilder::putBytes(
	const byte* buf,
	const uint32 bufLen,
	SmartPtrCDynamicByteArray& buffer) {
	CAF_CM_STATIC_FUNC_LOG_VALIDATE("CMessagePartsBuilder", "putBytes");
	CAF_CM_VALIDATE_PTR(buf);
	CAF_CM_VALIDATE_SMARTPTR(buffer);

	for (uint32 index = 0; index < bufLen; index++) {
		buffer->memAppend(&buf[index], sizeof(buf[index]));
	}
}
void CMessagePartsBuilder::put(
	const byte value,
	SmartPtrCDynamicByteArray& buffer) {
	CAF_CM_STATIC_FUNC_LOG_VALIDATE("CMessagePartsBuilder", "put(byte)");
	CAF_CM_VALIDATE_SMARTPTR(buffer);

//	const size_t currentPos = buffer->getByteCount() - buffer->getByteCountFromCurrentPos();

	buffer->memAppend(&value, sizeof(value));

//	CAF_CM_LOG_DEBUG_VA2("buffer - pos: %d, val: %02x", currentPos, value);
}
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;
}