tikhomirov@534: /* tikhomirov@534: * Copyright (c) 2013 TMate Software Ltd tikhomirov@534: * tikhomirov@534: * This program is free software; you can redistribute it and/or modify tikhomirov@534: * it under the terms of the GNU General Public License as published by tikhomirov@534: * the Free Software Foundation; version 2 of the License. tikhomirov@534: * tikhomirov@534: * This program is distributed in the hope that it will be useful, tikhomirov@534: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@534: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@534: * GNU General Public License for more details. tikhomirov@534: * tikhomirov@534: * For information on how to redistribute this software under tikhomirov@534: * the terms of a license other than GNU General Public License tikhomirov@534: * contact TMate Software at support@hg4j.com tikhomirov@534: */ tikhomirov@534: package org.tmatesoft.hg.internal; tikhomirov@534: tikhomirov@618: import java.io.ByteArrayOutputStream; tikhomirov@618: tikhomirov@618: import org.tmatesoft.hg.core.HgIOException; tikhomirov@534: tikhomirov@534: /** tikhomirov@534: * Serialization friend of {@link DataAccess} tikhomirov@534: * tikhomirov@534: * @author Artem Tikhomirov tikhomirov@534: * @author TMate Software Ltd. tikhomirov@534: */ tikhomirov@534: @Experimental(reason="Work in progress") tikhomirov@534: public class DataSerializer { tikhomirov@618: private byte[] buffer; tikhomirov@534: tikhomirov@618: public void writeByte(byte... values) throws HgIOException { tikhomirov@534: write(values, 0, values.length); tikhomirov@534: } tikhomirov@534: tikhomirov@618: public void writeInt(int... values) throws HgIOException { tikhomirov@618: ensureBufferSize(4*values.length); // sizeof(int) tikhomirov@618: int idx = 0; tikhomirov@534: for (int v : values) { tikhomirov@618: bigEndian(v, buffer, idx); tikhomirov@618: idx += 4; tikhomirov@618: } tikhomirov@618: write(buffer, 0, idx); tikhomirov@618: } tikhomirov@618: tikhomirov@618: public void write(byte[] data, int offset, int length) throws HgIOException { tikhomirov@618: throw new HgIOException("Attempt to write to non-existent file", null); tikhomirov@618: } tikhomirov@618: tikhomirov@618: public void done() throws HgIOException { tikhomirov@618: // no-op tikhomirov@618: } tikhomirov@618: tikhomirov@618: private void ensureBufferSize(int bytesNeeded) { tikhomirov@618: if (buffer == null || buffer.length < bytesNeeded) { tikhomirov@618: buffer = new byte[bytesNeeded]; tikhomirov@534: } tikhomirov@534: } tikhomirov@534: tikhomirov@534: /** tikhomirov@534: * Writes 4 bytes of supplied value into the buffer at given offset, big-endian. tikhomirov@534: */ tikhomirov@534: public static final void bigEndian(int value, byte[] buffer, int offset) { tikhomirov@534: assert offset + 4 <= buffer.length; tikhomirov@534: buffer[offset++] = (byte) ((value >>> 24) & 0x0ff); tikhomirov@534: buffer[offset++] = (byte) ((value >>> 16) & 0x0ff); tikhomirov@534: buffer[offset++] = (byte) ((value >>> 8) & 0x0ff); tikhomirov@534: buffer[offset++] = (byte) (value & 0x0ff); tikhomirov@534: } tikhomirov@534: tikhomirov@556: /** tikhomirov@556: * Denotes an entity that wants to/could be serialized tikhomirov@556: */ tikhomirov@534: @Experimental(reason="Work in progress") tikhomirov@534: interface DataSource { tikhomirov@618: /** tikhomirov@618: * Invoked once for a single write operation, tikhomirov@618: * although the source itself may get serialized several times tikhomirov@618: */ tikhomirov@618: public void serialize(DataSerializer out) throws HgIOException; tikhomirov@534: tikhomirov@534: /** tikhomirov@534: * Hint of data length it would like to writes tikhomirov@534: * @return -1 if can't answer tikhomirov@534: */ tikhomirov@534: public int serializeLength(); tikhomirov@534: } tikhomirov@534: tikhomirov@534: public static class ByteArrayDataSource implements DataSource { tikhomirov@534: tikhomirov@534: private final byte[] data; tikhomirov@534: tikhomirov@534: public ByteArrayDataSource(byte[] bytes) { tikhomirov@534: data = bytes; tikhomirov@534: } tikhomirov@534: tikhomirov@618: public void serialize(DataSerializer out) throws HgIOException { tikhomirov@534: if (data != null) { tikhomirov@534: out.write(data, 0, data.length); tikhomirov@534: } tikhomirov@534: } tikhomirov@534: tikhomirov@534: public int serializeLength() { tikhomirov@534: return data == null ? 0 : data.length; tikhomirov@534: } tikhomirov@618: } tikhomirov@618: tikhomirov@618: public static class ByteArrayDataSerializer extends DataSerializer { tikhomirov@618: private final ByteArrayOutputStream out = new ByteArrayOutputStream(); tikhomirov@618: tikhomirov@618: @Override tikhomirov@618: public void write(byte[] data, int offset, int length) { tikhomirov@618: out.write(data, offset, length); tikhomirov@618: } tikhomirov@534: tikhomirov@618: public byte[] toByteArray() { tikhomirov@618: return out.toByteArray(); tikhomirov@618: } tikhomirov@534: } tikhomirov@534: }