package org.jf.dexlib2.writer.io; import javax.annotation.Nonnull; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; public class MemoryDataStore implements DexDataStore { private byte[] buf; public MemoryDataStore() { this(1024 * 1024); } public MemoryDataStore(int initialCapacity) { buf = new byte[initialCapacity]; } public byte[] getData() { return buf; } @Nonnull @Override public OutputStream outputAt(final int offset) { return new OutputStream() { private int position = offset; @Override public void write(int b) throws IOException { growBufferIfNeeded(position); buf[position++] = (byte)b; } @Override public void write(byte[] b) throws IOException { growBufferIfNeeded(position + b.length); System.arraycopy(b, 0, buf, position, b.length); position += b.length; } @Override public void write(byte[] b, int off, int len) throws IOException { growBufferIfNeeded(position + len); System.arraycopy(b, off, buf, position, len); position += len; } }; } private void growBufferIfNeeded(int index) { if (index < buf.length) { return; } buf = Arrays.copyOf(buf, (int)((index + 1) * 1.2)); } @Nonnull @Override public InputStream readAt(final int offset) { return new InputStream() { private int position = offset; @Override public int read() throws IOException { if (position >= buf.length) { return -1; } return buf[position++]; } @Override public int read(byte[] b) throws IOException { int readLength = Math.min(b.length, buf.length - position); if (readLength <= 0) { if (position >= buf.length) { return -1; } return 0; } System.arraycopy(buf, position, b, 0, readLength); position += readLength; return readLength; } @Override public int read(byte[] b, int off, int len) throws IOException { int readLength = Math.min(len, buf.length - position); if (readLength <= 0) { if (position >= buf.length) { return -1; } return 0; } System.arraycopy(buf, position, b, 0, readLength); position += readLength; return readLength; } @Override public long skip(long n) throws IOException { int skipLength = (int)Math.min(n, buf.length - position); position += skipLength; return skipLength; } @Override public int available() throws IOException { return buf.length - position; } }; } @Override public void close() throws IOException { // no-op } }