package yuku.alkitab.yes2.compress;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import yuku.snappy.codec.Snappy;

public class SnappyOutputStream extends FilterOutputStream {
	public final String TAG = SnappyOutputStream.class.getSimpleName();
	
	private final Snappy snappy;
	private final int block_size; 
	private byte[] uncompressed_buf;
	private byte[] compressed_buf;
	private int uncompressed_offset;
	private List<Integer> compressed_block_sizes = new ArrayList<Integer>();

	public SnappyOutputStream(OutputStream out, int block_size) {
		super(out);
		this.snappy = new Snappy.Factory().newInstance();
		this.block_size = block_size;
		this.uncompressed_buf = new byte[block_size];
		this.compressed_buf = new byte[snappy.maxCompressedLength(uncompressed_buf.length)];
	}

	@Override public void write(int b) throws IOException {
		if (uncompressed_offset >= block_size) {
			dump();
		}
		
		uncompressed_buf[uncompressed_offset++] = (byte) b;
	}
	
	@Override public void write(byte[] b, int off, int len) throws IOException {
		int remaining = len;
		int src_off = off;
		
		while (remaining > 0) {
			int can_write = block_size - uncompressed_offset;
			int will_write = Math.min(remaining, can_write);
			
			System.arraycopy(b, src_off, uncompressed_buf, uncompressed_offset, will_write);
			uncompressed_offset += will_write;
			src_off += will_write;
			remaining -= will_write;
			
			if (uncompressed_offset >= block_size) {
				dump();
			}
		}
		
		assert src_off == off + len;
	}
	
	private void dump() throws IOException {
		if (uncompressed_offset > 0) {
			int compressed_len = snappy.compress(uncompressed_buf, 0, compressed_buf, 0, uncompressed_offset);
			out.write(compressed_buf, 0, compressed_len);
			compressed_block_sizes.add(compressed_len);
			uncompressed_offset = 0;
		}
	}
	
	@Override public void flush() throws IOException {
		dump();
		out.flush();
	}
	
	public int[] getCompressedBlockSizes() {
		int[] res = new int[compressed_block_sizes.size()];
		for (int i = 0; i < res.length; i++) {
			res[i] = compressed_block_sizes.get(i);
		}
		return res;
	}
}
@@ -122,33 +122,50 @@
 Stream;%0A
+%0A
 import 
-java
+yuku.alkitab.base
 .util.
+Int
 ArrayLis
@@ -171,32 +171,8 @@
 st;%0A
-import java.util.List;%0A%0A
 impo
@@ -504,29 +504,28 @@
 private 
-List%3CInteger%3E
+IntArrayList
  compres
@@ -546,16 +546,19 @@
 s = new 
+Int
 ArrayLis
@@ -562,17 +562,8 @@
 List
-%3CInteger%3E
 ();%0A
@@ -2078,93 +2078,81 @@
 ;%0A%09%09
-for (int i = 0; i %3C res.length; i++) %7B%0A%09%09%09res%5Bi%5D = compressed_block_sizes.get(i);%0A%09%09%7D
+System.arraycopy(compressed_block_sizes.buffer(), 0, res, 0, res.length);
 %0A%09%09r

Use IntArrayList instead of List<Integer>