View Javadoc
1   /*
2    * Copyright 2013 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.spdy;
17  
18  import io.netty.buffer.ByteBuf;
19  import io.netty.buffer.Unpooled;
20  import io.netty.util.IllegalReferenceCountException;
21  import io.netty.util.internal.StringUtil;
22  
23  /**
24   * The default {@link SpdyDataFrame} implementation.
25   */
26  public class DefaultSpdyDataFrame extends DefaultSpdyStreamFrame implements SpdyDataFrame {
27  
28      private final ByteBuf data;
29  
30      /**
31       * Creates a new instance.
32       *
33       * @param streamId the Stream-ID of this frame
34       */
35      public DefaultSpdyDataFrame(int streamId) {
36          this(streamId, Unpooled.buffer(0));
37      }
38  
39      /**
40       * Creates a new instance.
41       *
42       * @param streamId  the Stream-ID of this frame
43       * @param data      the payload of the frame. Can not exceed {@link SpdyCodecUtil#SPDY_MAX_LENGTH}
44       */
45      public DefaultSpdyDataFrame(int streamId, ByteBuf data) {
46          super(streamId);
47          if (data == null) {
48              throw new NullPointerException("data");
49          }
50          this.data = validate(data);
51      }
52  
53      private static ByteBuf validate(ByteBuf data) {
54          if (data.readableBytes() > SpdyCodecUtil.SPDY_MAX_LENGTH) {
55              throw new IllegalArgumentException("data payload cannot exceed "
56                      + SpdyCodecUtil.SPDY_MAX_LENGTH + " bytes");
57          }
58          return data;
59      }
60  
61      @Override
62      public SpdyDataFrame setStreamId(int streamId) {
63          super.setStreamId(streamId);
64          return this;
65      }
66  
67      @Override
68      public SpdyDataFrame setLast(boolean last) {
69          super.setLast(last);
70          return this;
71      }
72  
73      @Override
74      public ByteBuf content() {
75          if (data.refCnt() <= 0) {
76              throw new IllegalReferenceCountException(data.refCnt());
77          }
78          return data;
79      }
80  
81      @Override
82      public SpdyDataFrame copy() {
83          return replace(content().copy());
84      }
85  
86      @Override
87      public SpdyDataFrame duplicate() {
88          return replace(content().duplicate());
89      }
90  
91      @Override
92      public SpdyDataFrame retainedDuplicate() {
93          return replace(content().retainedDuplicate());
94      }
95  
96      @Override
97      public SpdyDataFrame replace(ByteBuf content) {
98          SpdyDataFrame frame = new DefaultSpdyDataFrame(streamId(), content);
99          frame.setLast(isLast());
100         return frame;
101     }
102 
103     @Override
104     public int refCnt() {
105         return data.refCnt();
106     }
107 
108     @Override
109     public SpdyDataFrame retain() {
110         data.retain();
111         return this;
112     }
113 
114     @Override
115     public SpdyDataFrame retain(int increment) {
116         data.retain(increment);
117         return this;
118     }
119 
120     @Override
121     public SpdyDataFrame touch() {
122         data.touch();
123         return this;
124     }
125 
126     @Override
127     public SpdyDataFrame touch(Object hint) {
128         data.touch(hint);
129         return this;
130     }
131 
132     @Override
133     public boolean release() {
134         return data.release();
135     }
136 
137     @Override
138     public boolean release(int decrement) {
139         return data.release(decrement);
140     }
141 
142     @Override
143     public String toString() {
144         StringBuilder buf = new StringBuilder()
145             .append(StringUtil.simpleClassName(this))
146             .append("(last: ")
147             .append(isLast())
148             .append(')')
149             .append(StringUtil.NEWLINE)
150             .append("--> Stream-ID = ")
151             .append(streamId())
152             .append(StringUtil.NEWLINE)
153             .append("--> Size = ");
154         if (refCnt() == 0) {
155             buf.append("(freed)");
156         } else {
157             buf.append(content().readableBytes());
158         }
159         return buf.toString();
160     }
161 }