package me.ag2s.umdlib.domain; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.zip.DeflaterOutputStream; import me.ag2s.umdlib.tool.UmdUtils; import me.ag2s.umdlib.tool.WrapOutputStream; /** * It includes all titles and contents of each chapter in the UMD file. * And the content has been compressed by zlib. * * @author Ray Liang (liangguanhui@qq.com) * 2009-12-20 */ public class UmdChapters { private static final int DEFAULT_CHUNK_INIT_SIZE = 32768; private int TotalContentLen; public List getTitles() { return titles; } private final List titles = new ArrayList<>(); public List contentLengths = new ArrayList<>(); public ByteArrayOutputStream contents = new ByteArrayOutputStream(); public void addTitle(String s){ titles.add(UmdUtils.stringToUnicodeBytes(s)); } public void addTitle(byte[] s){ titles.add(s); } public void addContentLength(Integer integer){ contentLengths.add(integer); } public int getContentLength(int index){ return contentLengths.get(index); } public byte[] getContent(int index) { int st=contentLengths.get(index); byte[] b=contents.toByteArray(); int end=index+1 chunkRbList = new ArrayList(); while(startPos < allContents.length) { left = allContents.length - startPos; len = Math.min(DEFAULT_CHUNK_INIT_SIZE, left); bos.reset(); DeflaterOutputStream zos = new DeflaterOutputStream(bos); zos.write(allContents, startPos, len); zos.close(); byte[] chunk = bos.toByteArray(); byte[] rb = UmdUtils.genRandomBytes(4); wos.writeByte('$'); wos.writeBytes(rb); // 4 random chunkRbList.add(rb); wos.writeInt(chunk.length + 9); wos.write(chunk); // end of each chunk wos.writeBytes('#', 0xF1, 0, 0, 0x15); wos.write(zero16); startPos += len; chunkCnt++; } // end of all chunks wos.writeBytes('#', 0x81, 0, 0x01, 0x09); wos.writeBytes(0, 0, 0, 0); //random numbers wos.write('$'); wos.writeBytes(0, 0, 0, 0); //random numbers wos.writeInt(chunkCnt * 4 + 9); for (int i = chunkCnt - 1; i >= 0; i--) { // random. They are as the same as random numbers in the begin of each chunk // use desc order to output these random wos.writeBytes(chunkRbList.get(i)); } } public void addChapter(String title, String content) { titles.add(UmdUtils.stringToUnicodeBytes(title)); byte[] b = UmdUtils.stringToUnicodeBytes(content); contentLengths.add(b.length); try { contents.write(b); } catch (IOException e) { throw new RuntimeException(e); } } public void addFile(File f, String title) throws IOException { byte[] temp = UmdUtils.readFile(f); String s = new String(temp); addChapter(title, s); } public void addFile(File f) throws IOException { String s = f.getName(); int idx = s.lastIndexOf('.'); if (idx >= 0) { s = s.substring(0, idx); } addFile(f, s); } public void clearChapters() { titles.clear(); contentLengths.clear(); contents.reset(); } public int getTotalContentLen() { return TotalContentLen; } public void setTotalContentLen(int totalContentLen) { TotalContentLen = totalContentLen; } }