RuneHive-Game
Loading...
Searching...
No Matches
dev.advo.fs.fs.IndexedFileSystem Class Reference

A file system based on top of the operating system's file system. More...

Inheritance diagram for dev.advo.fs.fs.IndexedFileSystem:
Collaboration diagram for dev.advo.fs.fs.IndexedFileSystem:

Public Member Functions

void close () throws IOException
ByteBuffer getCrcTable () throws IOException
 Gets the CRC table.
ByteBuffer getFile (FileDescriptor fd) throws IOException
 Gets a file.
ByteBuffer getFile (int type, int file) throws IOException
 Gets a file.
ByteBuffer getJireCRCTable () throws IOException
 IndexedFileSystem (File base, boolean readOnly) throws Exception
 Creates the file system with the specified base directory.
boolean isReadOnly ()
 Checks if this IndexedFileSystem is read only.

Static Public Member Functions

static byte[] gzip (byte[] bytes) throws IOException
 Compresses a GZIP file.

Static Public Attributes

static byte[] bytes

Private Member Functions

void detectLayout (File base) throws Exception
 Automatically detect the layout of the specified directory.
int getFileCount (int type) throws IOException
 Gets the number of files with the specified type.
Index getIndex (FileDescriptor fd) throws IOException
 Gets the index of a file.
byte[] initialResponse () throws IOException

Private Attributes

ByteBuffer crcTable
 The cached CRC table.
RandomAccessFile data
 The data file.
RandomAccessFile[] indices = new RandomAccessFile[256]
 The index files.
final boolean readOnly
 Read only flag.

Detailed Description

A file system based on top of the operating system's file system.

It consists of a data file and index files. Index files point to blocks in the data file, which contains the actual data.

Author
Graham

Definition at line 20 of file IndexedFileSystem.java.

Constructor & Destructor Documentation

◆ IndexedFileSystem()

dev.advo.fs.fs.IndexedFileSystem.IndexedFileSystem ( File base,
boolean readOnly ) throws Exception

Creates the file system with the specified base directory.

Parameters
baseThe base directory.
readOnlyA flag indicating if the file system will be read only.
Exceptions
Exceptionif the file system is invalid.

Definition at line 48 of file IndexedFileSystem.java.

48 {
49 this.readOnly = readOnly;
50 detectLayout(base);
51 }

References detectLayout(), and readOnly.

Here is the call graph for this function:

Member Function Documentation

◆ close()

void dev.advo.fs.fs.IndexedFileSystem.close ( ) throws IOException

Definition at line 443 of file IndexedFileSystem.java.

443 {
444 if (data != null) {
445 synchronized (data) {
446 data.close();
447 }
448 }
449
450 for (RandomAccessFile index : indices) {
451 if (index != null) {
452 synchronized (index) {
453 index.close();
454 }
455 }
456 }
457 }
val index

References data, and indices.

◆ detectLayout()

void dev.advo.fs.fs.IndexedFileSystem.detectLayout ( File base) throws Exception
private

Automatically detect the layout of the specified directory.

Parameters
baseThe base directory.
Exceptions
Exceptionif the file system is invalid.

Definition at line 66 of file IndexedFileSystem.java.

66 {
67 int indexCount = 0;
68 for (int index = 0; index < indices.length; index++) {
69 File f = new File(base.getAbsolutePath() + "/main_file_cache.idx" + index);
70 if (f.exists() && !f.isDirectory()) {
71 indexCount++;
72 indices[index] = new RandomAccessFile(f, readOnly ? "r" : "rw");
73 }
74 }
75 if (indexCount <= 0) {
76 throw new Exception("No index file(s) present");
77 }
78
79 File oldEngineData = new File(base.getAbsolutePath() + "/main_file_cache.dat");
80 File newEngineData = new File(base.getAbsolutePath() + "/main_file_cache.dat2");
81 if (oldEngineData.exists() && !oldEngineData.isDirectory()) {
82 data = new RandomAccessFile(oldEngineData, readOnly ? "r" : "rw");
83 } else if (newEngineData.exists() && !oldEngineData.isDirectory()) {
84 data = new RandomAccessFile(newEngineData, readOnly ? "r" : "rw");
85 } else {
86 throw new Exception("No data file present");
87 }
88 if(bytes == null) {
89 bytes = initialResponse();
90 }
91 }

References bytes, data, indices, initialResponse(), and readOnly.

Referenced by IndexedFileSystem().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCrcTable()

ByteBuffer dev.advo.fs.fs.IndexedFileSystem.getCrcTable ( ) throws IOException

Gets the CRC table.

Returns
The CRC table.
Exceptions
IOExceptionif an I/O erorr occurs.

Definition at line 144 of file IndexedFileSystem.java.

