16762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverpackage org.jf.dexlib2.writer.io;
26762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
36762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverimport javax.annotation.Nonnull;
46762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverimport java.io.IOException;
56762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverimport java.io.InputStream;
66762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverimport java.io.OutputStream;
76762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverimport java.util.Arrays;
86762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
96762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverpublic class MemoryDataStore implements DexDataStore {
106762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    private byte[] buf;
116762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
126762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    public MemoryDataStore() {
136762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        this(1024 * 1024);
146762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    }
156762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
166762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    public MemoryDataStore(int initialCapacity) {
176762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        buf = new byte[initialCapacity];
186762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    }
196762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
206762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    public byte[] getData() {
216762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        return buf;
226762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    }
236762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
246762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    @Nonnull @Override public OutputStream outputAt(final int offset) {
256762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        return new OutputStream() {
266762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            private int position = offset;
276762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            @Override public void write(int b) throws IOException {
286762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                growBufferIfNeeded(position);
296762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                buf[position++] = (byte)b;
306762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            }
316762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
326762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            @Override public void write(byte[] b) throws IOException {
336762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                growBufferIfNeeded(position + b.length);
346762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                System.arraycopy(b, 0, buf, position, b.length);
356762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                position += b.length;
366762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            }
376762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
386762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            @Override public void write(byte[] b, int off, int len) throws IOException {
396762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                growBufferIfNeeded(position + len);
406762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                System.arraycopy(b, off, buf, position, len);
416762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                position += len;
426762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            }
436762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        };
446762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    }
456762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
466762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    private void growBufferIfNeeded(int index) {
476762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        if (index < buf.length) {
486762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            return;
496762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        }
506762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        buf = Arrays.copyOf(buf, (int)((index + 1) * 1.2));
516762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    }
526762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
536762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    @Nonnull @Override public InputStream readAt(final int offset) {
546762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        return new InputStream() {
556762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            private int position = offset;
566762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
576762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            @Override public int read() throws IOException {
586762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                if (position >= buf.length) {
596762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                    return -1;
606762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                }
616762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                return buf[position++];
626762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            }
636762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
646762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            @Override public int read(byte[] b) throws IOException {
656762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                int readLength = Math.min(b.length, buf.length - position);
666762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                if (readLength <= 0) {
676762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                    if (position >= buf.length) {
686762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                        return -1;
696762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                    }
706762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                    return 0;
716762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                }
726762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                System.arraycopy(buf, position, b, 0, readLength);
736762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                position += readLength;
746762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                return readLength;
756762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            }
766762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
776762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            @Override public int read(byte[] b, int off, int len) throws IOException {
786762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                int readLength = Math.min(len, buf.length - position);
796762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                if (readLength <= 0) {
806762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                    if (position >= buf.length) {
816762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                        return -1;
826762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                    }
836762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                    return 0;
846762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                }
856762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                System.arraycopy(buf, position, b, 0, readLength);
866762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                position += readLength;
876762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                return readLength;
886762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            }
896762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
906762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            @Override public long skip(long n) throws IOException {
916762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                int skipLength = (int)Math.min(n, buf.length - position);
926762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                position += skipLength;
936762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                return skipLength;
946762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            }
956762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
966762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            @Override public int available() throws IOException {
976762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                return buf.length - position;
986762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver            }
996762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        };
1006762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    }
1016762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
1026762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    @Override public void close() throws IOException {
1036762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver        // no-op
1046762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    }
1056762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver}
106