lollipop版本分开,有些新特性android5.0和6.0不支持

This commit is contained in:
kunfei
2023-03-30 08:40:58 +08:00
parent 0959e50f53
commit 3cf3231da5
258 changed files with 12817 additions and 13529 deletions
@@ -0,0 +1,88 @@
package me.ag2s.umdlib.domain;
import java.io.IOException;
import java.io.OutputStream;
import me.ag2s.umdlib.tool.WrapOutputStream;
public class UmdBook {
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
private int num;
/**
* Header Part of UMD book
*/
private UmdHeader header = new UmdHeader();
/**
* Detail chapters Part of UMD book
* (include Titles & Contents of each chapter)
*/
private UmdChapters chapters = new UmdChapters();
/**
* Cover Part of UMD book (for example, and JPEG file)
*/
private UmdCover cover = new UmdCover();
/**
* End Part of UMD book
*/
private UmdEnd end = new UmdEnd();
/**
* Build the UMD file.
*
* @param os OutputStream
* @throws IOException
*/
public void buildUmd(OutputStream os) throws IOException {
WrapOutputStream wos = new WrapOutputStream(os);
header.buildHeader(wos);
chapters.buildChapters(wos);
cover.buildCover(wos);
end.buildEnd(wos);
}
public UmdHeader getHeader() {
return header;
}
public void setHeader(UmdHeader header) {
this.header = header;
}
public UmdChapters getChapters() {
return chapters;
}
public void setChapters(UmdChapters chapters) {
this.chapters = chapters;
}
public UmdCover getCover() {
return cover;
}
public void setCover(UmdCover cover) {
this.cover = cover;
}
public UmdEnd getEnd() {
return end;
}
public void setEnd(UmdEnd end) {
this.end = end;
}
}
@@ -0,0 +1,212 @@
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;
}
}
@@ -0,0 +1,97 @@
package me.ag2s.umdlib.domain;
import java.io.File;
import java.io.IOException;
import me.ag2s.umdlib.tool.UmdUtils;
import me.ag2s.umdlib.tool.WrapOutputStream;
/**
* This is the cover part of the UMD file.
* <p>
* NOTICE: if the "coverData" is empty, it will be skipped when building UMD file.
* </P>
* There are 3 ways to load the image data:
* <ol>
* <li>new constructor function of UmdCover.</li>
* <li>use UmdCover.load function.</li>
* <li>use UmdCover.initDefaultCover, it will generate a simple image with text.</li>
* </ol>
*
* @author Ray Liang (liangguanhui@qq.com)
* 2009-12-20
*/
public class UmdCover {
private static final int DEFAULT_COVER_WIDTH = 120;
private static final int DEFAULT_COVER_HEIGHT = 160;
private byte[] coverData;
public UmdCover() {
}
public UmdCover(byte[] coverData) {
this.coverData = coverData;
}
public void load(File f) throws IOException {
this.coverData = UmdUtils.readFile(f);
}
public void load(String fileName) throws IOException {
load(new File(fileName));
}
public void initDefaultCover(String title) throws IOException {
// BufferedImage img = new BufferedImage(DEFAULT_COVER_WIDTH, DEFAULT_COVER_HEIGHT, BufferedImage.TYPE_INT_RGB);
// Graphics g = img.getGraphics();
// g.setColor(Color.BLACK);
// g.fillRect(0, 0, img.getWidth(), img.getHeight());
// g.setColor(Color.WHITE);
// g.setFont(new Font("", Font.PLAIN, 12));
//
// FontMetrics fm = g.getFontMetrics();
// int ascent = fm.getAscent();
// int descent = fm.getDescent();
// int strWidth = fm.stringWidth(title);
// int x = (img.getWidth() - strWidth) / 2;
// int y = (img.getHeight() - ascent - descent) / 2;
// g.drawString(title, x, y);
// g.dispose();
//
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
//
// JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos);
// JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(img);
// param.setQuality(0.5f, false);
// encoder.setJPEGEncodeParam(param);
// encoder.encode(img);
//
// coverData = baos.toByteArray();
}
public void buildCover(WrapOutputStream wos) throws IOException {
if (coverData == null || coverData.length == 0) {
return;
}
wos.writeBytes('#', 0x82, 0, 0x01, 0x0A, 0x01);
byte[] rb = UmdUtils.genRandomBytes(4);
wos.writeBytes(rb); //random numbers
wos.write('$');
wos.writeBytes(rb); //random numbers
wos.writeInt(coverData.length + 9);
wos.write(coverData);
}
public byte[] getCoverData() {
return coverData;
}
public void setCoverData(byte[] coverData) {
this.coverData = coverData;
}
}
@@ -0,0 +1,20 @@
package me.ag2s.umdlib.domain;
import java.io.IOException;
import me.ag2s.umdlib.tool.WrapOutputStream;
/**
* End part of UMD book, nothing to be special
*
* @author Ray Liang (liangguanhui@qq.com)
* 2009-12-20
*/
public class UmdEnd {
public void buildEnd(WrapOutputStream wos) throws IOException {
wos.writeBytes('#', 0x0C, 0, 0x01, 0x09);
wos.writeInt(wos.getWritten() + 4);
}
}
@@ -0,0 +1,164 @@
package me.ag2s.umdlib.domain;
import androidx.annotation.NonNull;
import java.io.IOException;
import me.ag2s.umdlib.tool.UmdUtils;
import me.ag2s.umdlib.tool.WrapOutputStream;
/**
* Header of UMD file.
* It includes a lot of properties of header.
* All the properties are String type.
*
* @author Ray Liang (liangguanhui@qq.com)
* 2009-12-20
*/
public class UmdHeader {
public byte getUmdType() {
return umdType;
}
public void setUmdType(byte umdType) {
this.umdType = umdType;
}
private byte umdType;
private String title;
private String author;
private String year;
private String month;
private String day;
private String bookType;
private String bookMan;
private String shopKeeper;
private final static byte B_type_umd = (byte) 0x01;
private final static byte B_type_title = (byte) 0x02;
private final static byte B_type_author = (byte) 0x03;
private final static byte B_type_year = (byte) 0x04;
private final static byte B_type_month = (byte) 0x05;
private final static byte B_type_day = (byte) 0x06;
private final static byte B_type_bookType = (byte) 0x07;
private final static byte B_type_bookMan = (byte) 0x08;
private final static byte B_type_shopKeeper = (byte) 0x09;
public void buildHeader(WrapOutputStream wos) throws IOException {
wos.writeBytes(0x89, 0x9b, 0x9a, 0xde); // UMD file type flags
wos.writeByte('#');
wos.writeBytes(0x01, 0x00, 0x00, 0x08); // Unknown
wos.writeByte(0x01); //0x01 is text type; while 0x02 is Image type.
wos.writeBytes(UmdUtils.genRandomBytes(2)); //random number
// start properties output
buildType(wos, B_type_title, getTitle());
buildType(wos, B_type_author, getAuthor());
buildType(wos, B_type_year, getYear());
buildType(wos, B_type_month, getMonth());
buildType(wos, B_type_day, getDay());
buildType(wos, B_type_bookType, getBookType());
buildType(wos, B_type_bookMan, getBookMan());
buildType(wos, B_type_shopKeeper, getShopKeeper());
}
public void buildType(WrapOutputStream wos, byte type, String content) throws IOException {
if (content == null || content.length() == 0) {
return;
}
wos.writeBytes('#', type, 0, 0);
byte[] temp = UmdUtils.stringToUnicodeBytes(content);
wos.writeByte(temp.length + 5);
wos.write(temp);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getBookMan() {
return bookMan;
}
public void setBookMan(String bookMan) {
this.bookMan = bookMan;
}
public String getShopKeeper() {
return shopKeeper;
}
public void setShopKeeper(String shopKeeper) {
this.shopKeeper = shopKeeper;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
public String getBookType() {
return bookType;
}
public void setBookType(String bookType) {
this.bookType = bookType;
}
@Override
@NonNull
public String toString() {
return "UmdHeader{" +
"umdType=" + umdType +
", title='" + title + '\'' +
", author='" + author + '\'' +
", year='" + year + '\'' +
", month='" + month + '\'' +
", day='" + day + '\'' +
", bookType='" + bookType + '\'' +
", bookMan='" + bookMan + '\'' +
", shopKeeper='" + shopKeeper + '\'' +
'}';
}
}
@@ -0,0 +1,131 @@
package me.ag2s.umdlib.tool;
import java.io.IOException;
import java.io.InputStream;
public class StreamReader {
private final InputStream is;
public long getOffset() {
return offset;
}
public void setOffset(long offset) {
this.offset = offset;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
private long offset;
private long size;
private void incCount(int value) {
int temp = (int) (offset + value);
if (temp < 0) {
temp = Integer.MAX_VALUE;
}
offset = temp;
}
public StreamReader(InputStream inputStream) throws IOException {
this.is = inputStream;
//this.size=inputStream.getChannel().size();
}
public short readUint8() throws IOException {
byte[] b = new byte[1];
is.read(b);
incCount(1);
return (short) ((b[0] & 0xFF));
}
public byte readByte() throws IOException {
byte[] b = new byte[1];
is.read(b);
incCount(1);
return b[0];
}
public byte[] readBytes(int len) throws IOException {
if (len < 1) {
System.out.println(len);
throw new IllegalArgumentException("Length must > 0: " + len);
}
byte[] b = new byte[len];
is.read(b);
incCount(len);
return b;
}
public String readHex(int len) throws IOException {
if (len < 1) {
System.out.println(len);
throw new IllegalArgumentException("Length must > 0: " + len);
}
byte[] b = new byte[len];
is.read(b);
incCount(len);
return UmdUtils.toHex(b);
}
public short readShort() throws IOException {
byte[] b = new byte[2];
is.read(b);
incCount(2);
short x = (short) (((b[0] & 0xFF) << 8) | ((b[1] & 0xFF) << 0));
return x;
}
public short readShortLe() throws IOException {
byte[] b = new byte[2];
is.read(b);
incCount(2);
short x = (short) (((b[1] & 0xFF) << 8) | ((b[0] & 0xFF) << 0));
return x;
}
public int readInt() throws IOException {
byte[] b = new byte[4];
is.read(b);
incCount(4);
int x = ((b[0] & 0xFF) << 24) | ((b[1] & 0xFF) << 16) |
((b[2] & 0xFF) << 8) | ((b[3] & 0xFF) << 0);
return x;
}
public int readIntLe() throws IOException {
byte[] b = new byte[4];
is.read(b);
incCount(4);
int x = ((b[3] & 0xFF) << 24) | ((b[2] & 0xFF) << 16) |
((b[1] & 0xFF) << 8) | ((b[0] & 0xFF) << 0);
return x;
}
public void skip(int len) throws IOException {
readBytes(len);
}
public byte[] read(byte[] b) throws IOException {
is.read(b);
incCount(b.length);
return b;
}
public byte[] read(byte[] b, int off, int len) throws IOException {
is.read(b, off, len);
incCount(len);
return b;
}
}
@@ -0,0 +1,155 @@
package me.ag2s.umdlib.tool;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.zip.InflaterInputStream;
public class UmdUtils {
private static final int EOF = -1;
private static final int BUFFER_SIZE = 8 * 1024;
/**
* 将字符串编码成Unicode形式的byte[]
*
* @param s 要编码的字符串
* @return 编码好的byte[]
*/
public static byte[] stringToUnicodeBytes(String s) {
if (s == null) {
throw new NullPointerException();
}
int len = s.length();
byte[] ret = new byte[len * 2];
int a, b, c;
for (int i = 0; i < len; i++) {
c = s.charAt(i);
a = c >> 8;
b = c & 0xFF;
if (a < 0) {
a += 0xFF;
}
if (b < 0) {
b += 0xFF;
}
ret[i * 2] = (byte) b;
ret[i * 2 + 1] = (byte) a;
}
return ret;
}
/**
* 将编码成Unicode形式的byte[]解码成原始字符串
*
* @param bytes 编码成Unicode形式的byte[]
* @return 原始字符串
*/
public static String unicodeBytesToString(byte[] bytes) {
char[] s = new char[bytes.length / 2];
StringBuilder sb = new StringBuilder();
int a, b, c;
for (int i = 0; i < s.length; i++) {
a = bytes[i * 2 + 1];
b = bytes[i * 2];
c = (a & 0xff) << 8 | (b & 0xff);
if (c < 0) {
c += 0xffff;
}
char[] c1 = Character.toChars(c);
sb.append(c1);
}
return sb.toString();
}
/**
* 将byte[]转化成Hex形式
*
* @param bArr byte[]
* @return 目标HEX字符串
*/
public static String toHex(byte[] bArr) {
StringBuilder sb = new StringBuilder(bArr.length);
String sTmp;
for (int i = 0; i < bArr.length; i++) {
sTmp = Integer.toHexString(0xFF & bArr[i]);
if (sTmp.length() < 2)
sb.append(0);
sb.append(sTmp.toUpperCase());
}
return sb.toString();
}
/**
* 解压缩zip的byte[]
*
* @param compress zippered byte[]
* @return decompressed byte[]
* @throws Exception 解码时失败时
*/
public static byte[] decompress(byte[] compress) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(compress);
InflaterInputStream iis = new InflaterInputStream(bais);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int c = 0;
byte[] buf = new byte[BUFFER_SIZE];
while (true) {
c = iis.read(buf);
if (c == EOF)
break;
baos.write(buf, 0, c);
}
baos.flush();
return baos.toByteArray();
}
public static void saveFile(File f, byte[] content) throws IOException {
try (FileOutputStream fos = new FileOutputStream(f)) {
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(content);
bos.flush();
}
}
public static byte[] readFile(File f) throws IOException {
try (FileInputStream fis = new FileInputStream(f)) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedInputStream bis = new BufferedInputStream(fis);
int ch;
while ((ch = bis.read()) >= 0) {
baos.write(ch);
}
baos.flush();
return baos.toByteArray();
}
}
private static final Random random = new Random();
public static byte[] genRandomBytes(int len) {
if (len <= 0) {
throw new IllegalArgumentException("Length must > 0: " + len);
}
byte[] ret = new byte[len];
for (int i = 0; i < ret.length; i++) {
ret[i] = (byte) random.nextInt(256);
}
return ret;
}
}
@@ -0,0 +1,91 @@
package me.ag2s.umdlib.tool;
import java.io.IOException;
import java.io.OutputStream;
public class WrapOutputStream extends OutputStream {
private final OutputStream os;
private int written;
public WrapOutputStream(OutputStream os) {
this.os = os;
}
private void incCount(int value) {
int temp = written + value;
if (temp < 0) {
temp = Integer.MAX_VALUE;
}
written = temp;
}
// it is different from the writeInt of DataOutputStream
public void writeInt(int v) throws IOException {
os.write((v >>> 0) & 0xFF);
os.write((v >>> 8) & 0xFF);
os.write((v >>> 16) & 0xFF);
os.write((v >>> 24) & 0xFF);
incCount(4);
}
public void writeByte(byte b) throws IOException {
write(b);
}
public void writeByte(int n) throws IOException {
write(n);
}
public void writeBytes(byte... bytes) throws IOException {
write(bytes);
}
public void writeBytes(int... vals) throws IOException {
for (int v : vals) {
write(v);
}
}
public void write(byte[] b, int off, int len) throws IOException {
os.write(b, off, len);
incCount(len);
}
public void write(byte[] b) throws IOException {
os.write(b);
incCount(b.length);
}
public void write(int b) throws IOException {
os.write(b);
incCount(1);
}
/////////////////////////////////////////////////
public void close() throws IOException {
os.close();
}
public void flush() throws IOException {
os.flush();
}
public boolean equals(Object obj) {
return os.equals(obj);
}
public int hashCode() {
return os.hashCode();
}
public String toString() {
return os.toString();
}
public int getWritten() {
return written;
}
}
@@ -0,0 +1,223 @@
package me.ag2s.umdlib.umd;
import androidx.annotation.NonNull;
import java.io.IOException;
import java.io.InputStream;
import me.ag2s.umdlib.domain.UmdBook;
import me.ag2s.umdlib.domain.UmdCover;
import me.ag2s.umdlib.domain.UmdHeader;
import me.ag2s.umdlib.tool.StreamReader;
import me.ag2s.umdlib.tool.UmdUtils;
/**
* UMD格式的电子书解析
* 格式规范参考:
* http://blog.sina.com.cn/s/blog_7c8dc2d501018o5d.html
* http://blog.sina.com.cn/s/blog_7c8dc2d501018o5l.html
*/
public class UmdReader {
UmdBook book;
InputStream inputStream;
int _AdditionalCheckNumber;
int _TotalContentLen;
boolean end = false;
public synchronized UmdBook read(InputStream inputStream) throws Exception {
book = new UmdBook();
this.inputStream = inputStream;
StreamReader reader = new StreamReader(inputStream);
UmdHeader umdHeader = new UmdHeader();
book.setHeader(umdHeader);
if (reader.readIntLe() != 0xde9a9b89) {
throw new IOException("Wrong header");
}
short num1 = -1;
byte ch = reader.readByte();
while (ch == 35) {
//int num2=reader.readByte();
short segType = reader.readShortLe();
byte segFlag = reader.readByte();
short len = (short) (reader.readUint8() - 5);
System.out.println("块标识:" + segType);
//short length1 = reader.readByte();
readSection(segType, segFlag, len, reader, umdHeader);
if ((int) segType == 241 || (int) segType == 10) {
segType = num1;
}
for (ch = reader.readByte(); ch == 36; ch = reader.readByte()) {
//int num3 = reader.readByte();
System.out.println(ch);
int additionalCheckNumber = reader.readIntLe();
int length2 = (reader.readIntLe() - 9);
readAdditionalSection(segType, additionalCheckNumber, length2, reader);
}
num1 = segType;
}
System.out.println(book.getHeader().toString());
return book;
}
private void readAdditionalSection(short segType, int additionalCheckNumber, int length, StreamReader reader) throws Exception {
switch (segType) {
case 14:
//this._TotalImageList.Add((object) Image.FromStream((Stream) new MemoryStream(reader.ReadBytes((int) length))));
break;
case 15:
//this._TotalImageList.Add((object) Image.FromStream((Stream) new MemoryStream(reader.ReadBytes((int) length))));
break;
case 129:
reader.readBytes(length);
break;
case 130:
//byte[] covers = reader.readBytes(length);
book.setCover(new UmdCover(reader.readBytes(length)));
//this._Book.Cover = BitmapImage.FromStream((Stream) new MemoryStream(reader.ReadBytes((int) length)));
break;
case 131:
System.out.println(length / 4);
book.setNum(length / 4);
for (int i = 0; i < length / 4; ++i) {
book.getChapters().addContentLength(reader.readIntLe());
}
break;
case 132:
//System.out.println(length/4);
System.out.println(_AdditionalCheckNumber);
System.out.println(additionalCheckNumber);
if (this._AdditionalCheckNumber != additionalCheckNumber) {
System.out.println(length);
book.getChapters().contents.write(UmdUtils.decompress(reader.readBytes(length)));
book.getChapters().contents.flush();
break;
} else {
for (int i = 0; i < book.getNum(); i++) {
short len = reader.readUint8();
byte[] title = reader.readBytes(len);
//System.out.println(UmdUtils.unicodeBytesToString(title));
book.getChapters().addTitle(title);
}
}
break;
default:
/*Console.WriteLine("未知内容");
Console.WriteLine("Seg Type = " + (object) segType);
Console.WriteLine("Seg Len = " + (object) length);
Console.WriteLine("content = " + (object) reader.ReadBytes((int) length));*/
break;
}
}
public void readSection(short segType, byte segFlag, short length, StreamReader reader, UmdHeader header) throws IOException {
switch (segType) {
case 1://umd文件头 DCTS_CMD_ID_VERSION
header.setUmdType(reader.readByte());
reader.readBytes(2);//Random 2
System.out.println("UMD文件类型:" + header.getUmdType());
break;
case 2://文件标题 DCTS_CMD_ID_TITLE
header.setTitle(UmdUtils.unicodeBytesToString(reader.readBytes(length)));
System.out.println("文件标题:" + header.getTitle());
break;
case 3://作者
header.setAuthor(UmdUtils.unicodeBytesToString(reader.readBytes(length)));
System.out.println("作者:" + header.getAuthor());
break;
case 4://年
header.setYear(UmdUtils.unicodeBytesToString(reader.readBytes(length)));
System.out.println("年:" + header.getYear());
break;
case 5://月
header.setMonth(UmdUtils.unicodeBytesToString(reader.readBytes(length)));
System.out.println("月:" + header.getMonth());
break;
case 6://日
header.setDay(UmdUtils.unicodeBytesToString(reader.readBytes(length)));
System.out.println("日:" + header.getDay());
break;
case 7://小说类型
header.setBookType(UmdUtils.unicodeBytesToString(reader.readBytes(length)));
System.out.println("小说类型:" + header.getBookType());
break;
case 8://出版商
header.setBookMan(UmdUtils.unicodeBytesToString(reader.readBytes(length)));
System.out.println("出版商:" + header.getBookMan());
break;
case 9:// 零售商
header.setShopKeeper(UmdUtils.unicodeBytesToString(reader.readBytes(length)));
System.out.println("零售商:" + header.getShopKeeper());
break;
case 10://CONTENT ID
System.out.println("CONTENT ID:" + reader.readHex(length));
break;
case 11:
//内容长度 DCTS_CMD_ID_FILE_LENGTH
_TotalContentLen = reader.readIntLe();
book.getChapters().setTotalContentLen(_TotalContentLen);
System.out.println("内容长度:" + _TotalContentLen);
break;
case 12://UMD文件结束
end = true;
int num2 = reader.readIntLe();
System.out.println("整个文件长度" + num2);
break;
case 13:
break;
case 14:
int num3 = reader.readByte();
break;
case 15:
reader.readBytes(length);
break;
case 129://正文
case 131://章节偏移
_AdditionalCheckNumber = reader.readIntLe();
System.out.println("章节偏移:" + _AdditionalCheckNumber);
break;
case 132://章节标题,正文
_AdditionalCheckNumber = reader.readIntLe();
System.out.println("章节标题,正文:" + _AdditionalCheckNumber);
break;
case 130://封面(jpg
int num4 = reader.readByte();
_AdditionalCheckNumber = reader.readIntLe();
break;
case 135://页面偏移(Page Offset
reader.readUint8();//fontSize 一字节 字体大小
reader.readUint8();//screenWidth 屏幕宽度
reader.readBytes(4);//BlockRandom 指向一个页面偏移数据块
break;
case 240://CDS KEY
break;
case 241://许可证(LICENCE KEY)
//System.out.println("整个文件长度" + length);
System.out.println("许可证(LICENCE KEY):" + reader.readHex(16));
break;
default:
if (length > 0) {
byte[] numArray = reader.readBytes(length);
}
}
}
@Override
@NonNull
public String toString() {
return "UmdReader{" +
"book=" + book +
'}';
}
}