summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/net/dcsctp/packet/bounded_byte_reader.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/net/dcsctp/packet/bounded_byte_reader.h')
-rw-r--r--third_party/libwebrtc/net/dcsctp/packet/bounded_byte_reader.h99
1 files changed, 99 insertions, 0 deletions
diff --git a/third_party/libwebrtc/net/dcsctp/packet/bounded_byte_reader.h b/third_party/libwebrtc/net/dcsctp/packet/bounded_byte_reader.h
new file mode 100644
index 0000000000..603ed6ac33
--- /dev/null
+++ b/third_party/libwebrtc/net/dcsctp/packet/bounded_byte_reader.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef NET_DCSCTP_PACKET_BOUNDED_BYTE_READER_H_
+#define NET_DCSCTP_PACKET_BOUNDED_BYTE_READER_H_
+
+#include <cstdint>
+
+#include "api/array_view.h"
+
+namespace dcsctp {
+
+// TODO(boivie): These generic functions - and possibly this entire class -
+// could be a candidate to have added to rtc_base/. They should use compiler
+// intrinsics as well.
+namespace internal {
+// Loads a 8-bit unsigned word at `data`.
+inline uint8_t LoadBigEndian8(const uint8_t* data) {
+ return data[0];
+}
+
+// Loads a 16-bit unsigned word at `data`.
+inline uint16_t LoadBigEndian16(const uint8_t* data) {
+ return (data[0] << 8) | data[1];
+}
+
+// Loads a 32-bit unsigned word at `data`.
+inline uint32_t LoadBigEndian32(const uint8_t* data) {
+ return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
+}
+} // namespace internal
+
+// BoundedByteReader wraps an ArrayView and divides it into two parts; A fixed
+// size - which is the template parameter - and a variable size, which is what
+// remains in `data` after the `FixedSize`.
+//
+// The BoundedByteReader provides methods to load/read big endian numbers from
+// the FixedSize portion of the buffer, and these are read with static bounds
+// checking, to avoid out-of-bounds accesses without a run-time penalty.
+//
+// The variable sized portion can either be used to create sub-readers, which
+// themselves would provide compile-time bounds-checking, or the entire variable
+// sized portion can be retrieved as an ArrayView.
+template <int FixedSize>
+class BoundedByteReader {
+ public:
+ explicit BoundedByteReader(rtc::ArrayView<const uint8_t> data) : data_(data) {
+ RTC_CHECK(data.size() >= FixedSize);
+ }
+
+ template <size_t offset>
+ uint8_t Load8() const {
+ static_assert(offset + sizeof(uint8_t) <= FixedSize, "Out-of-bounds");
+ return internal::LoadBigEndian8(&data_[offset]);
+ }
+
+ template <size_t offset>
+ uint16_t Load16() const {
+ static_assert(offset + sizeof(uint16_t) <= FixedSize, "Out-of-bounds");
+ static_assert((offset % sizeof(uint16_t)) == 0, "Unaligned access");
+ return internal::LoadBigEndian16(&data_[offset]);
+ }
+
+ template <size_t offset>
+ uint32_t Load32() const {
+ static_assert(offset + sizeof(uint32_t) <= FixedSize, "Out-of-bounds");
+ static_assert((offset % sizeof(uint32_t)) == 0, "Unaligned access");
+ return internal::LoadBigEndian32(&data_[offset]);
+ }
+
+ template <size_t SubSize>
+ BoundedByteReader<SubSize> sub_reader(size_t variable_offset) const {
+ RTC_CHECK(FixedSize + variable_offset + SubSize <= data_.size());
+
+ rtc::ArrayView<const uint8_t> sub_span =
+ data_.subview(FixedSize + variable_offset, SubSize);
+ return BoundedByteReader<SubSize>(sub_span);
+ }
+
+ size_t variable_data_size() const { return data_.size() - FixedSize; }
+
+ rtc::ArrayView<const uint8_t> variable_data() const {
+ return data_.subview(FixedSize, data_.size() - FixedSize);
+ }
+
+ private:
+ const rtc::ArrayView<const uint8_t> data_;
+};
+
+} // namespace dcsctp
+
+#endif // NET_DCSCTP_PACKET_BOUNDED_BYTE_READER_H_