kitaev@213: /* kitaev@213: * Copyright (c) 2011 TMate Software Ltd kitaev@213: * kitaev@213: * This program is free software; you can redistribute it and/or modify kitaev@213: * it under the terms of the GNU General Public License as published by kitaev@213: * the Free Software Foundation; version 2 of the License. kitaev@213: * kitaev@213: * This program is distributed in the hope that it will be useful, kitaev@213: * but WITHOUT ANY WARRANTY; without even the implied warranty of kitaev@213: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the kitaev@213: * GNU General Public License for more details. kitaev@213: * kitaev@213: * For information on how to redistribute this software under kitaev@213: * the terms of a license other than GNU General Public License kitaev@213: * contact TMate Software at support@hg4j.com kitaev@213: */ kitaev@213: package org.tmatesoft.hg.internal; kitaev@213: kitaev@213: import java.nio.ByteBuffer; kitaev@213: import java.util.LinkedList; kitaev@213: import java.util.List; kitaev@213: kitaev@213: import org.tmatesoft.hg.util.ByteChannel; kitaev@213: kitaev@213: /** kitaev@213: * kitaev@213: * @author Artem Tikhomirov kitaev@213: * @author TMate Software Ltd. kitaev@213: */ kitaev@213: public class ByteArrayChannel implements ByteChannel { kitaev@213: private final List buffers; kitaev@213: private ByteBuffer target; kitaev@213: private byte[] result; kitaev@213: kitaev@213: public ByteArrayChannel() { kitaev@213: this(-1); kitaev@213: } kitaev@213: kitaev@213: public ByteArrayChannel(int size) { kitaev@213: if (size == -1) { kitaev@213: buffers = new LinkedList(); kitaev@213: } else { kitaev@213: if (size < 0) { kitaev@213: throw new IllegalArgumentException(String.valueOf(size)); kitaev@213: } kitaev@213: buffers = null; kitaev@213: target = ByteBuffer.allocate(size); kitaev@213: } kitaev@213: } kitaev@213: kitaev@213: // TODO document what happens on write after toArray() in each case kitaev@213: public int write(ByteBuffer buffer) { kitaev@213: int rv = buffer.remaining(); kitaev@213: if (buffers == null) { kitaev@213: target.put(buffer); kitaev@213: } else { kitaev@213: ByteBuffer copy = ByteBuffer.allocate(rv); kitaev@213: copy.put(buffer); kitaev@213: buffers.add(copy); kitaev@213: } kitaev@213: return rv; kitaev@213: } kitaev@213: kitaev@213: public byte[] toArray() { kitaev@213: if (result != null) { kitaev@213: return result; kitaev@213: } kitaev@213: if (buffers == null) { kitaev@213: assert target.hasArray(); kitaev@213: // int total = target.position(); kitaev@213: // System.arraycopy(target.array(), new byte[total]); kitaev@213: // I don't want to duplicate byte[] for now kitaev@213: // although correct way of doing things is to make a copy and discard target kitaev@213: return target.array(); kitaev@213: } else { kitaev@213: int total = 0; kitaev@213: for (ByteBuffer bb : buffers) { kitaev@213: bb.flip(); kitaev@213: total += bb.limit(); kitaev@213: } kitaev@213: result = new byte[total]; kitaev@213: int off = 0; kitaev@213: for (ByteBuffer bb : buffers) { kitaev@213: bb.get(result, off, bb.limit()); kitaev@213: off += bb.limit(); kitaev@213: } kitaev@213: buffers.clear(); kitaev@213: return result; kitaev@213: } kitaev@213: } kitaev@213: }