blob: 9397330fd964fe88727262396e377de7af15a4bf [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
vasilvvb16f7962020-10-13 10:48:38 -070017#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050018#include "http2/hpack/huffman/hpack_huffman_decoder.h"
19#include "common/platform/api/quiche_export.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();
vasilvvb16f7962020-10-13 10:48:38 -070035 void Set(absl::string_view 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
vasilvvb16f7962020-10-13 10:48:38 -070050 // Returns a string_view 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).
vasilvvb16f7962020-10-13 10:48:38 -070054 absl::string_view str() const;
QUICHE teamfd50a402018-12-07 22:54:05 -050055
fayangf68be2c2020-07-29 06:53:59 -070056 // Same as str() if state_ is COMPLETE. Otherwise, returns empty string piece.
vasilvvb16f7962020-10-13 10:48:38 -070057 absl::string_view GetStringIfComplete() const;
fayangf68be2c2020-07-29 06:53:59 -070058
QUICHE teamfd50a402018-12-07 22:54:05 -050059 // Returns the completely collected string by value, using std::move in an
60 // effort to avoid unnecessary copies. ReleaseString() must not be called
61 // unless the string has been buffered (to avoid forcing a potentially
62 // unnecessary copy). ReleaseString() also resets the instance so that it can
63 // be used to collect another string.
bnc47904002019-08-16 11:49:48 -070064 std::string ReleaseString();
QUICHE teamfd50a402018-12-07 22:54:05 -050065
66 State state_for_testing() const { return state_; }
67 Backing backing_for_testing() const { return backing_; }
68 void OutputDebugStringTo(std::ostream& out) const;
69
70 // Returns the estimate of dynamically allocated memory in bytes.
71 size_t EstimateMemoryUsage() const;
72
73 private:
74 // Storage for the string being buffered, if buffering is necessary
75 // (e.g. if Huffman encoded, buffer_ is storage for the decoded string).
bnc47904002019-08-16 11:49:48 -070076 std::string buffer_;
QUICHE teamfd50a402018-12-07 22:54:05 -050077
vasilvvb16f7962020-10-13 10:48:38 -070078 // The string_view to be returned by HpackDecoderStringBuffer::str(). If
QUICHE teamfd50a402018-12-07 22:54:05 -050079 // a string has been collected, but not buffered, value_ points to that
80 // string.
vasilvvb16f7962020-10-13 10:48:38 -070081 absl::string_view value_;
QUICHE teamfd50a402018-12-07 22:54:05 -050082
83 // The decoder to use if the string is Huffman encoded.
84 HpackHuffmanDecoder decoder_;
85
86 // Count of bytes not yet passed to OnData.
87 size_t remaining_len_;
88
89 // Is the HPACK string Huffman encoded?
90 bool is_huffman_encoded_;
91
92 // State of the string decoding process.
93 State state_;
94
95 // Where is the string stored?
96 Backing backing_;
97};
98
bnc641ace72020-01-21 12:24:57 -080099QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
QUICHE teamfd50a402018-12-07 22:54:05 -0500100 std::ostream& out,
101 const HpackDecoderStringBuffer& v);
102
103} // namespace http2
104
105#endif // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_