rename epublib to book,库里面包含umd
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
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<byte[]> getTitles() {
|
||||
return titles;
|
||||
}
|
||||
|
||||
private final List<byte[]> titles = new ArrayList<>();
|
||||
public List<Integer> 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<contentLengths.size()?contentLengths.get(index+1): getTotalContentLen();
|
||||
System.out.println("总长度:"+contents.size());
|
||||
System.out.println("起始值:"+st);
|
||||
System.out.println("结束值:"+end);
|
||||
byte[] bAr=new byte[end-st];
|
||||
System.arraycopy(b,st,bAr,0,bAr.length);
|
||||
return bAr;
|
||||
|
||||
}
|
||||
public String getContentString(int index) {
|
||||
return UmdUtils.unicodeBytesToString(getContent(index)).replace((char) 0x2029, '\n');
|
||||
|
||||
}
|
||||
public String getTitle(int index){
|
||||
return UmdUtils.unicodeBytesToString(titles.get(index));
|
||||
}
|
||||
|
||||
|
||||
public void buildChapters(WrapOutputStream wos) throws IOException {
|
||||
writeChaptersHead(wos);
|
||||
writeChaptersContentOffset(wos);
|
||||
writeChaptersTitles(wos);
|
||||
writeChaptersChunks(wos);
|
||||
}
|
||||
|
||||
private void writeChaptersHead(WrapOutputStream wos) throws IOException {
|
||||
wos.writeBytes('#', 0x0b, 0, 0, 0x09);
|
||||
wos.writeInt(contents.size());
|
||||
}
|
||||
|
||||
private void writeChaptersContentOffset(WrapOutputStream wos) throws IOException {
|
||||
wos.writeBytes('#', 0x83, 0, 0, 0x09);
|
||||
byte[] rb = UmdUtils.genRandomBytes(4);
|
||||
wos.writeBytes(rb); //random numbers
|
||||
wos.write('$');
|
||||
wos.writeBytes(rb); //random numbers
|
||||
|
||||
wos.writeInt(contentLengths.size() * 4 + 9); // about the count of chapters
|
||||
int offset = 0;
|
||||
for (Integer n : contentLengths) {
|
||||
wos.writeInt(offset);
|
||||
offset += n;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeChaptersTitles(WrapOutputStream wos) throws IOException {
|
||||
wos.writeBytes('#', 0x84, 0, 0x01, 0x09);
|
||||
byte[] rb = UmdUtils.genRandomBytes(4);
|
||||
wos.writeBytes(rb); //random numbers
|
||||
wos.write('$');
|
||||
wos.writeBytes(rb); //random numbers
|
||||
|
||||
int totalTitlesLen = 0;
|
||||
for (byte[] t : titles) {
|
||||
totalTitlesLen += t.length;
|
||||
}
|
||||
|
||||
// about the length of the titles
|
||||
wos.writeInt(totalTitlesLen + titles.size() + 9);
|
||||
|
||||
for (byte[] t : titles) {
|
||||
wos.writeByte(t.length);
|
||||
wos.write(t);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeChaptersChunks(WrapOutputStream wos) throws IOException {
|
||||
byte[] allContents = contents.toByteArray();
|
||||
|
||||
byte[] zero16 = new byte[16];
|
||||
Arrays.fill(zero16, 0, zero16.length, (byte) 0);
|
||||
|
||||
// write each package of content
|
||||
int startPos = 0;
|
||||
int len = 0;
|
||||
int left = 0;
|
||||
int chunkCnt = 0;
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(DEFAULT_CHUNK_INIT_SIZE + 256);
|
||||
List<byte[]> 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user