1 /*
2  * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package jdk.internal.net.http.frame;
27 
28 import jdk.internal.net.http.common.Utils;
29 
30 import java.nio.ByteBuffer;
31 import java.util.List;
32 
33 public class DataFrame extends Http2Frame {
34 
35     public static final int TYPE = 0x0;
36 
37     // Flags
38     public static final int END_STREAM = 0x1;
39     public static final int PADDED = 0x8;
40 
41     private int padLength;
42     private final List<ByteBuffer> data;
43     private final int dataLength;
44 
DataFrame(int streamid, int flags, ByteBuffer data)45     public DataFrame(int streamid, int flags, ByteBuffer data) {
46         this(streamid, flags, List.of(data));
47     }
48 
DataFrame(int streamid, int flags, List<ByteBuffer> data)49     public DataFrame(int streamid, int flags, List<ByteBuffer> data) {
50         super(streamid, flags);
51         this.data = data;
52         this.dataLength = Utils.remaining(data, Integer.MAX_VALUE);
53     }
54 
DataFrame(int streamid, int flags, List<ByteBuffer> data, int padLength)55     public DataFrame(int streamid, int flags, List<ByteBuffer> data, int padLength) {
56         this(streamid, flags, data);
57         if (padLength > 0) {
58             setPadLength(padLength);
59         }
60     }
61 
62     @Override
type()63     public int type() {
64         return TYPE;
65     }
66 
67     @Override
length()68     int length() {
69         return dataLength + (((flags & PADDED) != 0) ? (padLength + 1) : 0);
70     }
71 
72     @Override
flagAsString(int flag)73     public String flagAsString(int flag) {
74         switch (flag) {
75         case END_STREAM:
76             return "END_STREAM";
77         case PADDED:
78             return "PADDED";
79         }
80         return super.flagAsString(flag);
81     }
82 
getData()83     public List<ByteBuffer> getData() {
84         return data;
85     }
86 
getDataLength()87     public int getDataLength() {
88         return dataLength;
89     }
90 
getPadLength()91     int getPadLength() {
92         return padLength;
93     }
94 
setPadLength(int padLength)95     public void setPadLength(int padLength) {
96         this.padLength = padLength;
97         flags |= PADDED;
98     }
99 
payloadLength()100     public int payloadLength() {
101         // RFC 7540 6.1:
102         // The entire DATA frame payload is included in flow control,
103         // including the Pad Length and Padding fields if present
104         if ((flags & PADDED) != 0) {
105             return dataLength + (1 + padLength);
106         } else {
107             return dataLength;
108         }
109     }
110 
111 
112 }
113