1 // Copyright (c) 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_SPDY_SPDY_BUFFER_H_
6 #define NET_SPDY_SPDY_BUFFER_H_
7 
8 #include <cstddef>
9 #include <memory>
10 #include <vector>
11 
12 #include "base/callback_forward.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "net/base/net_export.h"
16 
17 namespace spdy {
18 class SpdySerializedFrame;
19 }  // namespace spdy
20 
21 namespace net {
22 
23 class IOBuffer;
24 
25 // SpdyBuffer is a class to hold data read from or to be written to a
26 // SPDY connection. It is similar to a DrainableIOBuffer but is not
27 // ref-counted and will include a way to get notified when Consume()
28 // is called.
29 //
30 // NOTE(akalin): This explicitly does not inherit from IOBuffer to
31 // avoid the needless ref-counting and to avoid working around the
32 // fact that IOBuffer member functions are not virtual.
33 class NET_EXPORT_PRIVATE SpdyBuffer {
34  public:
35   // The source of a call to a ConsumeCallback.
36   enum ConsumeSource {
37     // Called via a call to Consume().
38     CONSUME,
39     // Called via the SpdyBuffer being destroyed.
40     DISCARD
41   };
42 
43   // A Callback that gets called when bytes are consumed with the
44   // (non-zero) number of bytes consumed and the source of the
45   // consume. May be called any number of times with CONSUME as the
46   // source followed by at most one call with DISCARD as the
47   // source. The sum of the number of bytes consumed equals the total
48   // size of the buffer.
49   typedef base::RepeatingCallback<void(size_t, ConsumeSource)> ConsumeCallback;
50 
51   // Construct with the data in the given frame. Assumes that data is
52   // owned by |frame| or outlives it.
53   explicit SpdyBuffer(std::unique_ptr<spdy::SpdySerializedFrame> frame);
54 
55   // Construct with a copy of the given raw data. |data| must be
56   // non-NULL and |size| must be non-zero.
57   SpdyBuffer(const char* data, size_t size);
58 
59   // If there are bytes remaining in the buffer, triggers a call to
60   // any consume callbacks with a DISCARD source.
61   ~SpdyBuffer();
62 
63   // Returns the remaining (unconsumed) data.
64   const char* GetRemainingData() const;
65 
66   // Returns the number of remaining (unconsumed) bytes.
67   size_t GetRemainingSize() const;
68 
69   // Add a callback to be called when bytes are consumed. The
70   // ConsumeCallback should not do anything complicated; ideally it
71   // should only update a counter. In particular, it must *not* cause
72   // the SpdyBuffer itself to be destroyed.
73   void AddConsumeCallback(const ConsumeCallback& consume_callback);
74 
75   // Consume the given number of bytes, which must be positive but not
76   // greater than GetRemainingSize().
77   void Consume(size_t consume_size);
78 
79   // Returns an IOBuffer pointing to the data starting at
80   // GetRemainingData(). Use with care; the returned IOBuffer is not
81   // updated when Consume() is called. However, it may still be used
82   // past the lifetime of this object.
83   //
84   // This is used with Socket::Write(), which takes an IOBuffer* that
85   // may be written to even after the socket itself is destroyed. (See
86   // http://crbug.com/249725 .)
87   scoped_refptr<IOBuffer> GetIOBufferForRemainingData();
88 
89   // Returns the estimate of dynamically allocated memory in bytes.
90   size_t EstimateMemoryUsage() const;
91 
92  private:
93   void ConsumeHelper(size_t consume_size, ConsumeSource consume_source);
94 
95   // Ref-count the passed-in spdy::SpdySerializedFrame to support the semantics
96   // of |GetIOBufferForRemainingData()|.
97   typedef base::RefCountedData<std::unique_ptr<spdy::SpdySerializedFrame>>
98       SharedFrame;
99 
100   class SharedFrameIOBuffer;
101 
102   const scoped_refptr<SharedFrame> shared_frame_;
103   std::vector<ConsumeCallback> consume_callbacks_;
104   size_t offset_;
105 
106   DISALLOW_COPY_AND_ASSIGN(SpdyBuffer);
107 };
108 
109 }  // namespace net
110 
111 #endif  // NET_SPDY_SPDY_BUFFER_H_
112