Home | History | Annotate | Download | only in io
      1 package org.jf.dexlib2.writer.io;
      2 
      3 import com.google.common.collect.Lists;
      4 
      5 import javax.annotation.Nonnull;
      6 import java.io.IOException;
      7 import java.io.OutputStream;
      8 import java.util.List;
      9 
     10 /**
     11  * A deferred output stream that is stored in memory
     12  */
     13 public class MemoryDeferredOutputStream extends DeferredOutputStream {
     14     private static final int DEFAULT_BUFFER_SIZE = 16 * 1024;
     15 
     16     private final List<byte[]> buffers = Lists.newArrayList();
     17     private byte[] currentBuffer;
     18     private int currentPosition;
     19 
     20     public MemoryDeferredOutputStream() {
     21         this(DEFAULT_BUFFER_SIZE);
     22     }
     23 
     24     public MemoryDeferredOutputStream(int bufferSize) {
     25         currentBuffer = new byte[bufferSize];
     26     }
     27 
     28     @Override public void writeTo(OutputStream output) throws IOException {
     29         for (byte[] buffer: buffers) {
     30             output.write(buffer);
     31         }
     32         if (currentPosition > 0) {
     33             output.write(currentBuffer, 0, currentPosition);
     34         }
     35         buffers.clear();
     36         currentPosition = 0;
     37     }
     38 
     39     @Override public void write(int i) throws IOException {
     40         if (remaining() == 0) {
     41             buffers.add(currentBuffer);
     42             currentBuffer = new byte[currentBuffer.length];
     43             currentPosition = 0;
     44         }
     45         currentBuffer[currentPosition++] = (byte)i;
     46     }
     47 
     48     @Override public void write(byte[] bytes) throws IOException {
     49         write(bytes, 0, bytes.length);
     50     }
     51 
     52     @Override public void write(byte[] bytes, int offset, int length) throws IOException {
     53         int remaining = remaining();
     54         int written = 0;
     55         while (length - written > 0) {
     56             int toWrite = Math.min(remaining, (length - written));
     57             System.arraycopy(bytes, offset + written, currentBuffer, currentPosition, toWrite);
     58             written += toWrite;
     59             currentPosition += toWrite;
     60 
     61             remaining = remaining();
     62             if (remaining == 0) {
     63                 buffers.add(currentBuffer);
     64                 currentBuffer = new byte[currentBuffer.length];
     65                 currentPosition = 0;
     66                 remaining = currentBuffer.length;
     67             }
     68         }
     69     }
     70 
     71     private int remaining() {
     72         return currentBuffer.length - currentPosition;
     73     }
     74 
     75     @Nonnull
     76     public static DeferredOutputStreamFactory getFactory() {
     77         return getFactory(DEFAULT_BUFFER_SIZE);
     78     }
     79 
     80     @Nonnull
     81     public static DeferredOutputStreamFactory getFactory(final int bufferSize) {
     82         return new DeferredOutputStreamFactory() {
     83             @Override public DeferredOutputStream makeDeferredOutputStream() {
     84                 return new MemoryDeferredOutputStream(bufferSize);
     85             }
     86         };
     87     }
     88 }
     89