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 |