144 {
145 if (readOnly) {
146 synchronized (this) {
147 if (crcTable != null) {
148 return crcTable.slice();
149 }
150 }
151
152 // the number of archives
153 int archives = getFileCount(0);
154
155 // the hash
156 int hash = 1234;
157
158 // the CRCs
159 int[] crcs = new int[archives];
160
161 // calculate the CRCs
162 CRC32 crc32 = new CRC32();
163 for (int i = 1; i < crcs.length; i++) {
164 crc32.reset();
165
166 ByteBuffer bb = getFile(0, i);
167 byte[] bytes = new byte[bb.remaining()];
168 bb.get(bytes, 0, bytes.length);
169 crc32.update(bytes, 0, bytes.length);
170
171 crcs[i] = (int) crc32.getValue();
172 }
173
174 // hash the CRCs and place them in the buffer
175 ByteBuffer buf = ByteBuffer.allocate(crcs.length * 4 + 4);
176 for (int i = 0; i < crcs.length; i++) {
177 hash = (hash << 1) + crcs[i];
178 buf.putInt(crcs[i]);
179 }
180
181 // place the hash into the buffer
182 buf.putInt(hash);
183 buf.flip();
184
185 synchronized (this) {
186 crcTable = buf;
187 return crcTable.slice();
188 }
189 } else {
190 throw new IOException("cannot get CRC table from a writable file system");
191 }
192 }

References bytes, crcTable, getFile(), getFileCount(), and readOnly.

Here is the call graph for this function:

◆ getFile() [1/2]

ByteBuffer dev.advo.fs.fs.IndexedFileSystem.getFile ( FileDescriptor fd) throws IOException

Gets a file.

Parameters
fdThe FileDescriptor which points to the file.
Returns
A ByteBuffer which contains the contents of the file.
Exceptions
IOExceptionif an I/O error occurs.

Definition at line 371 of file IndexedFileSystem.java.

371 {
372 Index index = getIndex(fd);
373 ByteBuffer buffer = ByteBuffer.allocate(index.getSize());
374
375 // calculate some initial values
376 long ptr = (long) index.getBlock() * (long) FileSystemConstants.BLOCK_SIZE;
377 int read = 0;
378 int size = index.getSize();
379 int blocks = size / FileSystemConstants.CHUNK_SIZE;
380 if (size % FileSystemConstants.CHUNK_SIZE != 0) {
381 blocks++;
382 }
383
384 for (int i = 0; i < blocks; i++) {
385
386 // read header
387 byte[] header = new byte[FileSystemConstants.HEADER_SIZE];
388 synchronized (data) {
389 data.seek(ptr);
390 data.readFully(header);
391 }
392
393 // increment pointers
394 ptr += FileSystemConstants.HEADER_SIZE;
395
396 // parse header
397 int nextFile = ((header[0] & 0xFF) << 8) | (header[1] & 0xFF);
398 int curChunk = ((header[2] & 0xFF) << 8) | (header[3] & 0xFF);
399 int nextBlock = ((header[4] & 0xFF) << 16) | ((header[5] & 0xFF) << 8) | (header[6] & 0xFF);
400 int nextType = header[7] & 0xFF;
401
402 // check expected chunk id is correct
403 if (i != curChunk) {
404 throw new IOException("Chunk id mismatch.");
405 }
406
407 // calculate how much we can read
408 int chunkSize = size - read;
409 if (chunkSize > FileSystemConstants.CHUNK_SIZE) {
410 chunkSize = FileSystemConstants.CHUNK_SIZE;
411 }
412
413 // read the next chunk and put it in the buffer
414 byte[] chunk = new byte[chunkSize];
415 synchronized (data) {
416 data.seek(ptr);
417 data.readFully(chunk);
418 }
419 buffer.put(chunk);
420
421 // increment pointers
422 read += chunkSize;
423 ptr = (long) nextBlock * (long) FileSystemConstants.BLOCK_SIZE;
424
425 // if we still have more data to read, check the validity of the
426 // header
427 if (size > read) {
428 if (nextType != (fd.getType() + 1)) {
429 throw new IOException("File type mismatch.");
430 }
431
432 if (nextFile != fd.getFile()) {
433 throw new IOException("File id mismatch.");
434 }
435 }
436 }
437
438 buffer.flip();
439 return buffer;
440 }

References dev.advo.fs.fs.FileSystemConstants.BLOCK_SIZE, dev.advo.fs.fs.FileSystemConstants.CHUNK_SIZE, data, getIndex(), and dev.advo.fs.fs.FileSystemConstants.HEADER_SIZE.

Here is the call graph for this function:

◆ getFile() [2/2]

