blob: 1ae8e6b4120850cc9ac8c3b45db71b531cec5e39 [file] [log] [blame]
QUICHE teamfd50a402018-12-07 22:54:05 -05001// 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#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_
6#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_
7
8// HpackDecoderStringBuffer helps an HPACK decoder to avoid copies of a string
9// literal (name or value) except when necessary (e.g. when split across two
10// or more HPACK block fragments).
11
12#include <stddef.h>
13
14#include <ostream>
bnc47904002019-08-16 11:49:48 -070015#include <string>
QUICHE teamfd50a402018-12-07 22:54:05 -050016
17#include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h"
bnc641ace72020-01-21 12:24:57 -080018#include "net/third_party/quiche/src/common/platform/api/quiche_export.h"
bnc74646d12019-12-13 09:21:19 -080019#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teamfd50a402018-12-07 22:54:05 -050020
21namespace http2 {
22
bnc641ace72020-01-21 12:24:57 -080023class QUICHE_EXPORT_PRIVATE HpackDecoderStringBuffer {
QUICHE teamfd50a402018-12-07 22:54:05 -050024 public:
25 enum class State : uint8_t { RESET, COLLECTING, COMPLETE };
26 enum class Backing : uint8_t { RESET, UNBUFFERED, BUFFERED, STATIC };
27
28 HpackDecoderStringBuffer();
29 ~HpackDecoderStringBuffer();
30
31 HpackDecoderStringBuffer(const HpackDecoderStringBuffer&) = delete;
32 HpackDecoderStringBuffer& operator=(const HpackDecoderStringBuffer&) = delete;
33
34 void Reset();
bnc74646d12019-12-13 09:21:19 -080035 void Set(quiche::QuicheStringPiece value, bool is_static);
QUICHE teamfd50a402018-12-07 22:54:05 -050036
37 // Note that for Huffman encoded strings the length of the string after
38 // decoding may be larger (expected), the same or even smaller; the latter
39 // are unlikely, but possible if the encoder makes odd choices.
40 void OnStart(bool huffman_encoded, size_t len);
41 bool OnData(const char* data, size_t len);
42 bool OnEnd();
43 void BufferStringIfUnbuffered();
44 bool IsBuffered() const;
45 size_t BufferedLength() const;
46
47 // Accessors for the completely collected string (i.e. Set or OnEnd has just
48 // been called, and no reset of the state has occurred).
49
bnc74646d12019-12-13 09:21:19 -080050 // Returns a QuicheStringPiece pointing to the backing store for the string,
QUICHE teamfd50a402018-12-07 22:54:05 -050051 // either the internal buffer or the original transport buffer (e.g. for a
52 // literal value that wasn't Huffman encoded, and that wasn't split across
53 // transport buffers).
bnc74646d12019-12-13 09:21:19 -080054 quiche::QuicheStringPiece str() const;
QUICHE teamfd50a402018-12-07 22:54:05 -050055
56 // Returns the completely collected string by value, using std::move in an
57 // effort to avoid unnecessary copies. ReleaseString() must not be called
58 // unless the string has been buffered (to avoid forcing a potentially
59 // unnecessary copy). ReleaseString() also resets the instance so that it can
60 // be used to collect another string.
bnc47904002019-08-16 11:49:48 -070061 std::string ReleaseString();
QUICHE teamfd50a402018-12-07 22:54:05 -050062
63 State state_for_testing() const { return state_; }
64 Backing backing_for_testing() const { return backing_; }
65 void OutputDebugStringTo(std::ostream& out) const;
66
67 // Returns the estimate of dynamically allocated memory in bytes.
68 size_t EstimateMemoryUsage() const;
69
70 private:
71 // Storage for the string being buffered, if buffering is necessary
72 // (e.g. if Huffman encoded, buffer_ is storage for the decoded string).
bnc47904002019-08-16 11:49:48 -070073 std::string buffer_;
QUICHE teamfd50a402018-12-07 22:54:05 -050074
bnc74646d12019-12-13 09:21:19 -080075 // The QuicheStringPiece to be returned by HpackDecoderStringBuffer::str(). If
QUICHE teamfd50a402018-12-07 22:54:05 -050076 // a string has been collected, but not buffered, value_ points to that
77 // string.
bnc74646d12019-12-13 09:21:19 -080078 quiche::QuicheStringPiece value_;
QUICHE teamfd50a402018-12-07 22:54:05 -050079
80 // The decoder to use if the string is Huffman encoded.
81 HpackHuffmanDecoder decoder_;
82
83 // Count of bytes not yet passed to OnData.
84 size_t remaining_len_;
85
86 // Is the HPACK string Huffman encoded?
87 bool is_huffman_encoded_;
88
89 // State of the string decoding process.
90 State state_;
91
92 // Where is the string stored?
93 Backing backing_;
94};
95
bnc641ace72020-01-21 12:24:57 -080096QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
QUICHE teamfd50a402018-12-07 22:54:05 -050097 std::ostream& out,
98 const HpackDecoderStringBuffer& v);
99
100} // namespace http2
101
102#endif // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_