< prev index next >
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 */
24
25 package java.net.http;
26
27 import java.nio.ByteBuffer;
28 import java.util.ArrayList;
29
30 /**
31 * Manages a ByteBuffer[] for writing frames into for output. The last
32 * ByteBuffer in the list is always unflipped (able to receive more bytes for
33 * sending) until getBufferArray() is called, which calls finish().
34 *
35 * This allows multiple frames to be written to the same BBG.
36 *
37 * Buffers added with addByteBuffer() must be already flipped.
38 */
39 class ByteBufferGenerator {
40
41 ByteBuffer currentBuffer;
42 // source is assumed to always return the same sized buffer
43 final BufferHandler pool;
44 final ArrayList<ByteBuffer> buflist;
45 final int bufsize;
46 boolean finished;
47
48 ByteBufferGenerator(BufferHandler pool) {
49 this.buflist = new ArrayList<>();
50 this.pool = pool;
51 this.currentBuffer = pool.getBuffer();
52 this.bufsize = currentBuffer.capacity();
53 }
54
55 private static final ByteBuffer[] EMPTY = new ByteBuffer[0];
56
57 public ByteBuffer[] getBufferArray() {
58 finish();
59 return buflist.toArray(EMPTY);
60 }
61
62 public ArrayList<ByteBuffer> getBufferList() {
63 finish();
64 return buflist;
65 }
66
67 private synchronized void finish() {
68 if (finished) {
69 return;
70 }
71 finished = true;
72 currentBuffer.flip();
73 if (currentBuffer.hasRemaining()) {
74 buflist.add(currentBuffer);
75 } else {
76 pool.returnBuffer(currentBuffer);
77 }
78 }
79
80 // only used for SettingsFrame: offset is number of bytes to
81 // ignore at start (we only want the payload of the settings frame)
82 public byte[] asByteArray(int offset) {
83 ByteBuffer[] bufs = getBufferArray();
84 int size = 0;
85 for (ByteBuffer buf : bufs) {
86 size += buf.remaining();
87 }
88 byte[] bytes = new byte[size-offset];
89 int pos = 0;
90 for (ByteBuffer buf : bufs) {
91 int rem = buf.remaining();
92 int ignore = Math.min(rem, offset);
93 buf.position(buf.position()+ignore);
94 rem -= ignore;
95 offset -= ignore;
96 buf.get(bytes, pos, rem);
97 pos += rem;
98 }
99 return bytes;
100 }
101
102 ByteBuffer getBuffer(long n) {
103 if (currentBuffer.remaining() < n) {
104 getNewBuffer();
105 if (n > currentBuffer.capacity()) {
106 throw new IllegalArgumentException("requested buffer too large");
107 }
108 }
109 return currentBuffer;
110 }
111
112 void getNewBuffer() {
113 currentBuffer.flip();
114 if (currentBuffer.hasRemaining()) {
115 buflist.add(currentBuffer);
116 } else {
117 pool.returnBuffer(currentBuffer);
118 }
119 currentBuffer = pool.getBuffer();
120 }
121
122 void addByteBuffer(ByteBuffer buf) {
123 getNewBuffer();
124 buflist.add(buf);
125 }
126
127 void addPadding(int length) {
128 while (length > 0) {
129 int n = Math.min(length, bufsize);
130 ByteBuffer b = getBuffer(n);
131 // TODO: currently zeroed?
132 b.position(b.position() + n);
133 length -= n;
134 }
135 }
136 }
< prev index next >