quic/dsr/frontend/WriteCodec.cpp (50 lines of code) (raw):
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <folly/Optional.h>
#include <quic/dsr/frontend/WriteCodec.h>
namespace quic {
uint32_t writeDSRStreamFrame(
DSRPacketBuilderBase& packetBuilder,
SendInstruction::Builder& instructionBuilder,
StreamId id,
uint64_t offset,
uint64_t writeBufferLen,
uint64_t flowControlLen,
bool fin,
uint64_t bufMetaStartingOffset) {
if (packetBuilder.remainingSpace() == 0) {
return 0;
}
if (writeBufferLen == 0 && !fin) {
throw QuicInternalException(
"No data or fin supplied when writing stream.",
LocalErrorCode::INTERNAL_ERROR);
}
QuicInteger idInt(id);
uint64_t headerSize = sizeof(uint8_t) + idInt.getSize();
if (packetBuilder.remainingSpace() < headerSize) {
VLOG(4) << "No space in packet for stream header. stream=" << id
<< " limit=" << packetBuilder.remainingSpace();
return 0;
}
QuicInteger offsetInt(offset);
if (offset != 0) {
headerSize += offsetInt.getSize();
}
instructionBuilder.setOffset(offset);
uint64_t dataLen = std::min(writeBufferLen, flowControlLen);
dataLen = std::min(dataLen, packetBuilder.remainingSpace() - headerSize);
bool shouldSetFin = fin && dataLen == writeBufferLen;
if (dataLen == 0 && !shouldSetFin) {
return 0;
}
if (packetBuilder.remainingSpace() < headerSize) {
VLOG(4) << "No space in packet for stream header. stream=" << id
<< " limit=" << packetBuilder.remainingSpace();
return 0;
}
DCHECK(dataLen + headerSize <= packetBuilder.remainingSpace());
instructionBuilder.setLength(dataLen);
instructionBuilder.setFin(shouldSetFin);
instructionBuilder.setBufMetaStartingOffset(bufMetaStartingOffset);
return dataLen + headerSize;
}
} // namespace quic