/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package org.ant4eclipse.lib.platform.internal.model.resource;
import org.ant4eclipse.lib.core.logging.A4ELogging;
import org.ant4eclipse.lib.core.util.Utilities;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
/**
* Simple representation for chunk based files as internally used by the Eclipse framework.
*
* @author Daniel Kasmeroglu (daniel.kasmeroglu@kasisoft.net)
*/
public class ChunkyFile {
private static final byte[] BEGIN_CHUNK = { 64, -79, -117, -127, 35, -68, 0, 20, 26, 37, -106, -25, -93, -109, -66,
30 };
private static final byte[] END_CHUNK = { -64, 88, -5, -13, 35, -68, 0, 20, 26, 81, -13, -116, 123, -69, 119, -58 };
private Vector<byte[]> _chunkdata;
/**
* Creates a chunked representation of the supplied file.
*
* @param source
* The file that shall be loaded.
*
* @throws IOException
* Reading the file failed for some reason.
*/
public ChunkyFile(File source) throws IOException {
this._chunkdata = new Vector<byte[]>();
byte[] data = new byte[(int) source.length()];
InputStream input = null;
try {
input = new FileInputStream(source);
input.read(data);
loadChunks(data);
} catch (IOException ex) {
A4ELogging.error(ex.getMessage());
throw (ex);
} finally {
Utilities.close(input);
}
}
/**
* Returns the number of available chunks.
*
* @return The number of available chunks.
*/
public int getChunkCount() {
return this._chunkdata.size();
}
/**
* Returns a chunk by it's index.
*
* @param index
* The index of the chunk.
*
* @return The chunk data. null if the index wasn't valid.
*/
public byte[] getChunk(int index) {
if ((index >= 0) && (index < this._chunkdata.size())) {
return this._chunkdata.get(index);
}
return null;
}
/**
* Loads each chunk while running through the supplied file content.
*
* @param content
* A bytewise representation of the file.
*/
private void loadChunks(byte[] content) {
int ptr = find(content, BEGIN_CHUNK, 0);
while ((ptr != -1) && (ptr < content.length)) {
ptr = ptr + BEGIN_CHUNK.length;
int end = find(content, END_CHUNK, ptr);
if (end != -1) {
byte[] data = new byte[end - ptr];
System.arraycopy(content, ptr, data, 0, data.length);
this._chunkdata.add(data);
ptr = end + END_CHUNK.length;
}
ptr = find(content, BEGIN_CHUNK, ptr);
}
}
/**
* Returns the index of a byte sequence.
*
* @param content
* The memory where to search for the byte sequence.
* @param sequence
* The sequence that shall be searched.
* @param first
* Initial starting point.
*
* @return The index of the byte sequence or -1 if the sequence could not be found.
*/
private int find(byte[] content, byte[] sequence, int first) {
while ((first + sequence.length) <= content.length) {
if (content[first] == sequence[0]) {
int i = 0;
int j = first;
while ((i < sequence.length) && (content[j] == sequence[i])) {
i++;
j++;
}
if (i == sequence.length) {
return first;
}
}
first++;
}
return -1;
}
} /* ENDCLASS */