1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.buffer;
17
18 import io.netty5.buffer.api.Buffer;
19 import io.netty5.util.CharsetUtil;
20
21 import java.io.DataOutput;
22 import java.io.DataOutputStream;
23 import java.io.IOException;
24 import java.io.OutputStream;
25
26 import static java.util.Objects.requireNonNull;
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public final class BufferOutputStream extends OutputStream implements DataOutput {
41 private final Buffer buffer;
42 private final int startIndex;
43 private DataOutputStream utf8out;
44 private boolean closed;
45
46
47
48
49 public BufferOutputStream(Buffer buffer) {
50 this.buffer = requireNonNull(buffer, "buffer");
51 startIndex = buffer.writerOffset();
52 }
53
54
55
56
57 public int writtenBytes() {
58 return buffer.writerOffset() - startIndex;
59 }
60
61 @Override
62 public void write(byte[] b, int off, int len) throws IOException {
63 prepareWrite(len);
64 if (len > 0) {
65 buffer.writeBytes(b, off, len);
66 }
67 }
68
69 @Override
70 public void write(byte[] b) throws IOException {
71 prepareWrite(b.length);
72 if (b.length > 0) {
73 buffer.writeBytes(b);
74 }
75 }
76
77 @Override
78 public void write(int b) throws IOException {
79 prepareWrite(Integer.BYTES);
80 buffer.writeByte((byte) b);
81 }
82
83 @Override
84 public void writeBoolean(boolean v) throws IOException {
85 prepareWrite(1);
86 buffer.writeByte((byte) (v ? 1 : 0));
87 }
88
89 @Override
90 public void writeByte(int v) throws IOException {
91 prepareWrite(1);
92 buffer.writeByte((byte) v);
93 }
94
95 @Override
96 public void writeBytes(String s) throws IOException {
97 prepareWrite(s.length());
98 buffer.writeCharSequence(s, CharsetUtil.US_ASCII);
99 }
100
101 @Override
102 public void writeChar(int v) throws IOException {
103 prepareWrite(Character.BYTES);
104 buffer.writeChar((char) v);
105 }
106
107 @Override
108 public void writeChars(String s) throws IOException {
109 int len = s.length();
110 prepareWrite(len * Character.BYTES);
111 for (int i = 0 ; i < len ; i ++) {
112 buffer.writeChar(s.charAt(i));
113 }
114 }
115
116 @Override
117 public void writeDouble(double v) throws IOException {
118 prepareWrite(Double.BYTES);
119 buffer.writeDouble(v);
120 }
121
122 @Override
123 public void writeFloat(float v) throws IOException {
124 prepareWrite(Float.BYTES);
125 buffer.writeFloat(v);
126 }
127
128 @Override
129 public void writeInt(int v) throws IOException {
130 prepareWrite(Integer.BYTES);
131 buffer.writeInt(v);
132 }
133
134 @Override
135 public void writeLong(long v) throws IOException {
136 prepareWrite(Long.BYTES);
137 buffer.writeLong(v);
138 }
139
140 @Override
141 public void writeShort(int v) throws IOException {
142 prepareWrite(Short.BYTES);
143 buffer.writeShort((short) v);
144 }
145
146 @Override
147 public void writeUTF(String s) throws IOException {
148 if (closed) {
149 throw new IOException("The stream is closed");
150 }
151 DataOutputStream out = utf8out;
152 if (out == null) {
153
154 utf8out = out = new DataOutputStream(this);
155 }
156 out.writeUTF(s);
157 }
158
159
160
161
162 public Buffer buffer() {
163 return buffer;
164 }
165
166 @Override
167 public void close() throws IOException {
168 if (closed) {
169 return;
170 }
171 closed = true;
172
173 try {
174 super.close();
175 } finally {
176 if (utf8out != null) {
177 utf8out.close();
178 }
179 }
180 }
181
182 private void prepareWrite(int len) throws IOException {
183 if (closed) {
184 throw new IOException("Stream closed");
185 }
186 if (len > 0) {
187 buffer.ensureWritable(len, buffer.capacity() >> 2, true);
188 }
189 }
190 }