ByteBuffer dev.advo.fs.fs.IndexedFileSystem.getFile ( int type,
int file ) throws IOException

Gets a file.

Parameters
typeThe file type.
fileThe file id.
Returns
A ByteBuffer which contains the contents of the file.
Exceptions
IOExceptionif an I/O error occurs.

Definition at line 361 of file IndexedFileSystem.java.

361 {
362 return getFile(new FileDescriptor(type, file));
363 }

References getFile().

Referenced by getCrcTable(), getFile(), getJireCRCTable(), and initialResponse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getFileCount()

int dev.advo.fs.fs.IndexedFileSystem.getFileCount ( int type) throws IOException
private

Gets the number of files with the specified type.

Parameters
typeThe type.
Returns
The number of files.
Exceptions
IOExceptionif an I/O error occurs.

Definition at line 128 of file IndexedFileSystem.java.

128 {
129 if (type < 0 || type >= indices.length) {
130 throw new IndexOutOfBoundsException();
131 }
132
133 RandomAccessFile indexFile = indices[type];
134 synchronized (indexFile) {
135 return (int) (indexFile.length() / FileSystemConstants.INDEX_SIZE);
136 }
137 }

References dev.advo.fs.fs.FileSystemConstants.INDEX_SIZE, and indices.

Referenced by getCrcTable(), getJireCRCTable(), and initialResponse().

Here is the caller graph for this function:

◆ getIndex()

Index dev.advo.fs.fs.IndexedFileSystem.getIndex ( FileDescriptor fd) throws IOException
private

Gets the index of a file.

Parameters
fdThe FileDescriptor which points to the file.
Returns
The Index.
Exceptions
IOExceptionif an I/O error occurs.

Definition at line 101 of file IndexedFileSystem.java.

101 {
102 int index = fd.getType();
103 if (index < 0 || index >= indices.length) {
104 throw new IndexOutOfBoundsException();
105 }
106
107 byte[] buffer = new byte[FileSystemConstants.INDEX_SIZE];
108 RandomAccessFile indexFile = indices[index];
109 synchronized (indexFile) {
110 long ptr = (long) fd.getFile() * (long) FileSystemConstants.INDEX_SIZE;
111 if (ptr >= 0 && indexFile.length() >= (ptr + FileSystemConstants.INDEX_SIZE)) {
112 indexFile.seek(ptr);
113 indexFile.readFully(buffer);
114 } else {
115 throw new FileNotFoundException();
116 }
117 }
118
119 return Index.decode(buffer);
120 }

References dev.advo.fs.fs.Index.decode(), dev.advo.fs.fs.FileSystemConstants.INDEX_SIZE, and indices.

Referenced by getFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getJireCRCTable()

ByteBuffer dev.advo.fs.fs.IndexedFileSystem.getJireCRCTable ( ) throws IOException

Definition at line 302 of file IndexedFileSystem.java.

302 {
303 if (readOnly) {
304 synchronized (this) {
305 if (crcTable != null) {
306 return crcTable.slice();
307 }
308 }
309
310 int size = 6;
311
312 // the number of archives
313 int archives = getFileCount(0);
314
315 // the hash
316 int hash = 1234;
317
318 // the CRCs
319 int[] crcs = new int[archives];
320
321 // calculate the CRCs
322 CRC32 crc32 = new CRC32();
323 for (int i = 1; i < crcs.length; i++) {
324 crc32.reset();
325
326 ByteBuffer bb = getFile(0, i);
327 byte[] bytes = new byte[bb.remaining()];
328 bb.get(bytes, 0, bytes.length);
329 crc32.update(bytes, 0, bytes.length);
330
331 crcs[i] = (int) crc32.getValue();
332 }
333
334 // hash the CRCs and place them in the buffer
335 ByteBuffer buf = ByteBuffer.allocate(crcs.length * 4 + 4);
336 for (int i = 0; i < crcs.length; i++) {
337 hash = (hash << 1) + crcs[i];
338 buf.putInt(crcs[i]);
339 }
340
341 // place the hash into the buffer
342 buf.putInt(hash);
343 buf.flip();
344
345 synchronized (this) {
346 crcTable = buf;
347 return crcTable.slice();
348 }
349 } else {
350 throw new IOException("cannot get CRC table from a writable file system");
351 }
352 }

References bytes, crcTable, getFile(), getFileCount(), and readOnly.

Here is the call graph for this function:

◆ gzip()

byte[] dev.advo.fs.fs.IndexedFileSystem.gzip ( byte[] bytes) throws IOException
static

Compresses a GZIP file.

Parameters
bytesThe uncompressed bytes.
Returns
The compressed bytes.
Exceptions
IOExceptionif an I/O error occurs.

Definition at line 203 of file IndexedFileSystem.java.

