2 * Sonitus - IntegralWriteOutputStream.java - Copyright © 2013 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sonitus.io;
20 import java.io.FilterOutputStream;
21 import java.io.IOException;
22 import java.io.OutputStream;
25 * {@link OutputStream} wrapper that always writes a multiple of a fixed amount
28 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
30 public class IntegralWriteOutputStream extends FilterOutputStream {
32 /** The current in-process values. */
33 private final byte[] buffer;
35 /** The next position of the buffer that will be written to. */
36 private int bufferPosition;
39 * Creates a new integral write output stream.
42 * The output stream to wrap
44 * The number of bytes to write at once
46 public IntegralWriteOutputStream(OutputStream outputStream, int integralSize) {
48 buffer = new byte[integralSize];
52 // OUTPUTSTREAM METHODS
56 public void write(int data) throws IOException {
57 buffer[bufferPosition++] = (byte) data;
58 if (bufferPosition == buffer.length) {
65 public void write(byte[] buffer) throws IOException {
66 write(buffer, 0, buffer.length);
70 public void write(byte[] buffer, int offset, int length) throws IOException {
71 /* are the some bytes in the current buffer? */
73 if (bufferPosition != 0) {
74 int bytesToCopy = Math.min(length, this.buffer.length - bufferPosition);
75 System.arraycopy(buffer, offset, this.buffer, bufferPosition, bytesToCopy);
76 sourceOffset += bytesToCopy;
77 bufferPosition += bytesToCopy;
78 if (bufferPosition == this.buffer.length) {
80 out.write(this.buffer);
84 /* write the largest possible chunk at once. */
85 int integralBytesLeft = (int) ((length - sourceOffset) / this.buffer.length) * this.buffer.length;
86 if (integralBytesLeft != 0) {
87 out.write(buffer, offset + sourceOffset, integralBytesLeft);
90 /* are there some bytes left? */
91 sourceOffset += integralBytesLeft;
92 if (sourceOffset < length) {
93 System.arraycopy(buffer, offset + sourceOffset, this.buffer, 0, length - sourceOffset);
94 bufferPosition = length - sourceOffset;