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