1/*
2 * Copyright (c) 2015, 2016, 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
26package jdk.incubator.http.internal.frame;
27
28/**
29 * When sending a frame, the length field must be set in sub-class
30 * by calling computeLength()
31 */
32public abstract class Http2Frame {
33
34    public static final int FRAME_HEADER_SIZE = 9;
35
36    protected int streamid;
37    protected int flags;
38
39    public Http2Frame(int streamid, int flags) {
40        this.streamid = streamid;
41        this.flags = flags;
42    }
43
44    public int streamid() {
45        return streamid;
46    }
47
48    public void setFlag(int flag) {
49        flags |= flag;
50    }
51
52    public void setFlags(int flags) {
53        this.flags = flags;
54    }
55
56    public int getFlags() {
57        return flags;
58    }
59
60    public boolean getFlag(int flag) {
61        return (flags & flag) != 0;
62    }
63
64    public void clearFlag(int flag) {
65        flags &= 0xffffffff ^ flag;
66    }
67
68    public void streamid(int streamid) {
69        this.streamid = streamid;
70    }
71
72
73    public String typeAsString() {
74        return asString(type());
75    }
76
77    public int type() {
78        return -1; // Unknown type
79    }
80
81    int length() {
82        return -1; // Unknown length
83    }
84
85
86    public static String asString(int type) {
87        switch (type) {
88          case DataFrame.TYPE:
89            return "DATA";
90          case HeadersFrame.TYPE:
91            return "HEADERS";
92          case ContinuationFrame.TYPE:
93            return "CONTINUATION";
94          case ResetFrame.TYPE:
95            return "RESET";
96          case PriorityFrame.TYPE:
97            return "PRIORITY";
98          case SettingsFrame.TYPE:
99            return "SETTINGS";
100          case GoAwayFrame.TYPE:
101            return "GOAWAY";
102          case PingFrame.TYPE:
103            return "PING";
104          case PushPromiseFrame.TYPE:
105            return "PUSH_PROMISE";
106          case WindowUpdateFrame.TYPE:
107            return "WINDOW_UPDATE";
108          default:
109            return "UNKNOWN";
110        }
111    }
112
113    @Override
114    public String toString() {
115        StringBuilder sb = new StringBuilder();
116        sb.append(typeAsString())
117                .append(": length=")
118                .append(Integer.toString(length()))
119                .append(", streamid=")
120                .append(streamid)
121                .append(", flags=");
122
123        int f = flags;
124        int i = 0;
125        if (f == 0) {
126            sb.append("0 ");
127        } else {
128            while (f != 0) {
129                if ((f & 1) == 1) {
130                    sb.append(flagAsString(1 << i))
131                      .append(' ');
132                }
133                f = f >> 1;
134                i++;
135            }
136        }
137        return sb.toString();
138    }
139
140    // Override
141    public String flagAsString(int f) {
142        return "unknown";
143    }
144
145}
146