Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
BaseNCodecOutputStream |
|
| 3.3333333333333335;3.333 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | ||
18 | package org.apache.commons.codec.binary; | |
19 | ||
20 | import static org.apache.commons.codec.binary.BaseNCodec.EOF; | |
21 | ||
22 | import java.io.FilterOutputStream; | |
23 | import java.io.IOException; | |
24 | import java.io.OutputStream; | |
25 | ||
26 | import org.apache.commons.codec.binary.BaseNCodec.Context; | |
27 | ||
28 | /** | |
29 | * Abstract superclass for Base-N output streams. | |
30 | * | |
31 | * @since 1.5 | |
32 | * @version $Id$ | |
33 | */ | |
34 | public class BaseNCodecOutputStream extends FilterOutputStream { | |
35 | ||
36 | private final boolean doEncode; | |
37 | ||
38 | private final BaseNCodec baseNCodec; | |
39 | ||
40 | 14002 | private final byte[] singleByte = new byte[1]; |
41 | ||
42 | 14002 | private final Context context = new Context(); |
43 | ||
44 | // TODO should this be protected? | |
45 | public BaseNCodecOutputStream(OutputStream out, BaseNCodec basedCodec, boolean doEncode) { | |
46 | 14002 | super(out); |
47 | 14002 | this.baseNCodec = basedCodec; |
48 | 14002 | this.doEncode = doEncode; |
49 | 14002 | } |
50 | ||
51 | /** | |
52 | * Writes the specified <code>byte</code> to this output stream. | |
53 | * | |
54 | * @param i | |
55 | * source byte | |
56 | * @throws IOException | |
57 | * if an I/O error occurs. | |
58 | */ | |
59 | @Override | |
60 | public void write(int i) throws IOException { | |
61 | 122862 | singleByte[0] = (byte) i; |
62 | 122862 | write(singleByte, 0, 1); |
63 | 122862 | } |
64 | ||
65 | /** | |
66 | * Writes <code>len</code> bytes from the specified <code>b</code> array starting at <code>offset</code> to this | |
67 | * output stream. | |
68 | * | |
69 | * @param b | |
70 | * source byte array | |
71 | * @param offset | |
72 | * where to start reading the bytes | |
73 | * @param len | |
74 | * maximum number of bytes to write | |
75 | * | |
76 | * @throws IOException | |
77 | * if an I/O error occurs. | |
78 | * @throws NullPointerException | |
79 | * if the byte array parameter is null | |
80 | * @throws IndexOutOfBoundsException | |
81 | * if offset, len or buffer size are invalid | |
82 | */ | |
83 | @Override | |
84 | public void write(byte b[], int offset, int len) throws IOException { | |
85 | 263743 | if (b == null) { |
86 | 2 | throw new NullPointerException(); |
87 | 263741 | } else if (offset < 0 || len < 0) { |
88 | 4 | throw new IndexOutOfBoundsException(); |
89 | 263737 | } else if (offset > b.length || offset + len > b.length) { |
90 | 4 | throw new IndexOutOfBoundsException(); |
91 | 263733 | } else if (len > 0) { |
92 | 263715 | if (doEncode) { |
93 | 116343 | baseNCodec.encode(b, offset, len, context); |
94 | } else { | |
95 | 147372 | baseNCodec.decode(b, offset, len, context); |
96 | } | |
97 | 263715 | flush(false); |
98 | } | |
99 | 263733 | } |
100 | ||
101 | /** | |
102 | * Flushes this output stream and forces any buffered output bytes to be written out to the stream. If propogate is | |
103 | * true, the wrapped stream will also be flushed. | |
104 | * | |
105 | * @param propogate | |
106 | * boolean flag to indicate whether the wrapped OutputStream should also be flushed. | |
107 | * @throws IOException | |
108 | * if an I/O error occurs. | |
109 | */ | |
110 | private void flush(boolean propogate) throws IOException { | |
111 | 432605 | int avail = baseNCodec.available(context); |
112 | 432605 | if (avail > 0) { |
113 | 168660 | byte[] buf = new byte[avail]; |
114 | 168660 | int c = baseNCodec.readResults(buf, 0, avail, context); |
115 | 168660 | if (c > 0) { |
116 | 168660 | out.write(buf, 0, c); |
117 | } | |
118 | } | |
119 | 432605 | if (propogate) { |
120 | 168890 | out.flush(); |
121 | } | |
122 | 432605 | } |
123 | ||
124 | /** | |
125 | * Flushes this output stream and forces any buffered output bytes to be written out to the stream. | |
126 | * | |
127 | * @throws IOException | |
128 | * if an I/O error occurs. | |
129 | */ | |
130 | @Override | |
131 | public void flush() throws IOException { | |
132 | 168890 | flush(true); |
133 | 168890 | } |
134 | ||
135 | /** | |
136 | * Closes this output stream and releases any system resources associated with the stream. | |
137 | * | |
138 | * @throws IOException | |
139 | * if an I/O error occurs. | |
140 | */ | |
141 | @Override | |
142 | public void close() throws IOException { | |
143 | // Notify encoder of EOF (-1). | |
144 | 14002 | if (doEncode) { |
145 | 6848 | baseNCodec.encode(singleByte, 0, EOF, context); |
146 | } else { | |
147 | 7154 | baseNCodec.decode(singleByte, 0, EOF, context); |
148 | } | |
149 | 14002 | flush(); |
150 | 14002 | out.close(); |
151 | 14002 | } |
152 | ||
153 | } |