1 package com.ericsson.research.transport.ws.spi;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 import java.io.IOException;
38 import java.util.Random;
39
40 import com.ericsson.research.transport.ws.WSException;
41
42 public class WSHybiFrame extends WSAbstractFrame
43 {
44
45 protected boolean masked;
46 protected boolean finalFragment;
47 private static final Random random = new Random();
48
49 protected WSHybiFrame()
50 {
51 }
52
53 public WSHybiFrame(byte type, byte[] payload, boolean masked) throws IOException
54 {
55 this(type, payload, masked, true);
56 }
57
58 public WSHybiFrame(byte type, byte[] payload, boolean masked, boolean finalFragment) throws IOException
59 {
60 super(type);
61 this.masked = masked;
62 this.finalFragment = finalFragment;
63 int j = 0;
64 byte b;
65 if (payload == null)
66 payload = empty;
67 j = payload.length;
68 if (masked)
69 {
70 j += 4;
71 b = (byte) 0x80;
72 }
73 else
74 b = 0;
75
76 if (payload.length < 126)
77 {
78 this.payload = new byte[j + 2];
79 b |= payload.length;
80 this.payload[1] = b;
81 }
82 else if (payload.length <= 0xFFFF)
83 {
84 this.payload = new byte[j + 4];
85 b |= 126;
86 this.payload[1] = b;
87 this.payload[2] = (byte) ((payload.length >>> 8) & 0xFF);
88 this.payload[3] = (byte) (payload.length & 0xFF);
89 }
90 else
91
92 {
93 this.payload = new byte[j + 10];
94 b |= 127;
95 this.payload[1] = b;
96 for (int i = 56; i >= 0; i = i - 8)
97 this.payload[((56 - i) >>> 3) + 2] = (byte) (((long) payload.length >>> i) & 0xFF);
98 }
99 j = this.payload.length - j;
100 this.payload[0] = type;
101 if (finalFragment)
102 this.payload[0] |= 0x80;
103 if (masked)
104 {
105 byte[] mask = new byte[4];
106 random.nextBytes(mask);
107 for (int i = 0; i < 4; i++)
108 this.payload[j++] = mask[i];
109 for (int i = 0; i < payload.length; i++)
110 {
111 int k = i % 4;
112 this.payload[j++] = (byte) (payload[i] ^ mask[k]);
113 }
114 }
115 else
116 System.arraycopy(payload, 0, this.payload, j, payload.length);
117 }
118
119 public int deserialize(byte[] data, int length) throws WSException
120 {
121 if (this.l1 == -1)
122 throw new IllegalStateException("Already deserialized");
123 for (;;)
124 {
125 if (length <= this.pos)
126 return 0;
127 switch (this.pos)
128 {
129 case 0:
130 this.finalFragment = ((data[0] & 0x80) == 0x80);
131 this.type = (byte) (data[0] & 0x0F);
132 this.pos++;
133 break;
134 case 1:
135 this.masked = ((data[1] & 0x80) == 0x80);
136 this.l1 = (byte) (data[1] & 0x7F);
137 switch (this.l1)
138 {
139 case 127:
140 this.pos += 8;
141 this.l1 = 10;
142 break;
143 case 126:
144 this.pos += 2;
145 this.l1 = 4;
146 break;
147 default:
148 if (this.len == 0)
149 {
150 this.payload = empty;
151 this.l1 = -1;
152 return 2;
153 }
154 this.len = this.l1;
155 this.pos += this.len;
156 this.l1 = 2;
157 }
158 if (this.masked)
159 this.pos += 4;
160 break;
161 default:
162 if (this.len == -1)
163 {
164 switch (this.l1)
165 {
166 case 4:
167 this.len = ((data[2] << 8) & 0xFF00) | (data[3] & 0xFF);
168 break;
169 case 10:
170 this.len = data[2];
171 if ((this.len & 0x80) == 0x80)
172 throw new WSException("Invalid frame length");
173 for (int i = 3; i < 10; i++)
174 this.len = ((this.len << 8) & 0xFFFFFF00) | (data[i] & 0xFF);
175 }
176 this.pos += this.len;
177 }
178 else
179 {
180
181 this.payload = new byte[this.len];
182 System.arraycopy(data, this.l1 + (this.masked ? 4 : 0), this.payload, 0, this.len);
183 if (this.masked)
184 for (int i = 0; i < this.len; i++)
185 this.payload[i] = (byte) (this.payload[i] ^ data[this.l1 + (i % 4)]);
186 this.l1 = -1;
187 return this.pos + 1;
188 }
189 }
190 }
191 }
192
193 }