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