/* * Copyright 2007-2013, martin isenburg, rapidlasso - fast tools to catch reality * * This is free software; you can redistribute and/or modify it under the * terms of the GNU Lesser General Licence as published by the Free Software * Foundation. See the LICENSE.txt file for more information. * * This software is distributed WITHOUT ANY WARRANTY and without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ package com.revolsys.io.channels; import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.WritableByteChannel; import com.revolsys.io.BaseCloseable; import com.revolsys.util.Exceptions; public class ChannelWriter implements BaseCloseable { private int available = 0; private ByteBuffer buffer; private final int capacity; private WritableByteChannel out; public ChannelWriter(final WritableByteChannel out) { this(out, 8096); } public ChannelWriter(final WritableByteChannel out, final ByteBuffer buffer) { this.out = out; this.buffer = buffer; this.capacity = buffer.capacity(); } public ChannelWriter(final WritableByteChannel out, final int capacity) { this(out, ByteBuffer.allocateDirect(capacity)); } public ChannelWriter(final WritableByteChannel out, final int capacity, final ByteOrder byteOrder) { this(out, ByteBuffer.allocateDirect(capacity)); setByteOrder(byteOrder); } @Override public void close() { final WritableByteChannel out = this.out; if (out != null) { write(); this.out = null; try { out.close(); } catch (final IOException e) { throw Exceptions.wrap(e); } } this.buffer = null; } public ByteOrder getByteOrder() { return this.buffer.order(); } public void putByte(final byte b) { if (this.available == 0) { write(); } this.available--; this.buffer.put(b); } public void putBytes(final byte[] bytes) { putBytes(bytes, bytes.length); } public void putBytes(final byte[] bytes, final int length) { if (length < this.available) { this.available -= length; this.buffer.put(bytes, 0, length); } else { this.buffer.put(bytes, 0, this.available); int offset = this.available; do { int bytesToWrite = length - offset; write(); if (bytesToWrite > this.available) { bytesToWrite = this.available; } this.available -= bytesToWrite; this.buffer.put(bytes, offset, bytesToWrite); offset += bytesToWrite; } while (offset < length); } } public void putDouble(final double d) { if (this.available < 8) { write(); } this.available -= 8; this.buffer.putDouble(d); } public void putFloat(final float f) { if (this.available < 4) { write(); } this.available -= 4; this.buffer.putFloat(f); } public void putInt(final int i) { if (this.available < 4) { write(); } this.available -= 4; this.buffer.putInt(i); } public void putLong(final long l) { if (this.available < 8) { write(); } this.available -= 8; this.buffer.putLong(l); } public void putShort(final short s) { if (this.available < 2) { write(); } this.available -= 2; this.buffer.putShort(s); } public void putUnsignedByte(final short b) { putByte((byte)b); } public void putUnsignedInt(final long i) { putInt((int)i); } /** * Unsigned longs don't actually work in Java * @return */ public void putUnsignedLong(final long l) { putLong(l); } public void putUnsignedShort(final int s) { putShort((short)s); } public void setByteOrder(final ByteOrder byteOrder) { this.buffer.order(byteOrder); } private void write() { try { final WritableByteChannel out = this.out; final ByteBuffer buffer = this.buffer; buffer.flip(); final int size = buffer.remaining(); int totalWritten = 0; while (totalWritten < size) { final int written = out.write(buffer); if (written == -1) { throw new EOFException(); } totalWritten += written; } buffer.clear(); this.available = this.capacity; } catch (final IOException e) { throw Exceptions.wrap(e); } } }