< prev index next >
1 /*
2 * To change this license header, choose License Headers in Project Properties.
3 * To change this template file, choose Tools | Templates
4 * and open the template in the editor.
5 */
6 package java.net.http;
7
8 import java.nio.ByteBuffer;
9 import java.util.LinkedList;
10 import java.util.List;
11
12 /**
13 * Represents one frame. May be initialized with a leftover buffer from previous
14 * frame. Call {@code haveFrame()} to determine if buffers contains at least one
15 * frame. If false, the obtain another buffer and call {@code}input(ByteBuffer)}.
16 * There may be additional bytes at end of the frame list.
17 */
18 class FrameReader {
19
20 final List<ByteBuffer> buffers;
21
22 FrameReader() {
23 buffers = new LinkedList<>();
24 }
25
26 FrameReader(FrameReader that) {
27 this.buffers = that.buffers;
28 }
29
30 FrameReader(ByteBuffer remainder) {
31 buffers = new LinkedList<>();
32 if (remainder != null) {
33 buffers.add(remainder);
34 }
35 }
36
37 public synchronized void input(ByteBuffer buffer) {
38 buffers.add(buffer);
39 }
40
41 public synchronized boolean haveFrame() {
42 //buffers = Utils.superCompact(buffers, () -> ByteBuffer.allocate(Utils.BUFSIZE));
43 int size = 0;
44 for (ByteBuffer buffer : buffers) {
45 size += buffer.remaining();
46 }
47 if (size < 3) {
48 return false; // don't have length yet
49 }
50 // we at least have length field
51 int length = 0;
52 int j = 0;
53 ByteBuffer b = buffers.get(j);
54 b.mark();
55 for (int i=0; i<3; i++) {
56 while (!b.hasRemaining()) {
57 b.reset();
58 b = buffers.get(++j);
59 b.mark();
60 }
61 length = (length << 8) + (b.get() & 0xff);
62 }
63 b.reset();
64 return (size >= length + 9); // frame length
65 }
66
67 synchronized List<ByteBuffer> frame() {
68 return buffers;
69 }
70 }
< prev index next >