-
Notifications
You must be signed in to change notification settings - Fork 0
/
Slice.java
114 lines (96 loc) · 3.61 KB
/
Slice.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import java.io.*;
class Slice {
private final static byte[] signature = {'i', 'd', 's', 'k', 'a', '3', '2', 26};
private final static byte[] zlbsignature = {'z', 'l', 'b', 26};
private String path;
private char slicenum = 'a';
private RandomAccessFile file;
private FileList list;
private boolean readSetup;
/** creates a new Slice object and reads the first Slice */
public Slice(String path, FileList list) throws InvalidFileException, FileNotFoundException {
this (path, list, false);
}
public Slice(String path, FileList list, boolean readSetup) throws InvalidFileException, FileNotFoundException {
this.list = list;
this.path = path;
this.readSetup = readSetup;
next();
}
private void next() throws InvalidFileException, FileNotFoundException {
try {
if (readSetup) {
String fileName = path;
file = new RandomAccessFile(fileName, "r");
readSetup = false;
} else {
String fileName = path+"/setup-1"+slicenum+".bin";
if (!new File(fileName).exists()) // setup- does not exist, trying setup_ (fixes a bug reported by Ignaz Forster)
fileName = path+"/setup_1"+slicenum+".bin";
slicenum++;
if (file != null)
file.close();
file = new RandomAccessFile(fileName, "r");
/* Slice file format:
* first 8 bytes contain the signature "idska32"+26
* then a 4 byte 32 bit integer follows which contains the length of the Slice file
*/
if (!Util.isByteArrayEqual(Util.readBytes(file, signature.length), signature))
throw new InvalidFileException("Wrong signature");
if (Util.littleEndianToInt(Util.readBytes(file, 4)) != new File(fileName).length()) //TODO do we really need an extra file handle?
throw new InvalidFileException("Wrong filesize");
}
} catch (IOException e) {
throw new InvalidFileException(e.getMessage());
}
}
/** reads data for <b>f</b> from Slice.
* If the file is continued in the next Slice, the next Slice is opened and the old Slice is closed.<br/>
* <b>Warning</b>: The file must not span across more than 2 slices and must begin in the open Slice!
*/
private FileData readFile(FileList.FileLocation f) throws InvalidFileException, FileNotFoundException, IOException {
byte[] tmp = new byte[f.compressedSize];
byte[] props = new byte[5];
synchronized (this) {
file.seek(f.startOffset);
/* the begin of a new file is marked with the signature "zlb"+26 */
if (!Util.isByteArrayEqual(Util.readBytes(file, zlbsignature.length), zlbsignature)) {
throw new InvalidFileException("Wrong zlbsignature");
}
file.read(props);
if (f.firstSlice != f.lastSlice) { // TODO files with more than 2 slices?
int firstlen = (int)file.length()-f.startOffset-zlbsignature.length-5; // TODO examine these 5 bytes
int lastlen = f.compressedSize-firstlen;
byte[] first = new byte[firstlen];
file.read(first);
next();
byte[] last = new byte[lastlen];
file.read(last);
System.arraycopy(first, 0, tmp, 0 ,firstlen);
System.arraycopy(last, 0, tmp, firstlen, lastlen);
} else {
file.read(tmp);
}
}
FileData data = new FileData();
data.data = tmp;
data.props = props;
data.file = f;
return data;
}
/** reads data for next file from list. */
public FileData readNextFile() throws FileNotFoundException, InvalidFileException, IOException {
FileList.FileLocation loc = list.nextFile();
if (loc != null)
return readFile(loc);
return null;
}
public static class FileData {
/** byte properties for the lzma-decoder */
public byte[] props;
/** actual compresed data */
public byte[] data;
/** information about the file */
public FileList.FileLocation file;
}
}