203 {
204 /* create the streams */
205 InputStream is = new ByteArrayInputStream(bytes);
206 try {
207 ByteArrayOutputStream bout = new ByteArrayOutputStream();
208 OutputStream os = new GZIPOutputStream(bout);
209 try {
210 /* copy data between the streams */
211 byte[] buf = new byte[4096];
212 int len = 0;
213 while ((len = is.read(buf, 0, buf.length)) != -1) {
214 os.write(buf, 0, len);
215 }
216 } finally {
217 os.close();
218 }
219
220 /* return the compressed bytes */
221 return bout.toByteArray();
222 } finally {
223 is.close();
224 }
225 }

References bytes.

Referenced by initialResponse().

Here is the caller graph for this function:

◆ initialResponse()

byte[] dev.advo.fs.fs.IndexedFileSystem.initialResponse ( ) throws IOException
private

Definition at line 239 of file IndexedFileSystem.java.

239 {
240 // calculate the CRCs
241 CRC32 crc32 = new CRC32();
242// {
243// ChannelBuffer channelBuffer = ChannelBuffers.dynamicBuffer();
244// channelBuffer.writeByte(6);
245// for(int type = 0; type < 6; type++) {
246// int files = getFileCount(type);
247// channelBuffer.writeMedium(files);
248//
249// for(int file = 0; file < files; file++) {
250// crc32.reset();
251// ByteBuffer bb = getFile(type, file);
252// byte[] bytes = new byte[bb.remaining()];
253// bb.get(bytes, 0, bytes.length);
254// crc32.update(bytes, 0, bytes.length);
255// }
256//
257// //write int for the crc value.
258// channelBuffer.writeInt((int) crc32.getValue());
259// }
260// }
261// {
262 int bufLen = 0;
263 for(int i = 0; i < 6; i++) {
264 bufLen += getFileCount(i) * 4;
265 }
266 bufLen += (6*3) + 1;
267
268 ByteBuffer buf = ByteBuffer.allocate(bufLen);
269 buf.put((byte) 6);
270
271 for(int i = 0; i < 6; i++) {
272 //write the # of entries as a medium.
273 int value = getFileCount(i);
274 buf.put((byte) (value >> 16));
275 buf.put((byte) (value >> 8));
276 buf.put((byte) value);
277 for(int f = 0; f < value; f++) {
278 crc32.reset();
279 ByteBuffer bb = getFile(i, f);
280 byte[] bytes = new byte[bb.remaining()];
281 bb.get(bytes, 0, bytes.length);
282 crc32.update(bytes, 0, bytes.length);
283
284 //write int for the crc value.
285 buf.putInt((int) crc32.getValue());
286 }
287 }
288
289 buf.rewind();
290 byte[] uncompressed = new byte[buf.remaining()];
291 //System.out.println("unc" + uncompressed.length);
292 buf.get(uncompressed);
293// System.out.println(Arrays.toString(uncompressed));
294// System.exit(0);
295 byte[] compressed = gzip(uncompressed);
296 System.out.println("comp" + compressed.length);
297// }
298
299 return compressed;
300 }

References bytes, getFile(), getFileCount(), and gzip().

Referenced by detectLayout().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isReadOnly()

boolean dev.advo.fs.fs.IndexedFileSystem.isReadOnly ( )

Checks if this IndexedFileSystem is read only.

Returns
true if so, false if not.

Definition at line 57 of file IndexedFileSystem.java.

57 {
58 return readOnly;
59 }

References readOnly.

Member Data Documentation

◆ bytes

byte [] dev.advo.fs.fs.IndexedFileSystem.bytes
static

◆ crcTable

ByteBuffer dev.advo.fs.fs.IndexedFileSystem.crcTable
private

The cached CRC table.

Definition at line 40 of file IndexedFileSystem.java.

Referenced by getCrcTable(), and getJireCRCTable().

◆ data

RandomAccessFile dev.advo.fs.fs.IndexedFileSystem.data
private

The data file.

Definition at line 35 of file IndexedFileSystem.java.

Referenced by close(), detectLayout(), and getFile().

◆ indices

RandomAccessFile [] dev.advo.fs.fs.IndexedFileSystem.indices = new RandomAccessFile[256]
private

The index files.

Definition at line 30 of file IndexedFileSystem.java.

Referenced by close(), detectLayout(), getFileCount(), and getIndex().

◆ readOnly

final boolean dev.advo.fs.fs.IndexedFileSystem.readOnly
private

Read only flag.

Definition at line 25 of file IndexedFileSystem.java.

Referenced by detectLayout(), getCrcTable(), getJireCRCTable(), IndexedFileSystem(), and isReadOnly().


The documentation for this class was generated from the following file: