186 lines
6.2 KiB
C++
186 lines
6.2 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set sw=2 ts=8 et tw=80 : */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsString.h"
|
|
#include "nsTArray.h"
|
|
|
|
#include "Capsule.h"
|
|
#include "CapsuleEncoder.h"
|
|
|
|
namespace mozilla::net {
|
|
|
|
CapsuleEncoder::CapsuleEncoder() {
|
|
NeqoEncoder::Init(getter_AddRefs(mEncoder));
|
|
MOZ_ASSERT(mEncoder);
|
|
}
|
|
|
|
CapsuleEncoder::~CapsuleEncoder() = default;
|
|
|
|
void CapsuleEncoder::EncodeCapsule(Capsule& aCapsule) {
|
|
if (aCapsule.mCapsule.is<UnknownCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<UnknownCapsule>();
|
|
EncodeVarint(value.mType).EncodeBufferWithVarintLen(value.mData);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<CloseWebTransportSessionCapsule>()) {
|
|
const auto& value = aCapsule.mCapsule.as<CloseWebTransportSessionCapsule>();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(4 + value.mReason.Length())
|
|
.EncodeUint(4, value.mStatus)
|
|
.EncodeString(value.mReason);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportMaxDataCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportMaxDataCapsule>();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(CapsuleEncoder::VarintLength(value.mMaxDataSize))
|
|
.EncodeVarint(value.mMaxDataSize);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportStreamDataCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportStreamDataCapsule>();
|
|
uint64_t length =
|
|
CapsuleEncoder::VarintLength(value.mID) + value.mData.Length();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(length)
|
|
.EncodeVarint(value.mID)
|
|
.EncodeBuffer(value.mData);
|
|
mStreamMetadata = Some(StreamMetadata{
|
|
value.mID, value.mData.Length(),
|
|
CapsuleEncoder::VarintLength(static_cast<uint64_t>(value.Type())) +
|
|
CapsuleEncoder::VarintLength(length) +
|
|
CapsuleEncoder::VarintLength(value.mID)});
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportStreamsBlockedCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportStreamsBlockedCapsule>();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(CapsuleEncoder::VarintLength(value.mLimit))
|
|
.EncodeVarint(value.mLimit);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportMaxStreamsCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportMaxStreamsCapsule>();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(CapsuleEncoder::VarintLength(value.mLimit))
|
|
.EncodeVarint(value.mLimit);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportStreamDataBlockedCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportStreamDataBlockedCapsule>();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(CapsuleEncoder::VarintLength(value.mID) +
|
|
CapsuleEncoder::VarintLength(value.mLimit))
|
|
.EncodeVarint(value.mID)
|
|
.EncodeVarint(value.mLimit);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportMaxStreamDataCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportMaxStreamDataCapsule>();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(CapsuleEncoder::VarintLength(value.mID) +
|
|
CapsuleEncoder::VarintLength(value.mLimit))
|
|
.EncodeVarint(value.mID)
|
|
.EncodeVarint(value.mLimit);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportDataBlockedCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportDataBlockedCapsule>();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(CapsuleEncoder::VarintLength(value.mLimit))
|
|
.EncodeVarint(value.mLimit);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportStopSendingCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportStopSendingCapsule>();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(CapsuleEncoder::VarintLength(value.mID) +
|
|
CapsuleEncoder::VarintLength(value.mErrorCode))
|
|
.EncodeVarint(value.mID)
|
|
.EncodeVarint(value.mErrorCode);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportResetStreamCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportResetStreamCapsule>();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(CapsuleEncoder::VarintLength(value.mID) +
|
|
CapsuleEncoder::VarintLength(value.mErrorCode) +
|
|
CapsuleEncoder::VarintLength(value.mReliableSize))
|
|
.EncodeVarint(value.mID)
|
|
.EncodeVarint(value.mErrorCode)
|
|
.EncodeVarint(value.mReliableSize);
|
|
return;
|
|
}
|
|
|
|
if (aCapsule.mCapsule.is<WebTransportDatagramCapsule>()) {
|
|
auto& value = aCapsule.mCapsule.as<WebTransportDatagramCapsule>();
|
|
uint64_t length = value.mPayload.Length();
|
|
EncodeVarint(value.Type())
|
|
.EncodeVarint(length)
|
|
.EncodeBuffer(value.mPayload);
|
|
return;
|
|
}
|
|
}
|
|
|
|
CapsuleEncoder& CapsuleEncoder::EncodeByte(uint8_t aData) {
|
|
mEncoder->EncodeByte(aData);
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
CapsuleEncoder& CapsuleEncoder::EncodeUint(uint32_t aSize, T aValue) {
|
|
uint64_t value = static_cast<uint64_t>(aValue);
|
|
mEncoder->EncodeUint(aSize, value);
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
CapsuleEncoder& CapsuleEncoder::EncodeVarint(T aValue) {
|
|
uint64_t value = static_cast<uint64_t>(aValue);
|
|
mEncoder->EncodeVarint(value);
|
|
return *this;
|
|
}
|
|
|
|
CapsuleEncoder& CapsuleEncoder::EncodeString(const nsACString& aData) {
|
|
mEncoder->EncodeBuffer(reinterpret_cast<const uint8_t*>(aData.BeginReading()),
|
|
aData.Length());
|
|
return *this;
|
|
}
|
|
|
|
CapsuleEncoder& CapsuleEncoder::EncodeBuffer(nsTArray<uint8_t>& aData) {
|
|
mEncoder->EncodeBuffer(aData.Elements(), aData.Length());
|
|
return *this;
|
|
}
|
|
|
|
CapsuleEncoder& CapsuleEncoder::EncodeBufferWithVarintLen(
|
|
nsTArray<uint8_t>& aData) {
|
|
mEncoder->EncodeBufferWithVarintLen(aData.Elements(), aData.Length());
|
|
return *this;
|
|
}
|
|
|
|
// static
|
|
size_t CapsuleEncoder::VarintLength(uint64_t aValue) {
|
|
return NeqoEncoder::VarintLength(aValue);
|
|
}
|
|
|
|
mozilla::Span<const uint8_t> CapsuleEncoder::GetBuffer() {
|
|
const uint8_t* buffer = nullptr;
|
|
uint32_t length = 0;
|
|
mEncoder->GetData(&buffer, &length);
|
|
return Span<const uint8_t>(buffer, length);
|
|
}
|
|
|
|
} // namespace mozilla::net
|