• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/http2/decoder/decode_buffer.h"
6 
7 namespace http2 {
8 
DecodeUInt8()9 uint8_t DecodeBuffer::DecodeUInt8() {
10   return static_cast<uint8_t>(DecodeChar());
11 }
12 
DecodeUInt16()13 uint16_t DecodeBuffer::DecodeUInt16() {
14   QUICHE_DCHECK_LE(2u, Remaining());
15   const uint8_t b1 = DecodeUInt8();
16   const uint8_t b2 = DecodeUInt8();
17   // Note that chars are automatically promoted to ints during arithmetic,
18   // so the b1 << 8 doesn't end up as zero before being or-ed with b2.
19   // And the left-shift operator has higher precedence than the or operator.
20   return b1 << 8 | b2;
21 }
22 
DecodeUInt24()23 uint32_t DecodeBuffer::DecodeUInt24() {
24   QUICHE_DCHECK_LE(3u, Remaining());
25   const uint8_t b1 = DecodeUInt8();
26   const uint8_t b2 = DecodeUInt8();
27   const uint8_t b3 = DecodeUInt8();
28   return b1 << 16 | b2 << 8 | b3;
29 }
30 
DecodeUInt31()31 uint32_t DecodeBuffer::DecodeUInt31() {
32   QUICHE_DCHECK_LE(4u, Remaining());
33   const uint8_t b1 = DecodeUInt8() & 0x7f;  // Mask out the high order bit.
34   const uint8_t b2 = DecodeUInt8();
35   const uint8_t b3 = DecodeUInt8();
36   const uint8_t b4 = DecodeUInt8();
37   return b1 << 24 | b2 << 16 | b3 << 8 | b4;
38 }
39 
DecodeUInt32()40 uint32_t DecodeBuffer::DecodeUInt32() {
41   QUICHE_DCHECK_LE(4u, Remaining());
42   const uint8_t b1 = DecodeUInt8();
43   const uint8_t b2 = DecodeUInt8();
44   const uint8_t b3 = DecodeUInt8();
45   const uint8_t b4 = DecodeUInt8();
46   return b1 << 24 | b2 << 16 | b3 << 8 | b4;
47 }
48 
49 #ifndef NDEBUG
set_subset_of_base(DecodeBuffer * base,const DecodeBufferSubset * subset)50 void DecodeBuffer::set_subset_of_base(DecodeBuffer* base,
51                                       const DecodeBufferSubset* subset) {
52   QUICHE_DCHECK_EQ(this, subset);
53   base->set_subset(subset);
54 }
clear_subset_of_base(DecodeBuffer * base,const DecodeBufferSubset * subset)55 void DecodeBuffer::clear_subset_of_base(DecodeBuffer* base,
56                                         const DecodeBufferSubset* subset) {
57   QUICHE_DCHECK_EQ(this, subset);
58   base->clear_subset(subset);
59 }
set_subset(const DecodeBufferSubset * subset)60 void DecodeBuffer::set_subset(const DecodeBufferSubset* subset) {
61   QUICHE_DCHECK(subset != nullptr);
62   QUICHE_DCHECK_EQ(subset_, nullptr) << "There is already a subset";
63   subset_ = subset;
64 }
clear_subset(const DecodeBufferSubset * subset)65 void DecodeBuffer::clear_subset(const DecodeBufferSubset* subset) {
66   QUICHE_DCHECK(subset != nullptr);
67   QUICHE_DCHECK_EQ(subset_, subset);
68   subset_ = nullptr;
69 }
DebugSetup()70 void DecodeBufferSubset::DebugSetup() {
71   start_base_offset_ = base_buffer_->Offset();
72   max_base_offset_ = start_base_offset_ + FullSize();
73   QUICHE_DCHECK_LE(max_base_offset_, base_buffer_->FullSize());
74 
75   // Ensure that there is only one DecodeBufferSubset at a time for a base.
76   set_subset_of_base(base_buffer_, this);
77 }
DebugTearDown()78 void DecodeBufferSubset::DebugTearDown() {
79   // Ensure that the base hasn't been modified.
80   QUICHE_DCHECK_EQ(start_base_offset_, base_buffer_->Offset())
81       << "The base buffer was modified";
82 
83   // Ensure that we haven't gone beyond the maximum allowed offset.
84   size_t offset = Offset();
85   QUICHE_DCHECK_LE(offset, FullSize());
86   QUICHE_DCHECK_LE(start_base_offset_ + offset, max_base_offset_);
87   QUICHE_DCHECK_LE(max_base_offset_, base_buffer_->FullSize());
88 
89   clear_subset_of_base(base_buffer_, this);
90 }
91 #endif
92 
93 }  // namespace http2
94