1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef NET_WEBSOCKETS_WEBSOCKET_INFLATER_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_WEBSOCKETS_WEBSOCKET_INFLATER_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <memory> 11*6777b538SAndroid Build Coastguard Worker #include <utility> 12*6777b538SAndroid Build Coastguard Worker #include <vector> 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Worker #include "base/containers/circular_deque.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/memory/scoped_refptr.h" 16*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker extern "C" struct z_stream_s; 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker namespace net { 21*6777b538SAndroid Build Coastguard Worker 22*6777b538SAndroid Build Coastguard Worker class IOBufferWithSize; 23*6777b538SAndroid Build Coastguard Worker 24*6777b538SAndroid Build Coastguard Worker // WebSocketInflater uncompresses data compressed by DEFLATE algorithm. 25*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE WebSocketInflater { 26*6777b538SAndroid Build Coastguard Worker public: 27*6777b538SAndroid Build Coastguard Worker WebSocketInflater(); 28*6777b538SAndroid Build Coastguard Worker // |input_queue_capacity| is a capacity for each contiguous block in the 29*6777b538SAndroid Build Coastguard Worker // input queue. The input queue can grow without limit. 30*6777b538SAndroid Build Coastguard Worker WebSocketInflater(size_t input_queue_capacity, size_t output_buffer_capacity); 31*6777b538SAndroid Build Coastguard Worker 32*6777b538SAndroid Build Coastguard Worker WebSocketInflater(const WebSocketInflater&) = delete; 33*6777b538SAndroid Build Coastguard Worker WebSocketInflater& operator=(const WebSocketInflater&) = delete; 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker ~WebSocketInflater(); 36*6777b538SAndroid Build Coastguard Worker 37*6777b538SAndroid Build Coastguard Worker // Returns true if there is no error. 38*6777b538SAndroid Build Coastguard Worker // |window_bits| must be between 8 and 15 (both inclusive). 39*6777b538SAndroid Build Coastguard Worker // This function must be called exactly once before calling any of the 40*6777b538SAndroid Build Coastguard Worker // following functions. 41*6777b538SAndroid Build Coastguard Worker bool Initialize(int window_bits); 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker // Adds bytes to |stream_|. 44*6777b538SAndroid Build Coastguard Worker // Returns true if there is no error. 45*6777b538SAndroid Build Coastguard Worker // If the size of the output data reaches the capacity of the output buffer, 46*6777b538SAndroid Build Coastguard Worker // the following input data will be "choked", i.e. stored in the input queue, 47*6777b538SAndroid Build Coastguard Worker // staying compressed. 48*6777b538SAndroid Build Coastguard Worker bool AddBytes(const char* data, size_t size); 49*6777b538SAndroid Build Coastguard Worker 50*6777b538SAndroid Build Coastguard Worker // Flushes the input. 51*6777b538SAndroid Build Coastguard Worker // Returns true if there is no error. 52*6777b538SAndroid Build Coastguard Worker bool Finish(); 53*6777b538SAndroid Build Coastguard Worker 54*6777b538SAndroid Build Coastguard Worker // Returns up to |size| bytes of the decompressed output. 55*6777b538SAndroid Build Coastguard Worker // Returns null if there is an inflation error. 56*6777b538SAndroid Build Coastguard Worker // The returned bytes will be dropped from the current output and never be 57*6777b538SAndroid Build Coastguard Worker // returned again. 58*6777b538SAndroid Build Coastguard Worker // If some input data is choked, calling this function may restart the 59*6777b538SAndroid Build Coastguard Worker // inflation process. 60*6777b538SAndroid Build Coastguard Worker // This means that even if you call |Finish()| and call |GetOutput()| with 61*6777b538SAndroid Build Coastguard Worker // size = |CurrentOutputSize()|, the inflater may have some remaining data. 62*6777b538SAndroid Build Coastguard Worker // To confirm the inflater emptiness, you should check whether 63*6777b538SAndroid Build Coastguard Worker // |CurrentOutputSize()| is zero. 64*6777b538SAndroid Build Coastguard Worker scoped_refptr<IOBufferWithSize> GetOutput(size_t size); 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker // Returns the size of the current inflated output. CurrentOutputSize()67*6777b538SAndroid Build Coastguard Worker size_t CurrentOutputSize() const { return output_buffer_.Size(); } 68*6777b538SAndroid Build Coastguard Worker 69*6777b538SAndroid Build Coastguard Worker static constexpr size_t kDefaultBufferCapacity = 512; 70*6777b538SAndroid Build Coastguard Worker static constexpr size_t kDefaultInputIOBufferCapacity = 512; 71*6777b538SAndroid Build Coastguard Worker 72*6777b538SAndroid Build Coastguard Worker private: 73*6777b538SAndroid Build Coastguard Worker // Ring buffer with fixed capacity. 74*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE OutputBuffer { 75*6777b538SAndroid Build Coastguard Worker public: 76*6777b538SAndroid Build Coastguard Worker explicit OutputBuffer(size_t capacity); 77*6777b538SAndroid Build Coastguard Worker ~OutputBuffer(); 78*6777b538SAndroid Build Coastguard Worker 79*6777b538SAndroid Build Coastguard Worker size_t Size() const; 80*6777b538SAndroid Build Coastguard Worker // Returns (tail pointer, availabe size). 81*6777b538SAndroid Build Coastguard Worker // A user can push data to the queue by writing the data to 82*6777b538SAndroid Build Coastguard Worker // the area returned by this function and calling AdvanceTail. 83*6777b538SAndroid Build Coastguard Worker std::pair<char*, size_t> GetTail(); 84*6777b538SAndroid Build Coastguard Worker void Read(char* dest, size_t size); 85*6777b538SAndroid Build Coastguard Worker void AdvanceTail(size_t advance); 86*6777b538SAndroid Build Coastguard Worker 87*6777b538SAndroid Build Coastguard Worker private: 88*6777b538SAndroid Build Coastguard Worker void AdvanceHead(size_t advance); 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Worker const size_t capacity_; 91*6777b538SAndroid Build Coastguard Worker std::vector<char> buffer_; 92*6777b538SAndroid Build Coastguard Worker size_t head_ = 0; 93*6777b538SAndroid Build Coastguard Worker size_t tail_ = 0; 94*6777b538SAndroid Build Coastguard Worker }; 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker class InputQueue { 97*6777b538SAndroid Build Coastguard Worker public: 98*6777b538SAndroid Build Coastguard Worker // |capacity| is used for the capacity of each IOBuffer in this queue. 99*6777b538SAndroid Build Coastguard Worker // this queue itself can grow without limit. 100*6777b538SAndroid Build Coastguard Worker explicit InputQueue(size_t capacity); 101*6777b538SAndroid Build Coastguard Worker ~InputQueue(); 102*6777b538SAndroid Build Coastguard Worker 103*6777b538SAndroid Build Coastguard Worker // Returns (data pointer, size), the first component of unconsumed data. 104*6777b538SAndroid Build Coastguard Worker // The type of data pointer is non-const because |inflate| function 105*6777b538SAndroid Build Coastguard Worker // requires so. 106*6777b538SAndroid Build Coastguard Worker std::pair<char*, size_t> Top(); IsEmpty()107*6777b538SAndroid Build Coastguard Worker bool IsEmpty() const { return buffers_.empty(); } 108*6777b538SAndroid Build Coastguard Worker void Push(const char* data, size_t size); 109*6777b538SAndroid Build Coastguard Worker // Consumes the topmost |size| bytes. 110*6777b538SAndroid Build Coastguard Worker // |size| must be less than or equal to the first buffer size. 111*6777b538SAndroid Build Coastguard Worker void Consume(size_t size); 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker private: 114*6777b538SAndroid Build Coastguard Worker size_t PushToLastBuffer(const char* data, size_t size); 115*6777b538SAndroid Build Coastguard Worker 116*6777b538SAndroid Build Coastguard Worker const size_t capacity_; 117*6777b538SAndroid Build Coastguard Worker size_t head_of_first_buffer_ = 0; 118*6777b538SAndroid Build Coastguard Worker size_t tail_of_last_buffer_ = 0; 119*6777b538SAndroid Build Coastguard Worker base::circular_deque<scoped_refptr<IOBufferWithSize>> buffers_; 120*6777b538SAndroid Build Coastguard Worker }; 121*6777b538SAndroid Build Coastguard Worker 122*6777b538SAndroid Build Coastguard Worker int InflateWithFlush(const char* next_in, size_t avail_in); 123*6777b538SAndroid Build Coastguard Worker int Inflate(const char* next_in, size_t avail_in, int flush); 124*6777b538SAndroid Build Coastguard Worker int InflateChokedInput(); 125*6777b538SAndroid Build Coastguard Worker 126*6777b538SAndroid Build Coastguard Worker std::unique_ptr<z_stream_s> stream_; 127*6777b538SAndroid Build Coastguard Worker InputQueue input_queue_; 128*6777b538SAndroid Build Coastguard Worker OutputBuffer output_buffer_; 129*6777b538SAndroid Build Coastguard Worker }; 130*6777b538SAndroid Build Coastguard Worker 131*6777b538SAndroid Build Coastguard Worker } // namespace net 132*6777b538SAndroid Build Coastguard Worker 133*6777b538SAndroid Build Coastguard Worker #endif // NET_WEBSOCKETS_WEBSOCKET_INFLATER_H_ 134