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.
5 #ifndef NET_WEBSOCKETS_WEBSOCKET_INFLATER_H_
6 #define NET_WEBSOCKETS_WEBSOCKET_INFLATER_H_
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"
17 extern "C" struct z_stream_s
;
21 class IOBufferWithSize
;
23 // WebSocketInflater uncompresses data compressed by DEFLATE algorithm.
24 class NET_EXPORT_PRIVATE 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
);
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
);
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
);
46 // Returns true if there is no error.
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
53 // If some input data is choked, calling this function may restart the
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
);
61 // Returns the size of the current inflated output.
62 size_t CurrentOutputSize() const { return output_buffer_
.Size(); }
64 static const size_t kDefaultBufferCapacity
= 512;
65 static const size_t kDefaultInputIOBufferCapacity
= 512;
68 // Ring buffer with fixed capacity.
69 class NET_EXPORT_PRIVATE OutputBuffer
{
71 explicit OutputBuffer(size_t capacity
);
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
);
83 void AdvanceHead(size_t advance
);
85 const size_t capacity_
;
86 std::vector
<char> buffer_
;
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
);
98 // Returns (data pointer, size), the first component of unconsumed data.
99 // The type of data pointer is non-const because |inflate| function
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
);
109 size_t PushToLastBuffer(const char* data
, size_t size
);
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_
;
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();
121 scoped_ptr
<z_stream_s
> stream_
;
122 InputQueue input_queue_
;
123 OutputBuffer output_buffer_
;
125 DISALLOW_COPY_AND_ASSIGN(WebSocketInflater
);
130 #endif // NET_WEBSOCKETS_WEBSOCKET_INFLATER_H_