| Index: net/http2/decoder/decode_buffer.cc
|
| diff --git a/net/http2/decoder/decode_buffer.cc b/net/http2/decoder/decode_buffer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..15235bae4b53db8bcc127f190aee6a5df70deba8
|
| --- /dev/null
|
| +++ b/net/http2/decoder/decode_buffer.cc
|
| @@ -0,0 +1,90 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/http2/decoder/decode_buffer.h"
|
| +
|
| +namespace net {
|
| +
|
| +bool DecodeBuffer::SlowDecodeUnsignedInt(uint32_t field_size,
|
| + uint32_t field_offset,
|
| + uint32_t* decode_offset,
|
| + uint32_t* value) {
|
| + DCHECK_LT(0u, field_size);
|
| + DCHECK_LE(field_size, 4u);
|
| + DCHECK(decode_offset != nullptr);
|
| + DCHECK_LE(field_offset, *decode_offset);
|
| + const uint32_t next_field_offset = field_offset + field_size;
|
| + if (*decode_offset == field_offset) {
|
| + // Starting to decode field. It is possible we will reach this point
|
| + // twice, once when we've just exhausted the input, and once when
|
| + // resuming decoding with a new input buffer.
|
| + // Clear the field; we do NOT assume that the caller has done so
|
| + // previously.
|
| + *value = 0;
|
| + } else if (*decode_offset >= next_field_offset) {
|
| + // We already decoded this field.
|
| + return true;
|
| + }
|
| + do {
|
| + if (Empty()) {
|
| + return false; // Not done decoding.
|
| + }
|
| + *value = *value << 8 | DecodeUInt8();
|
| + (*decode_offset)++;
|
| + } while (*decode_offset < next_field_offset);
|
| + return true;
|
| +}
|
| +
|
| +bool DecodeBuffer::SlowDecodeUInt8(uint32_t field_offset,
|
| + uint32_t* decode_offset,
|
| + uint8_t* value) {
|
| + uint32_t tmp = *value;
|
| + const bool done = SlowDecodeUnsignedInt(1 /* field_size */, field_offset,
|
| + decode_offset, &tmp);
|
| + *value = tmp & 0xff;
|
| + DCHECK_EQ(tmp, *value);
|
| + return done;
|
| +}
|
| +
|
| +bool DecodeBuffer::SlowDecodeUInt16(uint32_t field_offset,
|
| + uint32_t* decode_offset,
|
| + uint16_t* value) {
|
| + uint32_t tmp = *value;
|
| + const bool done = SlowDecodeUnsignedInt(2 /* field_size */, field_offset,
|
| + decode_offset, &tmp);
|
| + *value = tmp & 0xffff;
|
| + DCHECK_EQ(tmp, *value);
|
| + return done;
|
| +}
|
| +
|
| +bool DecodeBuffer::SlowDecodeUInt24(uint32_t field_offset,
|
| + uint32_t* decode_offset,
|
| + uint32_t* value) {
|
| + uint32_t tmp = *value;
|
| + const bool done = SlowDecodeUnsignedInt(3 /* field_size */, field_offset,
|
| + decode_offset, &tmp);
|
| + *value = tmp & 0xffffff;
|
| + DCHECK_EQ(tmp, *value);
|
| + return done;
|
| +}
|
| +
|
| +bool DecodeBuffer::SlowDecodeUInt31(uint32_t field_offset,
|
| + uint32_t* decode_offset,
|
| + uint32_t* value) {
|
| + uint32_t tmp = *value;
|
| + const bool done = SlowDecodeUnsignedInt(4 /* field_size */, field_offset,
|
| + decode_offset, &tmp);
|
| + *value = tmp & 0x7fffffff;
|
| + DCHECK_EQ(tmp & 0x7fffffff, *value);
|
| + return done;
|
| +}
|
| +
|
| +bool DecodeBuffer::SlowDecodeUInt32(uint32_t field_offset,
|
| + uint32_t* decode_offset,
|
| + uint32_t* value) {
|
| + return SlowDecodeUnsignedInt(4 /* field_size */, field_offset, decode_offset,
|
| + value);
|
| +}
|
| +
|
| +} // namespace net
|
|
|