mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-10-04 11:26:44 -04:00
New code style. No functional changes.
This commit is contained in:
@@ -14,28 +14,28 @@ import java.io.InputStream;
|
||||
*/
|
||||
abstract class AbstractCachedSeekableStream extends SeekableInputStream {
|
||||
/** The backing stream */
|
||||
protected final InputStream mStream;
|
||||
protected final InputStream stream;
|
||||
|
||||
/** The stream positon in the backing stream (mStream) */
|
||||
protected long mStreamPosition;
|
||||
/** The stream positon in the backing stream (stream) */
|
||||
protected long streamPosition;
|
||||
|
||||
private StreamCache mCache;
|
||||
private StreamCache cache;
|
||||
|
||||
protected AbstractCachedSeekableStream(final InputStream pStream, final StreamCache pCache) {
|
||||
Validate.notNull(pStream, "stream");
|
||||
Validate.notNull(pCache, "cache");
|
||||
|
||||
mStream = pStream;
|
||||
mCache = pCache;
|
||||
stream = pStream;
|
||||
cache = pCache;
|
||||
}
|
||||
|
||||
protected final StreamCache getCache() {
|
||||
return mCache;
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
long avail = mStreamPosition - mPosition + mStream.available();
|
||||
long avail = streamPosition - position + stream.available();
|
||||
return avail > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) avail;
|
||||
}
|
||||
|
||||
@@ -43,26 +43,26 @@ abstract class AbstractCachedSeekableStream extends SeekableInputStream {
|
||||
checkOpen();
|
||||
int read;
|
||||
|
||||
if (mPosition == mStreamPosition) {
|
||||
if (position == streamPosition) {
|
||||
// TODO: Read more bytes here!
|
||||
// TODO: Use buffer if not in-memory cache? (See FileCacheSeekableStream overrides).
|
||||
// Read a byte from the stream
|
||||
read = mStream.read();
|
||||
read = stream.read();
|
||||
|
||||
if (read >= 0) {
|
||||
mStreamPosition++;
|
||||
mCache.write(read);
|
||||
streamPosition++;
|
||||
cache.write(read);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ..or read byte from the cache
|
||||
syncPosition();
|
||||
read = mCache.read();
|
||||
read = cache.read();
|
||||
}
|
||||
|
||||
// TODO: This field is not REALLY considered accessible.. :-P
|
||||
if (read != -1) {
|
||||
mPosition++;
|
||||
position++;
|
||||
}
|
||||
|
||||
return read;
|
||||
@@ -73,32 +73,32 @@ abstract class AbstractCachedSeekableStream extends SeekableInputStream {
|
||||
checkOpen();
|
||||
int length;
|
||||
|
||||
if (mPosition == mStreamPosition) {
|
||||
if (position == streamPosition) {
|
||||
// Read bytes from the stream
|
||||
length = mStream.read(pBytes, pOffset, pLength);
|
||||
length = stream.read(pBytes, pOffset, pLength);
|
||||
|
||||
if (length > 0) {
|
||||
mStreamPosition += length;
|
||||
mCache.write(pBytes, pOffset, length);
|
||||
streamPosition += length;
|
||||
cache.write(pBytes, pOffset, length);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ...or read bytes from the cache
|
||||
syncPosition();
|
||||
length = mCache.read(pBytes, pOffset, pLength);
|
||||
length = cache.read(pBytes, pOffset, pLength);
|
||||
}
|
||||
|
||||
// TODO: This field is not REALLY considered accessible.. :-P
|
||||
if (length > 0) {
|
||||
mPosition += length;
|
||||
position += length;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
protected final void syncPosition() throws IOException {
|
||||
if (mCache.getPosition() != mPosition) {
|
||||
mCache.seek(mPosition); // Assure EOF is correctly thrown
|
||||
if (cache.getPosition() != position) {
|
||||
cache.seek(position); // Assure EOF is correctly thrown
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,14 +111,14 @@ abstract class AbstractCachedSeekableStream extends SeekableInputStream {
|
||||
public abstract boolean isCachedFile();
|
||||
|
||||
protected void seekImpl(long pPosition) throws IOException {
|
||||
if (mStreamPosition < pPosition) {
|
||||
if (streamPosition < pPosition) {
|
||||
// Make sure we append at end of cache
|
||||
if (mCache.getPosition() != mStreamPosition) {
|
||||
mCache.seek(mStreamPosition);
|
||||
if (cache.getPosition() != streamPosition) {
|
||||
cache.seek(streamPosition);
|
||||
}
|
||||
|
||||
// Read diff from stream into cache
|
||||
long left = pPosition - mStreamPosition;
|
||||
long left = pPosition - streamPosition;
|
||||
|
||||
// TODO: Use fixed buffer, instead of allocating here...
|
||||
int bufferLen = left > 1024 ? 1024 : (int) left;
|
||||
@@ -126,11 +126,11 @@ abstract class AbstractCachedSeekableStream extends SeekableInputStream {
|
||||
|
||||
while (left > 0) {
|
||||
int length = buffer.length < left ? buffer.length : (int) left;
|
||||
int read = mStream.read(buffer, 0, length);
|
||||
int read = stream.read(buffer, 0, length);
|
||||
|
||||
if (read > 0) {
|
||||
mCache.write(buffer, 0, read);
|
||||
mStreamPosition += read;
|
||||
cache.write(buffer, 0, read);
|
||||
streamPosition += read;
|
||||
left -= read;
|
||||
}
|
||||
else if (read < 0) {
|
||||
@@ -138,27 +138,27 @@ abstract class AbstractCachedSeekableStream extends SeekableInputStream {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mStreamPosition >= pPosition) {
|
||||
else if (streamPosition >= pPosition) {
|
||||
// Seek backwards into the cache
|
||||
mCache.seek(pPosition);
|
||||
cache.seek(pPosition);
|
||||
}
|
||||
|
||||
// System.out.println("pPosition: " + pPosition);
|
||||
// System.out.println("mPosition: " + mPosition);
|
||||
// System.out.println("mStreamPosition: " + mStreamPosition);
|
||||
// System.out.println("mCache.mPosition: " + mCache.getPosition());
|
||||
// System.out.println("position: " + position);
|
||||
// System.out.println("streamPosition: " + streamPosition);
|
||||
// System.out.println("cache.position: " + cache.getPosition());
|
||||
|
||||
// NOTE: If mPosition == pPosition then we're good to go
|
||||
// NOTE: If position == pPosition then we're good to go
|
||||
}
|
||||
|
||||
protected void flushBeforeImpl(long pPosition) {
|
||||
mCache.flush(pPosition);
|
||||
cache.flush(pPosition);
|
||||
}
|
||||
|
||||
protected void closeImpl() throws IOException {
|
||||
mCache.flush(mPosition);
|
||||
mCache = null;
|
||||
mStream.close();
|
||||
cache.flush(position);
|
||||
cache = null;
|
||||
stream.close();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -46,15 +46,16 @@ import java.util.List;
|
||||
*/
|
||||
public class CompoundReader extends Reader {
|
||||
|
||||
private Reader mCurrent;
|
||||
private List<Reader> mReaders;
|
||||
protected final Object mLock;
|
||||
private Reader current;
|
||||
private List<Reader> readers;
|
||||
|
||||
protected final boolean mMarkSupported;
|
||||
protected final Object finalLock;
|
||||
|
||||
private int mCurrentReader;
|
||||
private int mMarkedReader;
|
||||
private int mMark;
|
||||
protected final boolean markSupported;
|
||||
|
||||
private int currentReader;
|
||||
private int markedReader;
|
||||
private int mark;
|
||||
private int mNext;
|
||||
|
||||
/**
|
||||
@@ -71,10 +72,10 @@ public class CompoundReader extends Reader {
|
||||
public CompoundReader(final Iterator<Reader> pReaders) {
|
||||
super(Validate.notNull(pReaders, "readers"));
|
||||
|
||||
mLock = pReaders; // NOTE: It's ok to sync on pReaders, as the
|
||||
finalLock = pReaders; // NOTE: It's ok to sync on pReaders, as the
|
||||
// reference can't change, only it's elements
|
||||
|
||||
mReaders = new ArrayList<Reader>();
|
||||
readers = new ArrayList<Reader>();
|
||||
|
||||
boolean markSupported = true;
|
||||
while (pReaders.hasNext()) {
|
||||
@@ -82,25 +83,25 @@ public class CompoundReader extends Reader {
|
||||
if (reader == null) {
|
||||
throw new NullPointerException("readers cannot contain null-elements");
|
||||
}
|
||||
mReaders.add(reader);
|
||||
readers.add(reader);
|
||||
markSupported = markSupported && reader.markSupported();
|
||||
}
|
||||
mMarkSupported = markSupported;
|
||||
this.markSupported = markSupported;
|
||||
|
||||
mCurrent = nextReader();
|
||||
current = nextReader();
|
||||
}
|
||||
|
||||
protected final Reader nextReader() {
|
||||
if (mCurrentReader >= mReaders.size()) {
|
||||
mCurrent = new EmptyReader();
|
||||
if (currentReader >= readers.size()) {
|
||||
current = new EmptyReader();
|
||||
}
|
||||
else {
|
||||
mCurrent = mReaders.get(mCurrentReader++);
|
||||
current = readers.get(currentReader++);
|
||||
}
|
||||
|
||||
// NOTE: Reset mNext for every reader, and record marked reader in mark/reset methods!
|
||||
mNext = 0;
|
||||
return mCurrent;
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,17 +110,18 @@ public class CompoundReader extends Reader {
|
||||
* @throws IOException if the stream is closed
|
||||
*/
|
||||
protected final void ensureOpen() throws IOException {
|
||||
if (mReaders == null) {
|
||||
if (readers == null) {
|
||||
throw new IOException("Stream closed");
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
// Close all readers
|
||||
for (Reader reader : mReaders) {
|
||||
for (Reader reader : readers) {
|
||||
reader.close();
|
||||
}
|
||||
mReaders = null;
|
||||
|
||||
readers = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,46 +132,46 @@ public class CompoundReader extends Reader {
|
||||
|
||||
// TODO: It would be nice if we could actually close some readers now
|
||||
|
||||
synchronized (mLock) {
|
||||
synchronized (finalLock) {
|
||||
ensureOpen();
|
||||
mMark = mNext;
|
||||
mMarkedReader = mCurrentReader;
|
||||
mark = mNext;
|
||||
markedReader = currentReader;
|
||||
|
||||
mCurrent.mark(pReadLimit);
|
||||
current.mark(pReadLimit);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
synchronized (mLock) {
|
||||
synchronized (finalLock) {
|
||||
ensureOpen();
|
||||
|
||||
if (mCurrentReader != mMarkedReader) {
|
||||
if (currentReader != markedReader) {
|
||||
// Reset any reader before this
|
||||
for (int i = mCurrentReader; i >= mMarkedReader; i--) {
|
||||
mReaders.get(i).reset();
|
||||
for (int i = currentReader; i >= markedReader; i--) {
|
||||
readers.get(i).reset();
|
||||
}
|
||||
|
||||
mCurrentReader = mMarkedReader - 1;
|
||||
currentReader = markedReader - 1;
|
||||
nextReader();
|
||||
}
|
||||
mCurrent.reset();
|
||||
current.reset();
|
||||
|
||||
mNext = mMark;
|
||||
mNext = mark;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return mMarkSupported;
|
||||
return markSupported;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
synchronized (mLock) {
|
||||
int read = mCurrent.read();
|
||||
synchronized (finalLock) {
|
||||
int read = current.read();
|
||||
|
||||
if (read < 0 && mCurrentReader < mReaders.size()) {
|
||||
if (read < 0 && currentReader < readers.size()) {
|
||||
nextReader();
|
||||
return read(); // In case of 0-length readers
|
||||
}
|
||||
@@ -181,10 +183,10 @@ public class CompoundReader extends Reader {
|
||||
}
|
||||
|
||||
public int read(char pBuffer[], int pOffset, int pLength) throws IOException {
|
||||
synchronized (mLock) {
|
||||
int read = mCurrent.read(pBuffer, pOffset, pLength);
|
||||
synchronized (finalLock) {
|
||||
int read = current.read(pBuffer, pOffset, pLength);
|
||||
|
||||
if (read < 0 && mCurrentReader < mReaders.size()) {
|
||||
if (read < 0 && currentReader < readers.size()) {
|
||||
nextReader();
|
||||
return read(pBuffer, pOffset, pLength); // In case of 0-length readers
|
||||
}
|
||||
@@ -197,15 +199,15 @@ public class CompoundReader extends Reader {
|
||||
|
||||
@Override
|
||||
public boolean ready() throws IOException {
|
||||
return mCurrent.ready();
|
||||
return current.ready();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long pChars) throws IOException {
|
||||
synchronized (mLock) {
|
||||
long skipped = mCurrent.skip(pChars);
|
||||
synchronized (finalLock) {
|
||||
long skipped = current.skip(pChars);
|
||||
|
||||
if (skipped == 0 && mCurrentReader < mReaders.size()) {
|
||||
if (skipped == 0 && currentReader < readers.size()) {
|
||||
nextReader();
|
||||
return skip(pChars); // In case of 0-length readers
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ import java.io.ByteArrayInputStream;
|
||||
// TODO: Performance test of a stream impl that uses list of fixed size blocks, rather than contiguous block
|
||||
public final class FastByteArrayOutputStream extends ByteArrayOutputStream {
|
||||
/** Max grow size (unless if writing more than this amount of bytes) */
|
||||
protected int mMaxGrowSize = 1024 * 1024; // 1 MB
|
||||
protected int maxGrowSize = 1024 * 1024; // 1 MB
|
||||
|
||||
/**
|
||||
* Creates a {@code ByteArrayOutputStream} with the given initial buffer
|
||||
@@ -94,7 +94,7 @@ public final class FastByteArrayOutputStream extends ByteArrayOutputStream {
|
||||
|
||||
private void growIfNeeded(int pNewcount) {
|
||||
if (pNewcount > buf.length) {
|
||||
int newSize = Math.max(Math.min(buf.length << 1, buf.length + mMaxGrowSize), pNewcount);
|
||||
int newSize = Math.max(Math.min(buf.length << 1, buf.length + maxGrowSize), pNewcount);
|
||||
byte newBuf[] = new byte[newSize];
|
||||
System.arraycopy(buf, 0, newBuf, 0, count);
|
||||
buf = newBuf;
|
||||
|
@@ -48,16 +48,7 @@ import java.io.*;
|
||||
*/
|
||||
public final class FileCacheSeekableStream extends AbstractCachedSeekableStream {
|
||||
|
||||
// private final InputStream mStream;
|
||||
// private final RandomAccessFile mCache;
|
||||
private byte[] mBuffer;
|
||||
|
||||
/** The stream positon in the backing stream (mStream) */
|
||||
// private long mStreamPosition;
|
||||
|
||||
// TODO: getStreamPosition() should always be the same as
|
||||
// mCache.getFilePointer()
|
||||
// otherwise there's some inconsistency here... Enforce this?
|
||||
private byte[] buffer;
|
||||
|
||||
/**
|
||||
* Creates a {@code FileCacheSeekableStream} reading from the given
|
||||
@@ -118,7 +109,7 @@ public final class FileCacheSeekableStream extends AbstractCachedSeekableStream
|
||||
super(pStream, new FileCache(pFile));
|
||||
|
||||
// TODO: Allow for custom buffer sizes?
|
||||
mBuffer = new byte[1024];
|
||||
buffer = new byte[1024];
|
||||
}
|
||||
|
||||
public final boolean isCachedMemory() {
|
||||
@@ -132,39 +123,19 @@ public final class FileCacheSeekableStream extends AbstractCachedSeekableStream
|
||||
@Override
|
||||
protected void closeImpl() throws IOException {
|
||||
super.closeImpl();
|
||||
mBuffer = null;
|
||||
buffer = null;
|
||||
}
|
||||
/*
|
||||
public final boolean isCached() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// InputStream overrides
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
long avail = mStreamPosition - mPosition + mStream.available();
|
||||
return avail > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) avail;
|
||||
}
|
||||
|
||||
public void closeImpl() throws IOException {
|
||||
mStream.close();
|
||||
mCache.close();
|
||||
|
||||
// TODO: Delete cache file here?
|
||||
// ThreadPool.invokeLater(new DeleteFileAction(mCacheFile));
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
checkOpen();
|
||||
|
||||
int read;
|
||||
if (mPosition == mStreamPosition) {
|
||||
if (position == streamPosition) {
|
||||
// Read ahead into buffer, for performance
|
||||
read = readAhead(mBuffer, 0, mBuffer.length);
|
||||
read = readAhead(buffer, 0, buffer.length);
|
||||
if (read >= 0) {
|
||||
read = mBuffer[0] & 0xff;
|
||||
read = buffer[0] & 0xff;
|
||||
}
|
||||
|
||||
//System.out.println("Read 1 byte from stream: " + Integer.toHexString(read & 0xff));
|
||||
@@ -179,7 +150,7 @@ public final class FileCacheSeekableStream extends AbstractCachedSeekableStream
|
||||
|
||||
// TODO: This field is not REALLY considered accessible.. :-P
|
||||
if (read != -1) {
|
||||
mPosition++;
|
||||
position++;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
@@ -189,7 +160,7 @@ public final class FileCacheSeekableStream extends AbstractCachedSeekableStream
|
||||
checkOpen();
|
||||
|
||||
int length;
|
||||
if (mPosition == mStreamPosition) {
|
||||
if (position == streamPosition) {
|
||||
// Read bytes from the stream
|
||||
length = readAhead(pBytes, pOffset, pLength);
|
||||
|
||||
@@ -198,83 +169,29 @@ public final class FileCacheSeekableStream extends AbstractCachedSeekableStream
|
||||
else {
|
||||
// ...or read bytes from the cache
|
||||
syncPosition();
|
||||
length = getCache().read(pBytes, pOffset, (int) Math.min(pLength, mStreamPosition - mPosition));
|
||||
length = getCache().read(pBytes, pOffset, (int) Math.min(pLength, streamPosition - position));
|
||||
|
||||
//System.out.println("Read " + length + " byte from cache");
|
||||
}
|
||||
|
||||
// TODO: This field is not REALLY considered accessible.. :-P
|
||||
if (length > 0) {
|
||||
mPosition += length;
|
||||
position += length;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
private int readAhead(final byte[] pBytes, final int pOffset, final int pLength) throws IOException {
|
||||
int length;
|
||||
length = mStream.read(pBytes, pOffset, pLength);
|
||||
length = stream.read(pBytes, pOffset, pLength);
|
||||
|
||||
if (length > 0) {
|
||||
mStreamPosition += length;
|
||||
streamPosition += length;
|
||||
getCache().write(pBytes, pOffset, length);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
private void syncPosition() throws IOException {
|
||||
if (mCache.getFilePointer() != mPosition) {
|
||||
mCache.seek(mPosition); // Assure EOF is correctly thrown
|
||||
}
|
||||
}
|
||||
|
||||
// Seekable overrides
|
||||
|
||||
protected void flushBeforeImpl(long pPosition) {
|
||||
// TODO: Implement
|
||||
// For now, it's probably okay to do nothing, this is just for
|
||||
// performance (as long as people follow spec, not behaviour)
|
||||
}
|
||||
|
||||
protected void seekImpl(long pPosition) throws IOException {
|
||||
if (mStreamPosition < pPosition) {
|
||||
// Make sure we append at end of cache
|
||||
if (mCache.getFilePointer() != mStreamPosition) {
|
||||
mCache.seek(mStreamPosition);
|
||||
}
|
||||
|
||||
// Read diff from stream into cache
|
||||
long left = pPosition - mStreamPosition;
|
||||
int bufferLen = left > 1024 ? 1024 : (int) left;
|
||||
byte[] buffer = new byte[bufferLen];
|
||||
|
||||
while (left > 0) {
|
||||
int length = buffer.length < left ? buffer.length : (int) left;
|
||||
int read = mStream.read(buffer, 0, length);
|
||||
|
||||
if (read > 0) {
|
||||
mCache.write(buffer, 0, read);
|
||||
mStreamPosition += read;
|
||||
left -= read;
|
||||
}
|
||||
else if (read < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mStreamPosition >= pPosition) {
|
||||
// Seek backwards into the cache
|
||||
mCache.seek(pPosition);
|
||||
}
|
||||
|
||||
// System.out.println("pPosition: " + pPosition);
|
||||
// System.out.println("mStreamPosition: " + mStreamPosition);
|
||||
// System.out.println("mCache.getFilePointer(): " + mCache.getFilePointer());
|
||||
|
||||
// NOTE: If mPosition == pPosition then we're good to go
|
||||
}
|
||||
*/
|
||||
|
||||
final static class FileCache extends StreamCache {
|
||||
private RandomAccessFile mCacheFile;
|
||||
|
||||
|
@@ -87,7 +87,7 @@ public final class FileSeekableStream extends SeekableInputStream {
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
long length = mRandomAccess.length() - mPosition;
|
||||
long length = mRandomAccess.length() - position;
|
||||
return length > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) length;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public final class FileSeekableStream extends SeekableInputStream {
|
||||
|
||||
int read = mRandomAccess.read();
|
||||
if (read >= 0) {
|
||||
mPosition++;
|
||||
position++;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
@@ -111,7 +111,7 @@ public final class FileSeekableStream extends SeekableInputStream {
|
||||
|
||||
int read = mRandomAccess.read(pBytes, pOffset, pLength);
|
||||
if (read > 0) {
|
||||
mPosition += read;
|
||||
position += read;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
@@ -80,10 +80,10 @@ abstract class FileSystem {
|
||||
}
|
||||
|
||||
private static class UnknownFileSystem extends FileSystem {
|
||||
private final String mOSName;
|
||||
private final String osName;
|
||||
|
||||
UnknownFileSystem(String pOSName) {
|
||||
mOSName = pOSName;
|
||||
osName = pOSName;
|
||||
}
|
||||
|
||||
long getFreeSpace(File pPath) {
|
||||
@@ -95,7 +95,7 @@ abstract class FileSystem {
|
||||
}
|
||||
|
||||
String getName() {
|
||||
return "Unknown (" + mOSName + ")";
|
||||
return "Unknown (" + osName + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -685,28 +685,28 @@ public final class FileUtil {
|
||||
// a file array, which may throw OutOfMemoryExceptions for
|
||||
// large directories/in low memory situations
|
||||
class DeleteFilesVisitor implements Visitor<File> {
|
||||
private int mFailedCount = 0;
|
||||
private IOException mException = null;
|
||||
private int failedCount = 0;
|
||||
private IOException exception = null;
|
||||
|
||||
public void visit(final File pFile) {
|
||||
try {
|
||||
if (!delete(pFile, true)) {
|
||||
mFailedCount++;
|
||||
failedCount++;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
mFailedCount++;
|
||||
if (mException == null) {
|
||||
mException = e;
|
||||
failedCount++;
|
||||
if (exception == null) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean succeeded() throws IOException {
|
||||
if (mException != null) {
|
||||
throw mException;
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
return mFailedCount == 0;
|
||||
return failedCount == 0;
|
||||
}
|
||||
}
|
||||
DeleteFilesVisitor fileDeleter = new DeleteFilesVisitor();
|
||||
|
@@ -60,9 +60,9 @@ import java.io.FilenameFilter;
|
||||
public class FilenameMaskFilter implements FilenameFilter {
|
||||
|
||||
// Members
|
||||
private String[] mFilenameMasksForInclusion;
|
||||
private String[] mFilenameMasksForExclusion;
|
||||
private boolean mInclusion = true;
|
||||
private String[] filenameMasksForInclusion;
|
||||
private String[] filenameMasksForExclusion;
|
||||
private boolean inclusion = true;
|
||||
|
||||
|
||||
/**
|
||||
@@ -127,29 +127,29 @@ public class FilenameMaskFilter implements FilenameFilter {
|
||||
* @param pFilenameMasksForInclusion the filename masks to include
|
||||
*/
|
||||
public void setFilenameMasksForInclusion(String[] pFilenameMasksForInclusion) {
|
||||
mFilenameMasksForInclusion = pFilenameMasksForInclusion;
|
||||
filenameMasksForInclusion = pFilenameMasksForInclusion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current inclusion masks
|
||||
*/
|
||||
public String[] getFilenameMasksForInclusion() {
|
||||
return mFilenameMasksForInclusion.clone();
|
||||
return filenameMasksForInclusion.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pFilenameMasksForExclusion the filename masks to exclude
|
||||
*/
|
||||
public void setFilenameMasksForExclusion(String[] pFilenameMasksForExclusion) {
|
||||
mFilenameMasksForExclusion = pFilenameMasksForExclusion;
|
||||
mInclusion = false;
|
||||
filenameMasksForExclusion = pFilenameMasksForExclusion;
|
||||
inclusion = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current exclusion masks
|
||||
*/
|
||||
public String[] getFilenameMasksForExclusion() {
|
||||
return mFilenameMasksForExclusion.clone();
|
||||
return filenameMasksForExclusion.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,8 +164,8 @@ public class FilenameMaskFilter implements FilenameFilter {
|
||||
WildcardStringParser parser;
|
||||
|
||||
// Check each filename string mask whether the file is to be accepted
|
||||
if (mInclusion) { // Inclusion
|
||||
for (String mask : mFilenameMasksForInclusion) {
|
||||
if (inclusion) { // Inclusion
|
||||
for (String mask : filenameMasksForInclusion) {
|
||||
parser = new WildcardStringParser(mask);
|
||||
if (parser.parseString(pName)) {
|
||||
|
||||
@@ -181,7 +181,7 @@ public class FilenameMaskFilter implements FilenameFilter {
|
||||
}
|
||||
else {
|
||||
// Exclusion
|
||||
for (String mask : mFilenameMasksForExclusion) {
|
||||
for (String mask : filenameMasksForExclusion) {
|
||||
parser = new WildcardStringParser(mask);
|
||||
if (parser.parseString(pName)) {
|
||||
|
||||
@@ -204,32 +204,32 @@ public class FilenameMaskFilter implements FilenameFilter {
|
||||
StringBuilder retVal = new StringBuilder();
|
||||
int i;
|
||||
|
||||
if (mInclusion) {
|
||||
if (inclusion) {
|
||||
// Inclusion
|
||||
if (mFilenameMasksForInclusion == null) {
|
||||
retVal.append("No filename masks set - property mFilenameMasksForInclusion is null!");
|
||||
if (filenameMasksForInclusion == null) {
|
||||
retVal.append("No filename masks set - property filenameMasksForInclusion is null!");
|
||||
}
|
||||
else {
|
||||
retVal.append(mFilenameMasksForInclusion.length);
|
||||
retVal.append(filenameMasksForInclusion.length);
|
||||
retVal.append(" filename mask(s) - ");
|
||||
for (i = 0; i < mFilenameMasksForInclusion.length; i++) {
|
||||
for (i = 0; i < filenameMasksForInclusion.length; i++) {
|
||||
retVal.append("\"");
|
||||
retVal.append(mFilenameMasksForInclusion[i]);
|
||||
retVal.append(filenameMasksForInclusion[i]);
|
||||
retVal.append("\", \"");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Exclusion
|
||||
if (mFilenameMasksForExclusion == null) {
|
||||
retVal.append("No filename masks set - property mFilenameMasksForExclusion is null!");
|
||||
if (filenameMasksForExclusion == null) {
|
||||
retVal.append("No filename masks set - property filenameMasksForExclusion is null!");
|
||||
}
|
||||
else {
|
||||
retVal.append(mFilenameMasksForExclusion.length);
|
||||
retVal.append(filenameMasksForExclusion.length);
|
||||
retVal.append(" exclusion filename mask(s) - ");
|
||||
for (i = 0; i < mFilenameMasksForExclusion.length; i++) {
|
||||
for (i = 0; i < filenameMasksForExclusion.length; i++) {
|
||||
retVal.append("\"");
|
||||
retVal.append(mFilenameMasksForExclusion[i]);
|
||||
retVal.append(filenameMasksForExclusion[i]);
|
||||
retVal.append("\", \"");
|
||||
}
|
||||
}
|
||||
|
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name "TwelveMonkeys" nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
|
||||
|
||||
/**
|
||||
* A Java Bean used for approving file names which are to be included in a
|
||||
* {@code java.io.File} listing. The file name suffixes are used as a
|
||||
* filter input and is given to the class via the string array property:<br>
|
||||
* <dd>{@code filenameSuffixesToExclude}
|
||||
* <p>
|
||||
* A recommended way of doing this is by referencing to the component which uses
|
||||
* this class for file listing. In this way all properties are set in the same
|
||||
* component and this utility component is kept in the background with only
|
||||
* initial configuration necessary.
|
||||
*
|
||||
* @author <a href="mailto:eirik.torske@iconmedialab.no">Eirik Torske</a>
|
||||
* @see File#list(java.io.FilenameFilter) java.io.File.list
|
||||
* @see FilenameFilter java.io.FilenameFilter
|
||||
*/
|
||||
public class FilenameSuffixFilter implements FilenameFilter {
|
||||
|
||||
// Members
|
||||
String[] mFilenameSuffixesToExclude;
|
||||
|
||||
/** Creates a {@code FileNameSuffixFilter} */
|
||||
public FilenameSuffixFilter() {
|
||||
}
|
||||
|
||||
public void setFilenameSuffixesToExclude(String[] pFilenameSuffixesToExclude) {
|
||||
mFilenameSuffixesToExclude = pFilenameSuffixesToExclude;
|
||||
}
|
||||
|
||||
public String[] getFilenameSuffixesToExclude() {
|
||||
return mFilenameSuffixesToExclude;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method implements the {@code java.io.FilenameFilter} interface.
|
||||
* <p/>
|
||||
*
|
||||
* @param pDir the directory in which the file was found.
|
||||
* @param pName the pName of the file.
|
||||
* @return {@code true} if the pName should be included in the file list;
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
public boolean accept(final File pDir, final String pName) {
|
||||
if (StringUtil.isEmpty(mFilenameSuffixesToExclude)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (String aMFilenameSuffixesToExclude : mFilenameSuffixesToExclude) {
|
||||
// -- Edit by haraldK, to make interfaces more consistent
|
||||
// if (StringUtil.filenameSuffixIs(pName, mFilenameSuffixesToExclude[i])) {
|
||||
if (aMFilenameSuffixesToExclude.equals(FileUtil.getExtension(pName))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -38,6 +38,8 @@
|
||||
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
@@ -75,10 +77,7 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
* @see java.io.FilterInputStream#in
|
||||
*/
|
||||
public LittleEndianDataInputStream(final InputStream pStream) {
|
||||
super(pStream);
|
||||
if (pStream == null) {
|
||||
throw new IllegalArgumentException("stream == null");
|
||||
}
|
||||
super(Validate.notNull(pStream, "stream"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,9 +92,11 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
*/
|
||||
public boolean readBoolean() throws IOException {
|
||||
int b = in.read();
|
||||
|
||||
if (b < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return b != 0;
|
||||
}
|
||||
|
||||
@@ -110,9 +111,11 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
*/
|
||||
public byte readByte() throws IOException {
|
||||
int b = in.read();
|
||||
|
||||
if (b < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return (byte) b;
|
||||
|
||||
}
|
||||
@@ -128,9 +131,11 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
*/
|
||||
public int readUnsignedByte() throws IOException {
|
||||
int b = in.read();
|
||||
|
||||
if (b < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -146,11 +151,13 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
public short readShort() throws IOException {
|
||||
int byte1 = in.read();
|
||||
int byte2 = in.read();
|
||||
|
||||
// only need to test last byte read
|
||||
// if byte1 is -1 so is byte2
|
||||
if (byte2 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return (short) (((byte2 << 24) >>> 16) + (byte1 << 24) >>> 24);
|
||||
}
|
||||
|
||||
@@ -166,10 +173,11 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
public int readUnsignedShort() throws IOException {
|
||||
int byte1 = in.read();
|
||||
int byte2 = in.read();
|
||||
|
||||
if (byte2 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
//return ((byte2 << 24) >> 16) + ((byte1 << 24) >> 24);
|
||||
|
||||
return (byte2 << 8) + byte1;
|
||||
}
|
||||
|
||||
@@ -185,9 +193,11 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
public char readChar() throws IOException {
|
||||
int byte1 = in.read();
|
||||
int byte2 = in.read();
|
||||
|
||||
if (byte2 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return (char) (((byte2 << 24) >>> 16) + ((byte1 << 24) >>> 24));
|
||||
}
|
||||
|
||||
@@ -210,6 +220,7 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
if (byte4 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return (byte4 << 24) + ((byte3 << 24) >>> 8)
|
||||
+ ((byte2 << 24) >>> 16) + ((byte1 << 24) >>> 24);
|
||||
}
|
||||
@@ -236,11 +247,11 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
if (byte8 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return (byte8 << 56) + ((byte7 << 56) >>> 8)
|
||||
+ ((byte6 << 56) >>> 16) + ((byte5 << 56) >>> 24)
|
||||
+ ((byte4 << 56) >>> 32) + ((byte3 << 56) >>> 40)
|
||||
+ ((byte2 << 56) >>> 48) + ((byte1 << 56) >>> 56);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,16 +271,17 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
public String readUTF() throws IOException {
|
||||
int byte1 = in.read();
|
||||
int byte2 = in.read();
|
||||
|
||||
if (byte2 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
int numbytes = (byte1 << 8) + byte2;
|
||||
char result[] = new char[numbytes];
|
||||
int numread = 0;
|
||||
int numchars = 0;
|
||||
|
||||
while (numread < numbytes) {
|
||||
|
||||
int c1 = readUnsignedByte();
|
||||
int c2, c3;
|
||||
|
||||
@@ -281,27 +293,34 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
}
|
||||
else if (test == 12 || test == 13) { // two bytes
|
||||
numread += 2;
|
||||
|
||||
if (numread > numbytes) {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
|
||||
c2 = readUnsignedByte();
|
||||
|
||||
if ((c2 & 0xC0) != 0x80) {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
|
||||
result[numchars++] = (char) (((c1 & 0x1F) << 6) | (c2 & 0x3F));
|
||||
}
|
||||
else if (test == 14) { // three bytes
|
||||
numread += 3;
|
||||
|
||||
if (numread > numbytes) {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
|
||||
c2 = readUnsignedByte();
|
||||
c3 = readUnsignedByte();
|
||||
|
||||
if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
result[numchars++] = (char)
|
||||
(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
|
||||
|
||||
result[numchars++] = (char) (((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
|
||||
}
|
||||
else { // malformed
|
||||
throw new UTFDataFormatException();
|
||||
@@ -396,12 +415,16 @@ public class LittleEndianDataInputStream extends FilterInputStream implements Da
|
||||
if (pLength < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
while (count < pLength) {
|
||||
int read = in.read(pBytes, pOffset + count, pLength - count);
|
||||
|
||||
if (read < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
count += read;
|
||||
}
|
||||
}
|
||||
|
@@ -38,6 +38,8 @@
|
||||
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
@@ -69,7 +71,7 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
/**
|
||||
* The number of bytes written so far to the little endian output stream.
|
||||
*/
|
||||
protected int mWritten;
|
||||
protected int bytesWritten;
|
||||
|
||||
/**
|
||||
* Creates a new little endian output stream and chains it to the
|
||||
@@ -79,10 +81,7 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
* @see java.io.FilterOutputStream#out
|
||||
*/
|
||||
public LittleEndianDataOutputStream(OutputStream pStream) {
|
||||
super(pStream);
|
||||
if (pStream == null) {
|
||||
throw new IllegalArgumentException("stream == null");
|
||||
}
|
||||
super(Validate.notNull(pStream, "stream"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +92,7 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
*/
|
||||
public synchronized void write(int pByte) throws IOException {
|
||||
out.write(pByte);
|
||||
mWritten++;
|
||||
bytesWritten++;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,10 +104,9 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
* @param pLength the number of bytes to write.
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public synchronized void write(byte[] pBytes, int pOffset, int pLength)
|
||||
throws IOException {
|
||||
public synchronized void write(byte[] pBytes, int pOffset, int pLength) throws IOException {
|
||||
out.write(pBytes, pOffset, pLength);
|
||||
mWritten += pLength;
|
||||
bytesWritten += pLength;
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +135,7 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
*/
|
||||
public void writeByte(int pByte) throws IOException {
|
||||
out.write(pByte);
|
||||
mWritten++;
|
||||
bytesWritten++;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,7 +148,7 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
public void writeShort(int pShort) throws IOException {
|
||||
out.write(pShort & 0xFF);
|
||||
out.write((pShort >>> 8) & 0xFF);
|
||||
mWritten += 2;
|
||||
bytesWritten += 2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +161,7 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
public void writeChar(int pChar) throws IOException {
|
||||
out.write(pChar & 0xFF);
|
||||
out.write((pChar >>> 8) & 0xFF);
|
||||
mWritten += 2;
|
||||
bytesWritten += 2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +176,7 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
out.write((pInt >>> 8) & 0xFF);
|
||||
out.write((pInt >>> 16) & 0xFF);
|
||||
out.write((pInt >>> 24) & 0xFF);
|
||||
mWritten += 4;
|
||||
bytesWritten += 4;
|
||||
|
||||
}
|
||||
|
||||
@@ -198,7 +196,7 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
out.write((int) (pLong >>> 40) & 0xFF);
|
||||
out.write((int) (pLong >>> 48) & 0xFF);
|
||||
out.write((int) (pLong >>> 56) & 0xFF);
|
||||
mWritten += 8;
|
||||
bytesWritten += 8;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,10 +233,12 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
*/
|
||||
public void writeBytes(String pString) throws IOException {
|
||||
int length = pString.length();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
out.write((byte) pString.charAt(i));
|
||||
}
|
||||
mWritten += length;
|
||||
|
||||
bytesWritten += length;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,12 +253,14 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
*/
|
||||
public void writeChars(String pString) throws IOException {
|
||||
int length = pString.length();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int c = pString.charAt(i);
|
||||
out.write(c & 0xFF);
|
||||
out.write((c >>> 8) & 0xFF);
|
||||
}
|
||||
mWritten += length * 2;
|
||||
|
||||
bytesWritten += length * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,6 +284,7 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
|
||||
for (int i = 0; i < numchars; i++) {
|
||||
int c = pString.charAt(i);
|
||||
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
numbytes++;
|
||||
}
|
||||
@@ -299,8 +302,10 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
|
||||
out.write((numbytes >>> 8) & 0xFF);
|
||||
out.write(numbytes & 0xFF);
|
||||
|
||||
for (int i = 0; i < numchars; i++) {
|
||||
int c = pString.charAt(i);
|
||||
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
out.write(c);
|
||||
}
|
||||
@@ -308,16 +313,16 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
out.write(0xE0 | ((c >> 12) & 0x0F));
|
||||
out.write(0x80 | ((c >> 6) & 0x3F));
|
||||
out.write(0x80 | (c & 0x3F));
|
||||
mWritten += 2;
|
||||
bytesWritten += 2;
|
||||
}
|
||||
else {
|
||||
out.write(0xC0 | ((c >> 6) & 0x1F));
|
||||
out.write(0x80 | (c & 0x3F));
|
||||
mWritten += 1;
|
||||
bytesWritten += 1;
|
||||
}
|
||||
}
|
||||
|
||||
mWritten += numchars + 2;
|
||||
bytesWritten += numchars + 2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,9 +331,9 @@ public class LittleEndianDataOutputStream extends FilterOutputStream implements
|
||||
* possible that this number is temporarily less than the actual
|
||||
* number of bytes written.)
|
||||
* @return the value of the {@code written} field.
|
||||
* @see #mWritten
|
||||
* @see #bytesWritten
|
||||
*/
|
||||
public int size() {
|
||||
return mWritten;
|
||||
return bytesWritten;
|
||||
}
|
||||
}
|
@@ -56,58 +56,58 @@ import java.nio.channels.FileChannel;
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/LittleEndianRandomAccessFile.java#1 $
|
||||
*/
|
||||
public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
private RandomAccessFile mFile;
|
||||
private RandomAccessFile file;
|
||||
|
||||
public LittleEndianRandomAccessFile(final String pName, final String pMode) throws FileNotFoundException {
|
||||
this(FileUtil.resolve(pName), pMode);
|
||||
}
|
||||
|
||||
public LittleEndianRandomAccessFile(final File pFile, final String pMode) throws FileNotFoundException {
|
||||
mFile = new RandomAccessFile(pFile, pMode);
|
||||
file = new RandomAccessFile(pFile, pMode);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
mFile.close();
|
||||
file.close();
|
||||
}
|
||||
|
||||
public FileChannel getChannel() {
|
||||
return mFile.getChannel();
|
||||
return file.getChannel();
|
||||
}
|
||||
|
||||
public FileDescriptor getFD() throws IOException {
|
||||
return mFile.getFD();
|
||||
return file.getFD();
|
||||
}
|
||||
|
||||
public long getFilePointer() throws IOException {
|
||||
return mFile.getFilePointer();
|
||||
return file.getFilePointer();
|
||||
}
|
||||
|
||||
public long length() throws IOException {
|
||||
return mFile.length();
|
||||
return file.length();
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
return mFile.read();
|
||||
return file.read();
|
||||
}
|
||||
|
||||
public int read(final byte[] b) throws IOException {
|
||||
return mFile.read(b);
|
||||
return file.read(b);
|
||||
}
|
||||
|
||||
public int read(final byte[] b, final int off, final int len) throws IOException {
|
||||
return mFile.read(b, off, len);
|
||||
return file.read(b, off, len);
|
||||
}
|
||||
|
||||
public void readFully(final byte[] b) throws IOException {
|
||||
mFile.readFully(b);
|
||||
file.readFully(b);
|
||||
}
|
||||
|
||||
public void readFully(final byte[] b, final int off, final int len) throws IOException {
|
||||
mFile.readFully(b, off, len);
|
||||
file.readFully(b, off, len);
|
||||
}
|
||||
|
||||
public String readLine() throws IOException {
|
||||
return mFile.readLine();
|
||||
return file.readLine();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,10 +121,12 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public boolean readBoolean() throws IOException {
|
||||
int b = mFile.read();
|
||||
int b = file.read();
|
||||
|
||||
if (b < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return b != 0;
|
||||
}
|
||||
|
||||
@@ -138,10 +140,12 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public byte readByte() throws IOException {
|
||||
int b = mFile.read();
|
||||
int b = file.read();
|
||||
|
||||
if (b < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return (byte) b;
|
||||
|
||||
}
|
||||
@@ -156,10 +160,12 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public int readUnsignedByte() throws IOException {
|
||||
int b = mFile.read();
|
||||
int b = file.read();
|
||||
|
||||
if (b < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -173,13 +179,15 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public short readShort() throws IOException {
|
||||
int byte1 = mFile.read();
|
||||
int byte2 = mFile.read();
|
||||
int byte1 = file.read();
|
||||
int byte2 = file.read();
|
||||
|
||||
// only need to test last byte read
|
||||
// if byte1 is -1 so is byte2
|
||||
if (byte2 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return (short) (((byte2 << 24) >>> 16) + (byte1 << 24) >>> 24);
|
||||
}
|
||||
|
||||
@@ -193,11 +201,13 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public int readUnsignedShort() throws IOException {
|
||||
int byte1 = mFile.read();
|
||||
int byte2 = mFile.read();
|
||||
int byte1 = file.read();
|
||||
int byte2 = file.read();
|
||||
|
||||
if (byte2 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
//return ((byte2 << 24) >> 16) + ((byte1 << 24) >> 24);
|
||||
return (byte2 << 8) + byte1;
|
||||
}
|
||||
@@ -212,11 +222,13 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public char readChar() throws IOException {
|
||||
int byte1 = mFile.read();
|
||||
int byte2 = mFile.read();
|
||||
int byte1 = file.read();
|
||||
int byte2 = file.read();
|
||||
|
||||
if (byte2 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return (char) (((byte2 << 24) >>> 16) + ((byte1 << 24) >>> 24));
|
||||
}
|
||||
|
||||
@@ -231,16 +243,16 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public int readInt() throws IOException {
|
||||
int byte1 = mFile.read();
|
||||
int byte2 = mFile.read();
|
||||
int byte3 = mFile.read();
|
||||
int byte4 = mFile.read();
|
||||
int byte1 = file.read();
|
||||
int byte2 = file.read();
|
||||
int byte3 = file.read();
|
||||
int byte4 = file.read();
|
||||
|
||||
if (byte4 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return (byte4 << 24) + ((byte3 << 24) >>> 8)
|
||||
+ ((byte2 << 24) >>> 16) + ((byte1 << 24) >>> 24);
|
||||
|
||||
return (byte4 << 24) + ((byte3 << 24) >>> 8) + ((byte2 << 24) >>> 16) + ((byte1 << 24) >>> 24);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,18 +265,19 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public long readLong() throws IOException {
|
||||
long byte1 = mFile.read();
|
||||
long byte2 = mFile.read();
|
||||
long byte3 = mFile.read();
|
||||
long byte4 = mFile.read();
|
||||
long byte5 = mFile.read();
|
||||
long byte6 = mFile.read();
|
||||
long byte7 = mFile.read();
|
||||
long byte8 = mFile.read();
|
||||
long byte1 = file.read();
|
||||
long byte2 = file.read();
|
||||
long byte3 = file.read();
|
||||
long byte4 = file.read();
|
||||
long byte5 = file.read();
|
||||
long byte6 = file.read();
|
||||
long byte7 = file.read();
|
||||
long byte8 = file.read();
|
||||
|
||||
if (byte8 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return (byte8 << 56) + ((byte7 << 56) >>> 8)
|
||||
+ ((byte6 << 56) >>> 16) + ((byte5 << 56) >>> 24)
|
||||
+ ((byte4 << 56) >>> 32) + ((byte3 << 56) >>> 40)
|
||||
@@ -287,11 +300,13 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public String readUTF() throws IOException {
|
||||
int byte1 = mFile.read();
|
||||
int byte2 = mFile.read();
|
||||
int byte1 = file.read();
|
||||
int byte2 = file.read();
|
||||
|
||||
if (byte2 < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
int numbytes = (byte1 << 8) + byte2;
|
||||
char result[] = new char[numbytes];
|
||||
int numread = 0;
|
||||
@@ -310,27 +325,34 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
}
|
||||
else if (test == 12 || test == 13) { // two bytes
|
||||
numread += 2;
|
||||
|
||||
if (numread > numbytes) {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
|
||||
c2 = readUnsignedByte();
|
||||
|
||||
if ((c2 & 0xC0) != 0x80) {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
|
||||
result[numchars++] = (char) (((c1 & 0x1F) << 6) | (c2 & 0x3F));
|
||||
}
|
||||
else if (test == 14) { // three bytes
|
||||
numread += 3;
|
||||
|
||||
if (numread > numbytes) {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
|
||||
c2 = readUnsignedByte();
|
||||
c3 = readUnsignedByte();
|
||||
|
||||
if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
result[numchars++] = (char)
|
||||
(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
|
||||
|
||||
result[numchars++] = (char) (((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
|
||||
}
|
||||
else { // malformed
|
||||
throw new UTFDataFormatException();
|
||||
@@ -378,27 +400,27 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* {@code 0} or if an I/O error occurs.
|
||||
*/
|
||||
public void seek(final long pos) throws IOException {
|
||||
mFile.seek(pos);
|
||||
file.seek(pos);
|
||||
}
|
||||
|
||||
public void setLength(final long newLength) throws IOException {
|
||||
mFile.setLength(newLength);
|
||||
file.setLength(newLength);
|
||||
}
|
||||
|
||||
public int skipBytes(final int n) throws IOException {
|
||||
return mFile.skipBytes(n);
|
||||
return file.skipBytes(n);
|
||||
}
|
||||
|
||||
public void write(final byte[] b) throws IOException {
|
||||
mFile.write(b);
|
||||
file.write(b);
|
||||
}
|
||||
|
||||
public void write(final byte[] b, final int off, final int len) throws IOException {
|
||||
mFile.write(b, off, len);
|
||||
file.write(b, off, len);
|
||||
}
|
||||
|
||||
public void write(final int b) throws IOException {
|
||||
mFile.write(b);
|
||||
file.write(b);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -425,7 +447,7 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public void writeByte(int pByte) throws IOException {
|
||||
mFile.write(pByte);
|
||||
file.write(pByte);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,8 +458,8 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public void writeShort(int pShort) throws IOException {
|
||||
mFile.write(pShort & 0xFF);
|
||||
mFile.write((pShort >>> 8) & 0xFF);
|
||||
file.write(pShort & 0xFF);
|
||||
file.write((pShort >>> 8) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -448,8 +470,8 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public void writeChar(int pChar) throws IOException {
|
||||
mFile.write(pChar & 0xFF);
|
||||
mFile.write((pChar >>> 8) & 0xFF);
|
||||
file.write(pChar & 0xFF);
|
||||
file.write((pChar >>> 8) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,11 +482,10 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public void writeInt(int pInt) throws IOException {
|
||||
mFile.write(pInt & 0xFF);
|
||||
mFile.write((pInt >>> 8) & 0xFF);
|
||||
mFile.write((pInt >>> 16) & 0xFF);
|
||||
mFile.write((pInt >>> 24) & 0xFF);
|
||||
|
||||
file.write(pInt & 0xFF);
|
||||
file.write((pInt >>> 8) & 0xFF);
|
||||
file.write((pInt >>> 16) & 0xFF);
|
||||
file.write((pInt >>> 24) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -475,14 +496,14 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
public void writeLong(long pLong) throws IOException {
|
||||
mFile.write((int) pLong & 0xFF);
|
||||
mFile.write((int) (pLong >>> 8) & 0xFF);
|
||||
mFile.write((int) (pLong >>> 16) & 0xFF);
|
||||
mFile.write((int) (pLong >>> 24) & 0xFF);
|
||||
mFile.write((int) (pLong >>> 32) & 0xFF);
|
||||
mFile.write((int) (pLong >>> 40) & 0xFF);
|
||||
mFile.write((int) (pLong >>> 48) & 0xFF);
|
||||
mFile.write((int) (pLong >>> 56) & 0xFF);
|
||||
file.write((int) pLong & 0xFF);
|
||||
file.write((int) (pLong >>> 8) & 0xFF);
|
||||
file.write((int) (pLong >>> 16) & 0xFF);
|
||||
file.write((int) (pLong >>> 24) & 0xFF);
|
||||
file.write((int) (pLong >>> 32) & 0xFF);
|
||||
file.write((int) (pLong >>> 40) & 0xFF);
|
||||
file.write((int) (pLong >>> 48) & 0xFF);
|
||||
file.write((int) (pLong >>> 56) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -515,12 +536,13 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @param pString the {@code String} value to be written.
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
* @see #writeByte(int)
|
||||
* @see #mFile
|
||||
* @see #file
|
||||
*/
|
||||
public void writeBytes(String pString) throws IOException {
|
||||
int length = pString.length();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
mFile.write((byte) pString.charAt(i));
|
||||
file.write((byte) pString.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,14 +554,15 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
* @param pString a {@code String} value to be written.
|
||||
* @throws IOException if the underlying stream throws an IOException.
|
||||
* @see #writeChar(int)
|
||||
* @see #mFile
|
||||
* @see #file
|
||||
*/
|
||||
public void writeChars(String pString) throws IOException {
|
||||
int length = pString.length();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int c = pString.charAt(i);
|
||||
mFile.write(c & 0xFF);
|
||||
mFile.write((c >>> 8) & 0xFF);
|
||||
file.write(c & 0xFF);
|
||||
file.write((c >>> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,6 +587,7 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
|
||||
for (int i = 0; i < numchars; i++) {
|
||||
int c = pString.charAt(i);
|
||||
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
numbytes++;
|
||||
}
|
||||
@@ -579,21 +603,23 @@ public class LittleEndianRandomAccessFile implements DataInput, DataOutput {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
|
||||
mFile.write((numbytes >>> 8) & 0xFF);
|
||||
mFile.write(numbytes & 0xFF);
|
||||
file.write((numbytes >>> 8) & 0xFF);
|
||||
file.write(numbytes & 0xFF);
|
||||
|
||||
for (int i = 0; i < numchars; i++) {
|
||||
int c = pString.charAt(i);
|
||||
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
mFile.write(c);
|
||||
file.write(c);
|
||||
}
|
||||
else if (c > 0x07FF) {
|
||||
mFile.write(0xE0 | ((c >> 12) & 0x0F));
|
||||
mFile.write(0x80 | ((c >> 6) & 0x3F));
|
||||
mFile.write(0x80 | (c & 0x3F));
|
||||
file.write(0xE0 | ((c >> 12) & 0x0F));
|
||||
file.write(0x80 | ((c >> 6) & 0x3F));
|
||||
file.write(0x80 | (c & 0x3F));
|
||||
}
|
||||
else {
|
||||
mFile.write(0xC0 | ((c >> 6) & 0x1F));
|
||||
mFile.write(0x80 | (c & 0x3F));
|
||||
file.write(0xC0 | ((c >> 6) & 0x1F));
|
||||
file.write(0x80 | (c & 0x3F));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -65,13 +65,13 @@ public final class MemoryCacheSeekableStream extends AbstractCachedSeekableStrea
|
||||
final static class MemoryCache extends StreamCache {
|
||||
final static int BLOCK_SIZE = 1 << 13;
|
||||
|
||||
private final List<byte[]> mCache = new ArrayList<byte[]>();
|
||||
private long mLength;
|
||||
private long mPosition;
|
||||
private long mStart;
|
||||
private final List<byte[]> cache = new ArrayList<byte[]>();
|
||||
private long length;
|
||||
private long position;
|
||||
private long start;
|
||||
|
||||
private byte[] getBlock() throws IOException {
|
||||
final long currPos = mPosition - mStart;
|
||||
final long currPos = position - start;
|
||||
if (currPos < 0) {
|
||||
throw new IOException("StreamCache flushed before read position");
|
||||
}
|
||||
@@ -82,31 +82,31 @@ public final class MemoryCacheSeekableStream extends AbstractCachedSeekableStrea
|
||||
throw new IOException("Memory cache max size exceeded");
|
||||
}
|
||||
|
||||
if (index >= mCache.size()) {
|
||||
if (index >= cache.size()) {
|
||||
try {
|
||||
mCache.add(new byte[BLOCK_SIZE]);
|
||||
cache.add(new byte[BLOCK_SIZE]);
|
||||
// System.out.println("Allocating new block, size: " + BLOCK_SIZE);
|
||||
// System.out.println("New total size: " + mCache.size() * BLOCK_SIZE + " (" + mCache.size() + " blocks)");
|
||||
// System.out.println("New total size: " + cache.size() * BLOCK_SIZE + " (" + cache.size() + " blocks)");
|
||||
}
|
||||
catch (OutOfMemoryError e) {
|
||||
throw new IOException("No more memory for cache: " + mCache.size() * BLOCK_SIZE);
|
||||
throw new IOException("No more memory for cache: " + cache.size() * BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println("index: " + index);
|
||||
|
||||
return mCache.get((int) index);
|
||||
return cache.get((int) index);
|
||||
}
|
||||
|
||||
public void write(final int pByte) throws IOException {
|
||||
byte[] buffer = getBlock();
|
||||
|
||||
int idx = (int) (mPosition % BLOCK_SIZE);
|
||||
int idx = (int) (position % BLOCK_SIZE);
|
||||
buffer[idx] = (byte) pByte;
|
||||
mPosition++;
|
||||
position++;
|
||||
|
||||
if (mPosition > mLength) {
|
||||
mLength = mPosition;
|
||||
if (position > length) {
|
||||
length = position;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,28 +115,28 @@ public final class MemoryCacheSeekableStream extends AbstractCachedSeekableStrea
|
||||
public void write(final byte[] pBuffer, final int pOffset, final int pLength) throws IOException {
|
||||
byte[] buffer = getBlock();
|
||||
for (int i = 0; i < pLength; i++) {
|
||||
int index = (int) mPosition % BLOCK_SIZE;
|
||||
int index = (int) position % BLOCK_SIZE;
|
||||
if (index == 0) {
|
||||
buffer = getBlock();
|
||||
}
|
||||
buffer[index] = pBuffer[pOffset + i];
|
||||
|
||||
mPosition++;
|
||||
position++;
|
||||
}
|
||||
if (mPosition > mLength) {
|
||||
mLength = mPosition;
|
||||
if (position > length) {
|
||||
length = position;
|
||||
}
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (mPosition >= mLength) {
|
||||
if (position >= length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
byte[] buffer = getBlock();
|
||||
|
||||
int idx = (int) (mPosition % BLOCK_SIZE);
|
||||
mPosition++;
|
||||
int idx = (int) (position % BLOCK_SIZE);
|
||||
position++;
|
||||
|
||||
return buffer[idx] & 0xff;
|
||||
}
|
||||
@@ -144,33 +144,33 @@ public final class MemoryCacheSeekableStream extends AbstractCachedSeekableStrea
|
||||
// TODO: OptimizeMe!!!
|
||||
@Override
|
||||
public int read(final byte[] pBytes, final int pOffset, final int pLength) throws IOException {
|
||||
if (mPosition >= mLength) {
|
||||
if (position >= length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
byte[] buffer = getBlock();
|
||||
|
||||
int bufferPos = (int) (mPosition % BLOCK_SIZE);
|
||||
int bufferPos = (int) (position % BLOCK_SIZE);
|
||||
|
||||
// Find maxIdx and simplify test in for-loop
|
||||
int maxLen = (int) Math.min(Math.min(pLength, buffer.length - bufferPos), mLength - mPosition);
|
||||
int maxLen = (int) Math.min(Math.min(pLength, buffer.length - bufferPos), length - position);
|
||||
|
||||
int i;
|
||||
//for (i = 0; i < pLength && i < buffer.length - idx && i < mLength - mPosition; i++) {
|
||||
//for (i = 0; i < pLength && i < buffer.length - idx && i < length - position; i++) {
|
||||
for (i = 0; i < maxLen; i++) {
|
||||
pBytes[pOffset + i] = buffer[bufferPos + i];
|
||||
}
|
||||
|
||||
mPosition += i;
|
||||
position += i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void seek(final long pPosition) throws IOException {
|
||||
if (pPosition < mStart) {
|
||||
if (pPosition < start) {
|
||||
throw new IOException("Seek before flush position");
|
||||
}
|
||||
mPosition = pPosition;
|
||||
position = pPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,14 +178,14 @@ public final class MemoryCacheSeekableStream extends AbstractCachedSeekableStrea
|
||||
int firstPos = (int) (pPosition / BLOCK_SIZE) - 1;
|
||||
|
||||
for (int i = 0; i < firstPos; i++) {
|
||||
mCache.remove(0);
|
||||
cache.remove(0);
|
||||
}
|
||||
|
||||
mStart = pPosition;
|
||||
start = pPosition;
|
||||
}
|
||||
|
||||
public long getPosition() {
|
||||
return mPosition;
|
||||
return position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -50,13 +50,12 @@ public abstract class RandomAccessStream implements Seekable, DataInput, DataOut
|
||||
// TODO: Package private SeekableDelegate?
|
||||
|
||||
// TODO: Both read and write must update stream position
|
||||
//private int mPosition = -1;
|
||||
//private int position = -1;
|
||||
|
||||
/** This random access stream, wrapped in an {@code InputStream} */
|
||||
SeekableInputStream mInputView = null;
|
||||
SeekableInputStream inputView = null;
|
||||
/** This random access stream, wrapped in an {@code OutputStream} */
|
||||
SeekableOutputStream mOutputView = null;
|
||||
|
||||
SeekableOutputStream outputView = null;
|
||||
|
||||
// TODO: Create an Input and an Output interface matching InputStream and OutputStream?
|
||||
public int read() throws IOException {
|
||||
@@ -119,10 +118,10 @@ public abstract class RandomAccessStream implements Seekable, DataInput, DataOut
|
||||
* @return a {@code SeekableInputStream} reading from this stream
|
||||
*/
|
||||
public final SeekableInputStream asInputStream() {
|
||||
if (mInputView == null) {
|
||||
mInputView = new InputStreamView(this);
|
||||
if (inputView == null) {
|
||||
inputView = new InputStreamView(this);
|
||||
}
|
||||
return mInputView;
|
||||
return inputView;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,15 +133,15 @@ public abstract class RandomAccessStream implements Seekable, DataInput, DataOut
|
||||
* @return a {@code SeekableOutputStream} writing to this stream
|
||||
*/
|
||||
public final SeekableOutputStream asOutputStream() {
|
||||
if (mOutputView == null) {
|
||||
mOutputView = new OutputStreamView(this);
|
||||
if (outputView == null) {
|
||||
outputView = new OutputStreamView(this);
|
||||
}
|
||||
return mOutputView;
|
||||
return outputView;
|
||||
}
|
||||
|
||||
static final class InputStreamView extends SeekableInputStream {
|
||||
// TODO: Consider adding synchonization (on mStream) for all operations
|
||||
// TODO: Is is a good thing that close/flush etc works on mStream?
|
||||
// TODO: Consider adding synchonization (on stream) for all operations
|
||||
// TODO: Is is a good thing that close/flush etc works on stream?
|
||||
// - Or should it rather just work on the views?
|
||||
// - Allow multiple views?
|
||||
|
||||
@@ -190,8 +189,8 @@ public abstract class RandomAccessStream implements Seekable, DataInput, DataOut
|
||||
}
|
||||
|
||||
static final class OutputStreamView extends SeekableOutputStream {
|
||||
// TODO: Consider adding synchonization (on mStream) for all operations
|
||||
// TODO: Is is a good thing that close/flush etc works on mStream?
|
||||
// TODO: Consider adding synchonization (on stream) for all operations
|
||||
// TODO: Is is a good thing that close/flush etc works on stream?
|
||||
// - Or should it rather just work on the views?
|
||||
// - Allow multiple views?
|
||||
|
||||
|
@@ -43,15 +43,15 @@ import java.util.Stack;
|
||||
public abstract class SeekableInputStream extends InputStream implements Seekable {
|
||||
|
||||
// TODO: It's at the moment not possible to create subclasses outside this
|
||||
// package, as there's no access to mPosition. mPosition needs to be
|
||||
// package, as there's no access to position. position needs to be
|
||||
// updated from the read/read/read methods...
|
||||
|
||||
/** The stream position in this stream */
|
||||
long mPosition;
|
||||
long mFlushedPosition;
|
||||
boolean mClosed;
|
||||
long position;
|
||||
long flushedPosition;
|
||||
boolean closed;
|
||||
|
||||
protected Stack<Long> mMarkedPositions = new Stack<Long>();
|
||||
protected Stack<Long> markedPositions = new Stack<Long>();
|
||||
|
||||
/// InputStream overrides
|
||||
@Override
|
||||
@@ -70,8 +70,8 @@ public abstract class SeekableInputStream extends InputStream implements Seekabl
|
||||
*/
|
||||
@Override
|
||||
public final long skip(long pLength) throws IOException {
|
||||
long pos = mPosition;
|
||||
if (pos + pLength < mFlushedPosition) {
|
||||
long pos = position;
|
||||
if (pos + pLength < flushedPosition) {
|
||||
throw new IOException("position < flushedPosition");
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public abstract class SeekableInputStream extends InputStream implements Seekabl
|
||||
// to seek past end of stream
|
||||
seek(Math.min(pos + pLength, pos + available()));
|
||||
|
||||
return mPosition - pos;
|
||||
return position - pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,7 +88,7 @@ public abstract class SeekableInputStream extends InputStream implements Seekabl
|
||||
|
||||
// TODO: We don't really need to do this.. Is it a good idea?
|
||||
try {
|
||||
flushBefore(Math.max(mPosition - pLimit, mFlushedPosition));
|
||||
flushBefore(Math.max(position - pLimit, flushedPosition));
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
// Ignore, as it's not really critical
|
||||
@@ -111,29 +111,29 @@ public abstract class SeekableInputStream extends InputStream implements Seekabl
|
||||
|
||||
// NOTE: This is correct according to javax.imageio (IndexOutOfBoundsException),
|
||||
// but it's kind of inconsistent with reset that throws IOException...
|
||||
if (pPosition < mFlushedPosition) {
|
||||
if (pPosition < flushedPosition) {
|
||||
throw new IndexOutOfBoundsException("position < flushedPosition");
|
||||
}
|
||||
|
||||
seekImpl(pPosition);
|
||||
mPosition = pPosition;
|
||||
position = pPosition;
|
||||
}
|
||||
|
||||
protected abstract void seekImpl(long pPosition) throws IOException;
|
||||
|
||||
public final void mark() {
|
||||
mMarkedPositions.push(mPosition);
|
||||
markedPositions.push(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void reset() throws IOException {
|
||||
checkOpen();
|
||||
if (!mMarkedPositions.isEmpty()) {
|
||||
long newPos = mMarkedPositions.pop();
|
||||
if (!markedPositions.isEmpty()) {
|
||||
long newPos = markedPositions.pop();
|
||||
|
||||
// NOTE: This is correct according to javax.imageio (IOException),
|
||||
// but it's kind of inconsistent with seek that throws IndexOutOfBoundsException...
|
||||
if (newPos < mFlushedPosition) {
|
||||
if (newPos < flushedPosition) {
|
||||
throw new IOException("Previous marked position has been discarded");
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ public abstract class SeekableInputStream extends InputStream implements Seekabl
|
||||
}
|
||||
|
||||
public final void flushBefore(long pPosition) throws IOException {
|
||||
if (pPosition < mFlushedPosition) {
|
||||
if (pPosition < flushedPosition) {
|
||||
throw new IndexOutOfBoundsException("position < flushedPosition");
|
||||
}
|
||||
if (pPosition > getStreamPosition()) {
|
||||
@@ -158,7 +158,7 @@ public abstract class SeekableInputStream extends InputStream implements Seekabl
|
||||
}
|
||||
checkOpen();
|
||||
flushBeforeImpl(pPosition);
|
||||
mFlushedPosition = pPosition;
|
||||
flushedPosition = pPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,21 +172,21 @@ public abstract class SeekableInputStream extends InputStream implements Seekabl
|
||||
protected abstract void flushBeforeImpl(long pPosition) throws IOException;
|
||||
|
||||
public final void flush() throws IOException {
|
||||
flushBefore(mFlushedPosition);
|
||||
flushBefore(flushedPosition);
|
||||
}
|
||||
|
||||
public final long getFlushedPosition() throws IOException {
|
||||
checkOpen();
|
||||
return mFlushedPosition;
|
||||
return flushedPosition;
|
||||
}
|
||||
|
||||
public final long getStreamPosition() throws IOException {
|
||||
checkOpen();
|
||||
return mPosition;
|
||||
return position;
|
||||
}
|
||||
|
||||
protected final void checkOpen() throws IOException {
|
||||
if (mClosed) {
|
||||
if (closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,7 @@ public abstract class SeekableInputStream extends InputStream implements Seekabl
|
||||
@Override
|
||||
public final void close() throws IOException {
|
||||
checkOpen();
|
||||
mClosed = true;
|
||||
closed = true;
|
||||
closeImpl();
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ public abstract class SeekableInputStream extends InputStream implements Seekabl
|
||||
*/
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (!mClosed) {
|
||||
if (!closed) {
|
||||
try {
|
||||
close();
|
||||
}
|
||||
|
@@ -43,11 +43,11 @@ import java.util.Stack;
|
||||
*/
|
||||
public abstract class SeekableOutputStream extends OutputStream implements Seekable {
|
||||
// TODO: Implement
|
||||
long mPosition;
|
||||
long mFlushedPosition;
|
||||
boolean mClosed;
|
||||
long position;
|
||||
long flushedPosition;
|
||||
boolean closed;
|
||||
|
||||
protected Stack<Long> mMarkedPositions = new Stack<Long>();
|
||||
protected Stack<Long> markedPositions = new Stack<Long>();
|
||||
|
||||
/// Outputstream overrides
|
||||
@Override
|
||||
@@ -63,28 +63,28 @@ public abstract class SeekableOutputStream extends OutputStream implements Seeka
|
||||
|
||||
// TODO: This is correct according to javax.imageio (IndexOutOfBoundsException),
|
||||
// but it's inconsistent with reset that throws IOException...
|
||||
if (pPosition < mFlushedPosition) {
|
||||
if (pPosition < flushedPosition) {
|
||||
throw new IndexOutOfBoundsException("position < flushedPosition!");
|
||||
}
|
||||
|
||||
seekImpl(pPosition);
|
||||
mPosition = pPosition;
|
||||
position = pPosition;
|
||||
}
|
||||
|
||||
protected abstract void seekImpl(long pPosition) throws IOException;
|
||||
|
||||
public final void mark() {
|
||||
mMarkedPositions.push(mPosition);
|
||||
markedPositions.push(position);
|
||||
}
|
||||
|
||||
public final void reset() throws IOException {
|
||||
checkOpen();
|
||||
if (!mMarkedPositions.isEmpty()) {
|
||||
long newPos = mMarkedPositions.pop();
|
||||
if (!markedPositions.isEmpty()) {
|
||||
long newPos = markedPositions.pop();
|
||||
|
||||
// TODO: This is correct according to javax.imageio (IOException),
|
||||
// but it's inconsistent with seek that throws IndexOutOfBoundsException...
|
||||
if (newPos < mFlushedPosition) {
|
||||
if (newPos < flushedPosition) {
|
||||
throw new IOException("Previous marked position has been discarded!");
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public abstract class SeekableOutputStream extends OutputStream implements Seeka
|
||||
}
|
||||
|
||||
public final void flushBefore(long pPosition) throws IOException {
|
||||
if (pPosition < mFlushedPosition) {
|
||||
if (pPosition < flushedPosition) {
|
||||
throw new IndexOutOfBoundsException("position < flushedPosition!");
|
||||
}
|
||||
if (pPosition > getStreamPosition()) {
|
||||
@@ -101,28 +101,28 @@ public abstract class SeekableOutputStream extends OutputStream implements Seeka
|
||||
}
|
||||
checkOpen();
|
||||
flushBeforeImpl(pPosition);
|
||||
mFlushedPosition = pPosition;
|
||||
flushedPosition = pPosition;
|
||||
}
|
||||
|
||||
protected abstract void flushBeforeImpl(long pPosition) throws IOException;
|
||||
|
||||
@Override
|
||||
public final void flush() throws IOException {
|
||||
flushBefore(mFlushedPosition);
|
||||
flushBefore(flushedPosition);
|
||||
}
|
||||
|
||||
public final long getFlushedPosition() throws IOException {
|
||||
checkOpen();
|
||||
return mFlushedPosition;
|
||||
return flushedPosition;
|
||||
}
|
||||
|
||||
public final long getStreamPosition() throws IOException {
|
||||
checkOpen();
|
||||
return mPosition;
|
||||
return position;
|
||||
}
|
||||
|
||||
protected final void checkOpen() throws IOException {
|
||||
if (mClosed) {
|
||||
if (closed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ public abstract class SeekableOutputStream extends OutputStream implements Seeka
|
||||
@Override
|
||||
public final void close() throws IOException {
|
||||
checkOpen();
|
||||
mClosed = true;
|
||||
closed = true;
|
||||
closeImpl();
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,8 @@
|
||||
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
@@ -42,13 +44,13 @@ import java.io.Reader;
|
||||
*/
|
||||
public class StringArrayReader extends StringReader {
|
||||
|
||||
private StringReader mCurrent;
|
||||
private String[] mStrings;
|
||||
protected final Object mLock;
|
||||
private int mCurrentSting;
|
||||
private int mMarkedString;
|
||||
private int mMark;
|
||||
private int mNext;
|
||||
private StringReader current;
|
||||
private String[] strings;
|
||||
protected final Object finalLock;
|
||||
private int currentSting;
|
||||
private int markedString;
|
||||
private int mark;
|
||||
private int next;
|
||||
|
||||
/**
|
||||
* Create a new string array reader.
|
||||
@@ -57,28 +59,28 @@ public class StringArrayReader extends StringReader {
|
||||
*/
|
||||
public StringArrayReader(final String[] pStrings) {
|
||||
super("");
|
||||
if (pStrings == null) {
|
||||
throw new NullPointerException("strings == null");
|
||||
}
|
||||
|
||||
mLock = lock = pStrings; // NOTE: It's ok to sync on pStrings, as the
|
||||
Validate.notNull(pStrings, "strings");
|
||||
|
||||
finalLock = lock = pStrings; // NOTE: It's ok to sync on pStrings, as the
|
||||
// reference can't change, only it's elements
|
||||
|
||||
mStrings = pStrings.clone(); // Defensive copy for content
|
||||
strings = pStrings.clone(); // Defensive copy for content
|
||||
nextReader();
|
||||
}
|
||||
|
||||
protected final Reader nextReader() {
|
||||
if (mCurrentSting >= mStrings.length) {
|
||||
mCurrent = new EmptyReader();
|
||||
if (currentSting >= strings.length) {
|
||||
current = new EmptyReader();
|
||||
}
|
||||
else {
|
||||
mCurrent = new StringReader(mStrings[mCurrentSting++]);
|
||||
current = new StringReader(strings[currentSting++]);
|
||||
}
|
||||
// NOTE: Reset mNext for every reader, and record marked reader in mark/reset methods!
|
||||
mNext = 0;
|
||||
|
||||
// NOTE: Reset next for every reader, and record marked reader in mark/reset methods!
|
||||
next = 0;
|
||||
|
||||
return mCurrent;
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,15 +89,15 @@ public class StringArrayReader extends StringReader {
|
||||
* @throws IOException if the stream is closed
|
||||
*/
|
||||
protected final void ensureOpen() throws IOException {
|
||||
if (mStrings == null) {
|
||||
if (strings == null) {
|
||||
throw new IOException("Stream closed");
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
super.close();
|
||||
mStrings = null;
|
||||
mCurrent.close();
|
||||
strings = null;
|
||||
current.close();
|
||||
}
|
||||
|
||||
public void mark(int pReadLimit) throws IOException {
|
||||
@@ -103,29 +105,29 @@ public class StringArrayReader extends StringReader {
|
||||
throw new IllegalArgumentException("Read limit < 0");
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
synchronized (finalLock) {
|
||||
ensureOpen();
|
||||
mMark = mNext;
|
||||
mMarkedString = mCurrentSting;
|
||||
mark = next;
|
||||
markedString = currentSting;
|
||||
|
||||
mCurrent.mark(pReadLimit);
|
||||
current.mark(pReadLimit);
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() throws IOException {
|
||||
synchronized (mLock) {
|
||||
synchronized (finalLock) {
|
||||
ensureOpen();
|
||||
|
||||
if (mCurrentSting != mMarkedString) {
|
||||
mCurrentSting = mMarkedString - 1;
|
||||
if (currentSting != markedString) {
|
||||
currentSting = markedString - 1;
|
||||
nextReader();
|
||||
mCurrent.skip(mMark);
|
||||
current.skip(mark);
|
||||
}
|
||||
else {
|
||||
mCurrent.reset();
|
||||
current.reset();
|
||||
}
|
||||
|
||||
mNext = mMark;
|
||||
next = mark;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,49 +136,49 @@ public class StringArrayReader extends StringReader {
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
synchronized (mLock) {
|
||||
int read = mCurrent.read();
|
||||
synchronized (finalLock) {
|
||||
int read = current.read();
|
||||
|
||||
if (read < 0 && mCurrentSting < mStrings.length) {
|
||||
if (read < 0 && currentSting < strings.length) {
|
||||
nextReader();
|
||||
return read(); // In case of empty strings
|
||||
}
|
||||
|
||||
mNext++;
|
||||
next++;
|
||||
|
||||
return read;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(char pBuffer[], int pOffset, int pLength) throws IOException {
|
||||
synchronized (mLock) {
|
||||
int read = mCurrent.read(pBuffer, pOffset, pLength);
|
||||
synchronized (finalLock) {
|
||||
int read = current.read(pBuffer, pOffset, pLength);
|
||||
|
||||
if (read < 0 && mCurrentSting < mStrings.length) {
|
||||
if (read < 0 && currentSting < strings.length) {
|
||||
nextReader();
|
||||
return read(pBuffer, pOffset, pLength); // In case of empty strings
|
||||
}
|
||||
|
||||
mNext += read;
|
||||
next += read;
|
||||
|
||||
return read;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean ready() throws IOException {
|
||||
return mCurrent.ready();
|
||||
return current.ready();
|
||||
}
|
||||
|
||||
public long skip(long pChars) throws IOException {
|
||||
synchronized (mLock) {
|
||||
long skipped = mCurrent.skip(pChars);
|
||||
synchronized (finalLock) {
|
||||
long skipped = current.skip(pChars);
|
||||
|
||||
if (skipped == 0 && mCurrentSting < mStrings.length) {
|
||||
if (skipped == 0 && currentSting < strings.length) {
|
||||
nextReader();
|
||||
return skip(pChars);
|
||||
}
|
||||
|
||||
mNext += skipped;
|
||||
next += skipped;
|
||||
|
||||
return skipped;
|
||||
}
|
||||
|
@@ -43,8 +43,8 @@ import java.io.InputStream;
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/SubStream.java#2 $
|
||||
*/
|
||||
public final class SubStream extends FilterInputStream {
|
||||
private long mLeft;
|
||||
private int mMarkLimit;
|
||||
private long bytesLeft;
|
||||
private int markLimit;
|
||||
|
||||
/**
|
||||
* Creates a {@code SubStream} of the given {@code pStream}.
|
||||
@@ -54,7 +54,7 @@ public final class SubStream extends FilterInputStream {
|
||||
*/
|
||||
public SubStream(final InputStream pStream, final long pLength) {
|
||||
super(Validate.notNull(pStream, "stream"));
|
||||
mLeft = pLength;
|
||||
bytesLeft = pLength;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,32 +64,32 @@ public final class SubStream extends FilterInputStream {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// NOTE: Do not close the underlying stream
|
||||
while (mLeft > 0) {
|
||||
while (bytesLeft > 0) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
skip(mLeft);
|
||||
skip(bytesLeft);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return (int) Math.min(super.available(), mLeft);
|
||||
return (int) Math.min(super.available(), bytesLeft);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(int pReadLimit) {
|
||||
super.mark(pReadLimit);// This either succeeds or does nothing...
|
||||
mMarkLimit = pReadLimit;
|
||||
markLimit = pReadLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
super.reset();// This either succeeds or throws IOException
|
||||
mLeft += mMarkLimit;
|
||||
bytesLeft += markLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (mLeft-- <= 0) {
|
||||
if (bytesLeft-- <= 0) {
|
||||
return -1;
|
||||
}
|
||||
return super.read();
|
||||
@@ -102,12 +102,12 @@ public final class SubStream extends FilterInputStream {
|
||||
|
||||
@Override
|
||||
public int read(final byte[] pBytes, final int pOffset, final int pLength) throws IOException {
|
||||
if (mLeft <= 0) {
|
||||
if (bytesLeft <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int read = super.read(pBytes, pOffset, (int) findMaxLen(pLength));
|
||||
mLeft = read < 0 ? 0 : mLeft - read;
|
||||
bytesLeft = read < 0 ? 0 : bytesLeft - read;
|
||||
return read;
|
||||
}
|
||||
|
||||
@@ -118,8 +118,8 @@ public final class SubStream extends FilterInputStream {
|
||||
* @return the maximum number of bytes to read
|
||||
*/
|
||||
private long findMaxLen(long pLength) {
|
||||
if (mLeft < pLength) {
|
||||
return (int) Math.max(mLeft, 0);
|
||||
if (bytesLeft < pLength) {
|
||||
return (int) Math.max(bytesLeft, 0);
|
||||
}
|
||||
else {
|
||||
return pLength;
|
||||
@@ -129,7 +129,7 @@ public final class SubStream extends FilterInputStream {
|
||||
@Override
|
||||
public long skip(long pLength) throws IOException {
|
||||
long skipped = super.skip(findMaxLen(pLength));// Skips 0 or more, never -1
|
||||
mLeft -= skipped;
|
||||
bytesLeft -= skipped;
|
||||
return skipped;
|
||||
}
|
||||
}
|
||||
|
@@ -50,7 +50,8 @@ final class Win32Lnk extends File {
|
||||
(byte) 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 'F'
|
||||
};
|
||||
|
||||
private final File mTarget;
|
||||
private final File target;
|
||||
|
||||
private static final int FLAG_ITEM_ID_LIST = 0x01;
|
||||
private static final int FLAG_FILE_LOC_INFO = 0x02;
|
||||
private static final int FLAG_DESC_STRING = 0x04;
|
||||
@@ -65,10 +66,10 @@ final class Win32Lnk extends File {
|
||||
File target = parse(this);
|
||||
if (target == this) {
|
||||
// NOTE: This is a workaround
|
||||
// mTarget = this causes infinite loops in some methods
|
||||
// target = this causes infinite loops in some methods
|
||||
target = new File(pPath);
|
||||
}
|
||||
mTarget = target;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
Win32Lnk(final File pPath) throws IOException {
|
||||
@@ -336,24 +337,24 @@ final class Win32Lnk extends File {
|
||||
*/
|
||||
|
||||
public File getTarget() {
|
||||
return mTarget;
|
||||
return target;
|
||||
}
|
||||
|
||||
// java.io.File overrides below
|
||||
|
||||
@Override
|
||||
public boolean isDirectory() {
|
||||
return mTarget.isDirectory();
|
||||
return target.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead() {
|
||||
return mTarget.canRead();
|
||||
return target.canRead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite() {
|
||||
return mTarget.canWrite();
|
||||
return target.canWrite();
|
||||
}
|
||||
|
||||
// NOTE: equals is implemented using compareto == 0
|
||||
@@ -362,7 +363,7 @@ final class Win32Lnk extends File {
|
||||
// TODO: Verify this
|
||||
// Probably not a good idea, as it IS NOT THE SAME file
|
||||
// It's probably better to not override
|
||||
return mTarget.compareTo(pathname);
|
||||
return target.compareTo(pathname);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -375,7 +376,7 @@ final class Win32Lnk extends File {
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return mTarget.exists();
|
||||
return target.exists();
|
||||
}
|
||||
|
||||
// A .lnk may be absolute
|
||||
@@ -385,12 +386,12 @@ final class Win32Lnk extends File {
|
||||
// Theses should be resolved according to the API (for Unix).
|
||||
@Override
|
||||
public File getCanonicalFile() throws IOException {
|
||||
return mTarget.getCanonicalFile();
|
||||
return target.getCanonicalFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCanonicalPath() throws IOException {
|
||||
return mTarget.getCanonicalPath();
|
||||
return target.getCanonicalPath();
|
||||
}
|
||||
|
||||
//public String getName() {
|
||||
@@ -402,47 +403,47 @@ final class Win32Lnk extends File {
|
||||
// public boolean isAbsolute() {
|
||||
@Override
|
||||
public boolean isFile() {
|
||||
return mTarget.isFile();
|
||||
return target.isFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
return mTarget.isHidden();
|
||||
return target.isHidden();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long lastModified() {
|
||||
return mTarget.lastModified();
|
||||
return target.lastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long length() {
|
||||
return mTarget.length();
|
||||
return target.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] list() {
|
||||
return mTarget.list();
|
||||
return target.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] list(final FilenameFilter filter) {
|
||||
return mTarget.list(filter);
|
||||
return target.list(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File[] listFiles() {
|
||||
return Win32File.wrap(mTarget.listFiles());
|
||||
return Win32File.wrap(target.listFiles());
|
||||
}
|
||||
|
||||
@Override
|
||||
public File[] listFiles(final FileFilter filter) {
|
||||
return Win32File.wrap(mTarget.listFiles(filter));
|
||||
return Win32File.wrap(target.listFiles(filter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public File[] listFiles(final FilenameFilter filter) {
|
||||
return Win32File.wrap(mTarget.listFiles(filter));
|
||||
return Win32File.wrap(target.listFiles(filter));
|
||||
}
|
||||
|
||||
// Makes no sense, does it?
|
||||
@@ -454,19 +455,19 @@ final class Win32Lnk extends File {
|
||||
|
||||
@Override
|
||||
public boolean setLastModified(long time) {
|
||||
return mTarget.setLastModified(time);
|
||||
return target.setLastModified(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setReadOnly() {
|
||||
return mTarget.setReadOnly();
|
||||
return target.setReadOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (mTarget.equals(this)) {
|
||||
if (target.equals(this)) {
|
||||
return super.toString();
|
||||
}
|
||||
return super.toString() + " -> " + mTarget.toString();
|
||||
return super.toString() + " -> " + target.toString();
|
||||
}
|
||||
}
|
||||
|
@@ -51,10 +51,11 @@ import java.nio.CharBuffer;
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/WriterOutputStream.java#2 $
|
||||
*/
|
||||
public class WriterOutputStream extends OutputStream {
|
||||
protected Writer mWriter;
|
||||
final protected Decoder mDecoder;
|
||||
final ByteArrayOutputStream mBufferStream = new FastByteArrayOutputStream(1024);
|
||||
private volatile boolean mIsFlushing = false; // Ugly but critical...
|
||||
protected Writer writer;
|
||||
final protected Decoder decoder;
|
||||
final ByteArrayOutputStream bufferStream = new FastByteArrayOutputStream(1024);
|
||||
|
||||
private volatile boolean isFlushing = false; // Ugly but critical...
|
||||
|
||||
private static final boolean NIO_AVAILABLE = isNIOAvailable();
|
||||
|
||||
@@ -71,8 +72,8 @@ public class WriterOutputStream extends OutputStream {
|
||||
}
|
||||
|
||||
public WriterOutputStream(final Writer pWriter, final String pCharset) {
|
||||
mWriter = pWriter;
|
||||
mDecoder = getDecoder(pCharset);
|
||||
writer = pWriter;
|
||||
decoder = getDecoder(pCharset);
|
||||
}
|
||||
|
||||
public WriterOutputStream(final Writer pWriter) {
|
||||
@@ -94,14 +95,14 @@ public class WriterOutputStream extends OutputStream {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
flush();
|
||||
mWriter.close();
|
||||
mWriter = null;
|
||||
writer.close();
|
||||
writer = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
flushBuffer();
|
||||
mWriter.flush();
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,22 +116,22 @@ public class WriterOutputStream extends OutputStream {
|
||||
@Override
|
||||
public final void write(byte[] pBytes, int pOffset, int pLength) throws IOException {
|
||||
flushBuffer();
|
||||
mDecoder.decodeTo(mWriter, pBytes, pOffset, pLength);
|
||||
decoder.decodeTo(writer, pBytes, pOffset, pLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void write(int pByte) {
|
||||
// TODO: Is it possible to know if this is a good place in the stream to
|
||||
// flush? It might be in the middle of a multi-byte encoded character..
|
||||
mBufferStream.write(pByte);
|
||||
bufferStream.write(pByte);
|
||||
}
|
||||
|
||||
private void flushBuffer() throws IOException {
|
||||
if (!mIsFlushing && mBufferStream.size() > 0) {
|
||||
mIsFlushing = true;
|
||||
mBufferStream.writeTo(this); // NOTE: Avoids cloning buffer array
|
||||
mBufferStream.reset();
|
||||
mIsFlushing = false;
|
||||
if (!isFlushing && bufferStream.size() > 0) {
|
||||
isFlushing = true;
|
||||
bufferStream.writeTo(this); // NOTE: Avoids cloning buffer array
|
||||
bufferStream.reset();
|
||||
isFlushing = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +139,7 @@ public class WriterOutputStream extends OutputStream {
|
||||
public static void main(String[] pArgs) throws IOException {
|
||||
int iterations = 1000000;
|
||||
|
||||
byte[] bytes = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> klashf lkash ljah lhaaklhghdfgu ksd".getBytes("UTF-8");
|
||||
byte[] bytes = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> klashf lkash ljah lhaaklhghdfgu ksd".getBytes("UTF-8");
|
||||
|
||||
Decoder d;
|
||||
long start;
|
||||
|
@@ -41,12 +41,12 @@ import java.io.InputStream;
|
||||
*/
|
||||
// TODO: Move to other package or make public
|
||||
abstract class AbstractRLEDecoder implements Decoder {
|
||||
protected final byte[] mRow;
|
||||
protected final int mWidth;
|
||||
protected int mSrcX;
|
||||
protected int mSrcY;
|
||||
protected int mDstX;
|
||||
protected int mDstY;
|
||||
protected final byte[] row;
|
||||
protected final int width;
|
||||
protected int srcX;
|
||||
protected int srcY;
|
||||
protected int dstX;
|
||||
protected int dstY;
|
||||
|
||||
/**
|
||||
* Creates an RLEDecoder. As RLE encoded BMP's may contain x and y deltas,
|
||||
@@ -56,21 +56,21 @@ abstract class AbstractRLEDecoder implements Decoder {
|
||||
* @param pHeight heigth of the image
|
||||
*/
|
||||
AbstractRLEDecoder(int pWidth, int pHeight) {
|
||||
mWidth = pWidth;
|
||||
int bytesPerRow = mWidth;
|
||||
width = pWidth;
|
||||
int bytesPerRow = width;
|
||||
int mod = bytesPerRow % 4;
|
||||
|
||||
if (mod != 0) {
|
||||
bytesPerRow += 4 - mod;
|
||||
}
|
||||
|
||||
mRow = new byte[bytesPerRow];
|
||||
row = new byte[bytesPerRow];
|
||||
|
||||
mSrcX = 0;
|
||||
mSrcY = pHeight - 1;
|
||||
srcX = 0;
|
||||
srcY = pHeight - 1;
|
||||
|
||||
mDstX = mSrcX;
|
||||
mDstY = mSrcY;
|
||||
dstX = srcX;
|
||||
dstY = srcY;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,26 +95,26 @@ abstract class AbstractRLEDecoder implements Decoder {
|
||||
public final int decode(InputStream pStream, byte[] pBuffer) throws IOException {
|
||||
int decoded = 0;
|
||||
|
||||
while (decoded < pBuffer.length && mDstY >= 0) {
|
||||
while (decoded < pBuffer.length && dstY >= 0) {
|
||||
// NOTE: Decode only full rows, don't decode if y delta
|
||||
if (mDstX == 0 && mSrcY == mDstY) {
|
||||
if (dstX == 0 && srcY == dstY) {
|
||||
decodeRow(pStream);
|
||||
}
|
||||
|
||||
int length = Math.min(mRow.length - mDstX, pBuffer.length - decoded);
|
||||
System.arraycopy(mRow, mDstX, pBuffer, decoded, length);
|
||||
mDstX += length;
|
||||
int length = Math.min(row.length - dstX, pBuffer.length - decoded);
|
||||
System.arraycopy(row, dstX, pBuffer, decoded, length);
|
||||
dstX += length;
|
||||
decoded += length;
|
||||
|
||||
if (mDstX == mRow.length) {
|
||||
mDstX = 0;
|
||||
mDstY--;
|
||||
if (dstX == row.length) {
|
||||
dstX = 0;
|
||||
dstY--;
|
||||
|
||||
// NOTE: If src Y is < dst Y, we have a delta, and have to fill the
|
||||
// gap with zero-bytes
|
||||
if (mDstY > mSrcY) {
|
||||
for (int i = 0; i < mRow.length; i++) {
|
||||
mRow[i] = 0x00;
|
||||
if (dstY > srcY) {
|
||||
for (int i = 0; i < row.length; i++) {
|
||||
row[i] = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -61,9 +61,9 @@ public final class Base64Decoder implements Decoder {
|
||||
|
||||
final static byte[] PEM_CONVERT_ARRAY;
|
||||
|
||||
private byte[] mDecodeBuffer = new byte[4];
|
||||
private ByteArrayOutputStream mWrapped;
|
||||
private Object mWrappedObject;
|
||||
private byte[] decodeBuffer = new byte[4];
|
||||
private ByteArrayOutputStream wrapped;
|
||||
private Object wrappedObject;
|
||||
|
||||
static {
|
||||
PEM_CONVERT_ARRAY = new byte[256];
|
||||
@@ -116,8 +116,8 @@ public final class Base64Decoder implements Decoder {
|
||||
}
|
||||
} while (read == 10 || read == 13);
|
||||
|
||||
mDecodeBuffer[0] = (byte) read;
|
||||
read = readFully(pInput, mDecodeBuffer, 1, pLength - 1);
|
||||
decodeBuffer[0] = (byte) read;
|
||||
read = readFully(pInput, decodeBuffer, 1, pLength - 1);
|
||||
|
||||
if (read == -1) {
|
||||
return false;
|
||||
@@ -125,24 +125,24 @@ public final class Base64Decoder implements Decoder {
|
||||
|
||||
int length = pLength;
|
||||
|
||||
if (length > 3 && mDecodeBuffer[3] == 61) {
|
||||
if (length > 3 && decodeBuffer[3] == 61) {
|
||||
length = 3;
|
||||
}
|
||||
|
||||
if (length > 2 && mDecodeBuffer[2] == 61) {
|
||||
if (length > 2 && decodeBuffer[2] == 61) {
|
||||
length = 2;
|
||||
}
|
||||
|
||||
switch (length) {
|
||||
case 4:
|
||||
byte3 = PEM_CONVERT_ARRAY[mDecodeBuffer[3] & 255];
|
||||
byte3 = PEM_CONVERT_ARRAY[decodeBuffer[3] & 255];
|
||||
// fall through
|
||||
case 3:
|
||||
byte2 = PEM_CONVERT_ARRAY[mDecodeBuffer[2] & 255];
|
||||
byte2 = PEM_CONVERT_ARRAY[decodeBuffer[2] & 255];
|
||||
// fall through
|
||||
case 2:
|
||||
byte1 = PEM_CONVERT_ARRAY[mDecodeBuffer[1] & 255];
|
||||
byte0 = PEM_CONVERT_ARRAY[mDecodeBuffer[0] & 255];
|
||||
byte1 = PEM_CONVERT_ARRAY[decodeBuffer[1] & 255];
|
||||
byte0 = PEM_CONVERT_ARRAY[decodeBuffer[0] & 255];
|
||||
// fall through
|
||||
default:
|
||||
switch (length) {
|
||||
@@ -185,15 +185,15 @@ public final class Base64Decoder implements Decoder {
|
||||
}
|
||||
|
||||
public int decode(final InputStream pStream, final byte[] pBuffer) throws IOException {
|
||||
if (mWrappedObject != pBuffer) {
|
||||
if (wrappedObject != pBuffer) {
|
||||
// NOTE: Array not cloned in FastByteArrayOutputStream
|
||||
mWrapped = new FastByteArrayOutputStream(pBuffer);
|
||||
mWrappedObject = pBuffer;
|
||||
wrapped = new FastByteArrayOutputStream(pBuffer);
|
||||
wrappedObject = pBuffer;
|
||||
}
|
||||
|
||||
mWrapped.reset(); // NOTE: This only resets count to 0
|
||||
decodeBuffer(pStream, mWrapped, pBuffer.length);
|
||||
wrapped.reset(); // NOTE: This only resets count to 0
|
||||
decodeBuffer(pStream, wrapped, pBuffer.length);
|
||||
|
||||
return mWrapped.size();
|
||||
return wrapped.size();
|
||||
}
|
||||
}
|
||||
|
@@ -44,10 +44,10 @@ import java.io.FilterInputStream;
|
||||
*/
|
||||
public final class DecoderStream extends FilterInputStream {
|
||||
|
||||
protected int mBufferPos;
|
||||
protected int mBufferLimit;
|
||||
protected final byte[] mBuffer;
|
||||
protected final Decoder mDecoder;
|
||||
protected int bufferPos;
|
||||
protected int bufferLimit;
|
||||
protected final byte[] buffer;
|
||||
protected final Decoder decoder;
|
||||
|
||||
/**
|
||||
* Creates a new decoder stream and chains it to the
|
||||
@@ -76,26 +76,26 @@ public final class DecoderStream extends FilterInputStream {
|
||||
*/
|
||||
public DecoderStream(final InputStream pStream, final Decoder pDecoder, final int pBufferSize) {
|
||||
super(pStream);
|
||||
mDecoder = pDecoder;
|
||||
mBuffer = new byte[pBufferSize];
|
||||
mBufferPos = 0;
|
||||
mBufferLimit = 0;
|
||||
decoder = pDecoder;
|
||||
buffer = new byte[pBufferSize];
|
||||
bufferPos = 0;
|
||||
bufferLimit = 0;
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
return mBufferLimit - mBufferPos + super.available();
|
||||
return bufferLimit - bufferPos + super.available();
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (mBufferPos == mBufferLimit) {
|
||||
mBufferLimit = fill();
|
||||
if (bufferPos == bufferLimit) {
|
||||
bufferLimit = fill();
|
||||
}
|
||||
|
||||
if (mBufferLimit < 0) {
|
||||
if (bufferLimit < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mBuffer[mBufferPos++] & 0xff;
|
||||
return buffer[bufferPos++] & 0xff;
|
||||
}
|
||||
|
||||
public int read(final byte pBytes[]) throws IOException {
|
||||
@@ -115,7 +115,7 @@ public final class DecoderStream extends FilterInputStream {
|
||||
}
|
||||
|
||||
// End of file?
|
||||
if ((mBufferLimit - mBufferPos) < 0) {
|
||||
if ((bufferLimit - bufferPos) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -124,21 +124,21 @@ public final class DecoderStream extends FilterInputStream {
|
||||
int off = pOffset;
|
||||
|
||||
while (pLength > count) {
|
||||
int avail = mBufferLimit - mBufferPos;
|
||||
int avail = bufferLimit - bufferPos;
|
||||
|
||||
if (avail <= 0) {
|
||||
mBufferLimit = fill();
|
||||
bufferLimit = fill();
|
||||
|
||||
if (mBufferLimit < 0) {
|
||||
if (bufferLimit < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy as many bytes as possible
|
||||
int dstLen = Math.min(pLength - count, avail);
|
||||
System.arraycopy(mBuffer, mBufferPos, pBytes, off, dstLen);
|
||||
System.arraycopy(buffer, bufferPos, pBytes, off, dstLen);
|
||||
|
||||
mBufferPos += dstLen;
|
||||
bufferPos += dstLen;
|
||||
|
||||
// Update offset (rest)
|
||||
off += dstLen;
|
||||
@@ -152,7 +152,7 @@ public final class DecoderStream extends FilterInputStream {
|
||||
|
||||
public long skip(final long pLength) throws IOException {
|
||||
// End of file?
|
||||
if (mBufferLimit - mBufferPos < 0) {
|
||||
if (bufferLimit - bufferPos < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -160,12 +160,12 @@ public final class DecoderStream extends FilterInputStream {
|
||||
long total = 0;
|
||||
|
||||
while (total < pLength) {
|
||||
int avail = mBufferLimit - mBufferPos;
|
||||
int avail = bufferLimit - bufferPos;
|
||||
|
||||
if (avail == 0) {
|
||||
mBufferLimit = fill();
|
||||
bufferLimit = fill();
|
||||
|
||||
if (mBufferLimit < 0) {
|
||||
if (bufferLimit < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -174,7 +174,7 @@ public final class DecoderStream extends FilterInputStream {
|
||||
// an int, so the cast is safe
|
||||
int skipped = (int) Math.min(pLength - total, avail);
|
||||
|
||||
mBufferPos += skipped; // Just skip these bytes
|
||||
bufferPos += skipped; // Just skip these bytes
|
||||
total += skipped;
|
||||
}
|
||||
|
||||
@@ -190,19 +190,19 @@ public final class DecoderStream extends FilterInputStream {
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
protected int fill() throws IOException {
|
||||
int read = mDecoder.decode(in, mBuffer);
|
||||
int read = decoder.decode(in, buffer);
|
||||
|
||||
// TODO: Enforce this in test case, leave here to aid debugging
|
||||
if (read > mBuffer.length) {
|
||||
if (read > buffer.length) {
|
||||
throw new AssertionError(
|
||||
String.format(
|
||||
"Decode beyond buffer (%d): %d (using %s decoder)",
|
||||
mBuffer.length, read, mDecoder.getClass().getName()
|
||||
buffer.length, read, decoder.getClass().getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
mBufferPos = 0;
|
||||
bufferPos = 0;
|
||||
|
||||
if (read == 0) {
|
||||
return -1;
|
||||
|
@@ -57,8 +57,7 @@ public interface Encoder {
|
||||
*
|
||||
* @throws java.io.IOException if an I/O error occurs
|
||||
*/
|
||||
void encode(OutputStream pStream, byte[] pBuffer, int pOffset, int pLength)
|
||||
throws IOException;
|
||||
void encode(OutputStream pStream, byte[] pBuffer, int pOffset, int pLength) throws IOException;
|
||||
|
||||
//TODO: int requiredBufferSize(): -1 == any, otherwise, use this buffer size
|
||||
// void flush()?
|
||||
|
@@ -44,11 +44,11 @@ import java.io.IOException;
|
||||
*/
|
||||
public final class EncoderStream extends FilterOutputStream {
|
||||
|
||||
protected final Encoder mEncoder;
|
||||
private final boolean mFlushOnWrite;
|
||||
protected final Encoder encoder;
|
||||
private final boolean flushOnWrite;
|
||||
|
||||
protected int mBufferPos;
|
||||
protected final byte[] mBuffer;
|
||||
protected int bufferPos;
|
||||
protected final byte[] buffer;
|
||||
|
||||
/**
|
||||
* Creates an output stream filter built on top of the specified
|
||||
@@ -73,11 +73,11 @@ public final class EncoderStream extends FilterOutputStream {
|
||||
public EncoderStream(final OutputStream pStream, final Encoder pEncoder, final boolean pFlushOnWrite) {
|
||||
super(pStream);
|
||||
|
||||
mEncoder = pEncoder;
|
||||
mFlushOnWrite = pFlushOnWrite;
|
||||
encoder = pEncoder;
|
||||
flushOnWrite = pFlushOnWrite;
|
||||
|
||||
mBuffer = new byte[1024];
|
||||
mBufferPos = 0;
|
||||
buffer = new byte[1024];
|
||||
bufferPos = 0;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
@@ -91,12 +91,12 @@ public final class EncoderStream extends FilterOutputStream {
|
||||
}
|
||||
|
||||
private void encodeBuffer() throws IOException {
|
||||
if (mBufferPos != 0) {
|
||||
if (bufferPos != 0) {
|
||||
// Make sure all remaining data in buffer is written to the stream
|
||||
mEncoder.encode(out, mBuffer, 0, mBufferPos);
|
||||
encoder.encode(out, buffer, 0, bufferPos);
|
||||
|
||||
// Reset buffer
|
||||
mBufferPos = 0;
|
||||
bufferPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,27 +109,27 @@ public final class EncoderStream extends FilterOutputStream {
|
||||
// that the encoder can't buffer. In that case, the encoder should probably
|
||||
// tell the EncoderStream how large buffer it prefers...
|
||||
public void write(final byte[] pBytes, final int pOffset, final int pLength) throws IOException {
|
||||
if (!mFlushOnWrite && mBufferPos + pLength < mBuffer.length) {
|
||||
if (!flushOnWrite && bufferPos + pLength < buffer.length) {
|
||||
// Buffer data
|
||||
System.arraycopy(pBytes, pOffset, mBuffer, mBufferPos, pLength);
|
||||
mBufferPos += pLength;
|
||||
System.arraycopy(pBytes, pOffset, buffer, bufferPos, pLength);
|
||||
bufferPos += pLength;
|
||||
}
|
||||
else {
|
||||
// Encode data already in the buffer
|
||||
if (mBufferPos != 0) {
|
||||
if (bufferPos != 0) {
|
||||
encodeBuffer();
|
||||
}
|
||||
|
||||
// Encode rest without buffering
|
||||
mEncoder.encode(out, pBytes, pOffset, pLength);
|
||||
encoder.encode(out, pBytes, pOffset, pLength);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(final int pByte) throws IOException {
|
||||
if (mBufferPos >= mBuffer.length - 1) {
|
||||
encodeBuffer(); // Resets mBufferPos to 0
|
||||
if (bufferPos >= buffer.length - 1) {
|
||||
encodeBuffer(); // Resets bufferPos to 0
|
||||
}
|
||||
|
||||
mBuffer[mBufferPos++] = (byte) pByte;
|
||||
buffer[bufferPos++] = (byte) pByte;
|
||||
}
|
||||
}
|
||||
|
@@ -46,11 +46,11 @@ import java.io.EOFException;
|
||||
*/
|
||||
public final class PackBits16Decoder implements Decoder {
|
||||
// TODO: Refactor this into an option for the PackBitsDecoder?
|
||||
private final boolean mDisableNoop;
|
||||
private final boolean disableNoop;
|
||||
|
||||
private int mLeftOfRun;
|
||||
private boolean mSplitRun;
|
||||
private boolean mEOF;
|
||||
private int leftOfRun;
|
||||
private boolean splitRun;
|
||||
private boolean reachedEOF;
|
||||
|
||||
/**
|
||||
* Creates a {@code PackBitsDecoder}.
|
||||
@@ -71,7 +71,7 @@ public final class PackBits16Decoder implements Decoder {
|
||||
* @param pDisableNoop {@code true} if {@code -128} should be treated as a compressed run, and not a no-op
|
||||
*/
|
||||
public PackBits16Decoder(final boolean pDisableNoop) {
|
||||
mDisableNoop = pDisableNoop;
|
||||
disableNoop = pDisableNoop;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ public final class PackBits16Decoder implements Decoder {
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public int decode(final InputStream pStream, final byte[] pBuffer) throws IOException {
|
||||
if (mEOF) {
|
||||
if (reachedEOF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -95,16 +95,16 @@ public final class PackBits16Decoder implements Decoder {
|
||||
while (read < max) {
|
||||
int n;
|
||||
|
||||
if (mSplitRun) {
|
||||
if (splitRun) {
|
||||
// Continue run
|
||||
n = mLeftOfRun;
|
||||
mSplitRun = false;
|
||||
n = leftOfRun;
|
||||
splitRun = false;
|
||||
}
|
||||
else {
|
||||
// Start new run
|
||||
int b = pStream.read();
|
||||
if (b < 0) {
|
||||
mEOF = true;
|
||||
reachedEOF = true;
|
||||
break;
|
||||
}
|
||||
n = (byte) b;
|
||||
@@ -112,13 +112,13 @@ public final class PackBits16Decoder implements Decoder {
|
||||
|
||||
// Split run at or before max
|
||||
if (n >= 0 && 2 * (n + 1) + read > max) {
|
||||
mLeftOfRun = n;
|
||||
mSplitRun = true;
|
||||
leftOfRun = n;
|
||||
splitRun = true;
|
||||
break;
|
||||
}
|
||||
else if (n < 0 && 2 * (-n + 1) + read > max) {
|
||||
mLeftOfRun = n;
|
||||
mSplitRun = true;
|
||||
leftOfRun = n;
|
||||
splitRun = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ public final class PackBits16Decoder implements Decoder {
|
||||
read += len;
|
||||
}
|
||||
// Allow -128 for compatibility, see above
|
||||
else if (mDisableNoop || n != -128) {
|
||||
else if (disableNoop || n != -128) {
|
||||
// Replicate the next short -n + 1 times
|
||||
byte value1 = readByte(pStream);
|
||||
byte value2 = readByte(pStream);
|
||||
|
@@ -63,11 +63,11 @@ import java.io.EOFException;
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/enc/PackBitsDecoder.java#1 $
|
||||
*/
|
||||
public final class PackBitsDecoder implements Decoder {
|
||||
private final boolean mDisableNoop;
|
||||
private final boolean disableNoop;
|
||||
|
||||
private int mLeftOfRun;
|
||||
private boolean mSplitRun;
|
||||
private boolean mEOF;
|
||||
private int leftOfRun;
|
||||
private boolean splitRun;
|
||||
private boolean reachedEOF;
|
||||
|
||||
/** Creates a {@code PackBitsDecoder}. */
|
||||
public PackBitsDecoder() {
|
||||
@@ -86,7 +86,7 @@ public final class PackBitsDecoder implements Decoder {
|
||||
* @param pDisableNoop {@code true} if {@code -128} should be treated as a compressed run, and not a no-op
|
||||
*/
|
||||
public PackBitsDecoder(final boolean pDisableNoop) {
|
||||
mDisableNoop = pDisableNoop;
|
||||
disableNoop = pDisableNoop;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,7 +100,7 @@ public final class PackBitsDecoder implements Decoder {
|
||||
* @throws IOException
|
||||
*/
|
||||
public int decode(final InputStream pStream, final byte[] pBuffer) throws IOException {
|
||||
if (mEOF) {
|
||||
if (reachedEOF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -111,16 +111,16 @@ public final class PackBitsDecoder implements Decoder {
|
||||
while (read < max) {
|
||||
int n;
|
||||
|
||||
if (mSplitRun) {
|
||||
if (splitRun) {
|
||||
// Continue run
|
||||
n = mLeftOfRun;
|
||||
mSplitRun = false;
|
||||
n = leftOfRun;
|
||||
splitRun = false;
|
||||
}
|
||||
else {
|
||||
// Start new run
|
||||
int b = pStream.read();
|
||||
if (b < 0) {
|
||||
mEOF = true;
|
||||
reachedEOF = true;
|
||||
break;
|
||||
}
|
||||
n = (byte) b;
|
||||
@@ -128,13 +128,13 @@ public final class PackBitsDecoder implements Decoder {
|
||||
|
||||
// Split run at or before max
|
||||
if (n >= 0 && n + 1 + read > max) {
|
||||
mLeftOfRun = n;
|
||||
mSplitRun = true;
|
||||
leftOfRun = n;
|
||||
splitRun = true;
|
||||
break;
|
||||
}
|
||||
else if (n < 0 && -n + 1 + read > max) {
|
||||
mLeftOfRun = n;
|
||||
mSplitRun = true;
|
||||
leftOfRun = n;
|
||||
splitRun = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ public final class PackBitsDecoder implements Decoder {
|
||||
read += n + 1;
|
||||
}
|
||||
// Allow -128 for compatibility, see above
|
||||
else if (mDisableNoop || n != -128) {
|
||||
else if (disableNoop || n != -128) {
|
||||
// Replicate the next byte -n + 1 times
|
||||
byte value = readByte(pStream);
|
||||
|
||||
|
@@ -63,7 +63,7 @@ import java.io.IOException;
|
||||
*/
|
||||
public final class PackBitsEncoder implements Encoder {
|
||||
|
||||
final private byte[] mBuffer = new byte[128];
|
||||
final private byte[] buffer = new byte[128];
|
||||
|
||||
/**
|
||||
* Creates a {@code PackBitsEncoder}.
|
||||
@@ -101,17 +101,17 @@ public final class PackBitsEncoder implements Encoder {
|
||||
run = 0;
|
||||
while ((run < 128 && ((offset < max && pBuffer[offset] != pBuffer[offset + 1])
|
||||
|| (offset < maxMinus1 && pBuffer[offset] != pBuffer[offset + 2])))) {
|
||||
mBuffer[run++] = pBuffer[offset++];
|
||||
buffer[run++] = pBuffer[offset++];
|
||||
}
|
||||
|
||||
// If last byte, include it in literal run, if space
|
||||
if (offset == max && run > 0 && run < 128) {
|
||||
mBuffer[run++] = pBuffer[offset++];
|
||||
buffer[run++] = pBuffer[offset++];
|
||||
}
|
||||
|
||||
if (run > 0) {
|
||||
pStream.write(run - 1);
|
||||
pStream.write(mBuffer, 0, run);
|
||||
pStream.write(buffer, 0, run);
|
||||
}
|
||||
|
||||
// If last byte, and not space, start new literal run
|
||||
|
@@ -49,7 +49,7 @@ final class RLE4Decoder extends AbstractRLEDecoder {
|
||||
int deltaX = 0;
|
||||
int deltaY = 0;
|
||||
|
||||
while (mSrcY >= 0) {
|
||||
while (srcY >= 0) {
|
||||
int byte1 = pInput.read();
|
||||
int byte2 = checkEOF(pInput.read());
|
||||
|
||||
@@ -58,20 +58,20 @@ final class RLE4Decoder extends AbstractRLEDecoder {
|
||||
case 0x00:
|
||||
// End of line
|
||||
// NOTE: Some BMPs have double EOLs..
|
||||
if (mSrcX != 0) {
|
||||
mSrcX = mRow.length;
|
||||
if (srcX != 0) {
|
||||
srcX = row.length;
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
// End of bitmap
|
||||
mSrcX = mRow.length;
|
||||
mSrcY = 0;
|
||||
srcX = row.length;
|
||||
srcY = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
// Delta
|
||||
deltaX = mSrcX + pInput.read();
|
||||
deltaY = mSrcY - checkEOF(pInput.read());
|
||||
mSrcX = mRow.length;
|
||||
deltaX = srcX + pInput.read();
|
||||
deltaY = srcY - checkEOF(pInput.read());
|
||||
srcX = row.length;
|
||||
break;
|
||||
default:
|
||||
// Absolute mode
|
||||
@@ -82,13 +82,13 @@ final class RLE4Decoder extends AbstractRLEDecoder {
|
||||
boolean paddingByte = (((byte2 + 1) / 2) % 2) != 0;
|
||||
while (byte2 > 1) {
|
||||
int packed = checkEOF(pInput.read());
|
||||
mRow[mSrcX++] = (byte) packed;
|
||||
row[srcX++] = (byte) packed;
|
||||
byte2 -= 2;
|
||||
}
|
||||
if (byte2 == 1) {
|
||||
// TODO: Half byte alignment? Seems to be ok...
|
||||
int packed = checkEOF(pInput.read());
|
||||
mRow[mSrcX++] = (byte) (packed & 0xf0);
|
||||
row[srcX++] = (byte) (packed & 0xf0);
|
||||
}
|
||||
if (paddingByte) {
|
||||
checkEOF(pInput.read());
|
||||
@@ -100,24 +100,24 @@ final class RLE4Decoder extends AbstractRLEDecoder {
|
||||
// Encoded mode
|
||||
// Replicate the two samples in byte2 as many times as byte1 says
|
||||
while (byte1 > 1) {
|
||||
mRow[mSrcX++] = (byte) byte2;
|
||||
row[srcX++] = (byte) byte2;
|
||||
byte1 -= 2;
|
||||
}
|
||||
|
||||
if (byte1 == 1) {
|
||||
// TODO: Half byte alignment? Seems to be ok...
|
||||
mRow[mSrcX++] = (byte) (byte2 & 0xf0);
|
||||
row[srcX++] = (byte) (byte2 & 0xf0);
|
||||
}
|
||||
}
|
||||
|
||||
// If we're done with a complete row, copy the data
|
||||
if (mSrcX == mRow.length) {
|
||||
if (srcX == row.length) {
|
||||
// Move to new position, either absolute (delta) or next line
|
||||
if (deltaX != 0 || deltaY != 0) {
|
||||
mSrcX = (deltaX + 1) / 2;
|
||||
srcX = (deltaX + 1) / 2;
|
||||
|
||||
if (deltaY > mSrcY) {
|
||||
mSrcY = deltaY;
|
||||
if (deltaY > srcY) {
|
||||
srcY = deltaY;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -125,8 +125,8 @@ final class RLE4Decoder extends AbstractRLEDecoder {
|
||||
deltaY = 0;
|
||||
}
|
||||
else {
|
||||
mSrcX = 0;
|
||||
mSrcY--;
|
||||
srcX = 0;
|
||||
srcY--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -49,7 +49,7 @@ final class RLE8Decoder extends AbstractRLEDecoder {
|
||||
int deltaX = 0;
|
||||
int deltaY = 0;
|
||||
|
||||
while (mSrcY >= 0) {
|
||||
while (srcY >= 0) {
|
||||
int byte1 = pInput.read();
|
||||
int byte2 = checkEOF(pInput.read());
|
||||
|
||||
@@ -58,27 +58,27 @@ final class RLE8Decoder extends AbstractRLEDecoder {
|
||||
case 0x00:
|
||||
// End of line
|
||||
// NOTE: Some BMPs have double EOLs..
|
||||
if (mSrcX != 0) {
|
||||
mSrcX = mRow.length;
|
||||
if (srcX != 0) {
|
||||
srcX = row.length;
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
// End of bitmap
|
||||
mSrcX = mRow.length;
|
||||
mSrcY = 0;
|
||||
srcX = row.length;
|
||||
srcY = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
// Delta
|
||||
deltaX = mSrcX + pInput.read();
|
||||
deltaY = mSrcY - checkEOF(pInput.read());
|
||||
mSrcX = mRow.length;
|
||||
deltaX = srcX + pInput.read();
|
||||
deltaY = srcY - checkEOF(pInput.read());
|
||||
srcX = row.length;
|
||||
break;
|
||||
default:
|
||||
// Absolute mode
|
||||
// Copy the next byte2 (3..255) bytes from file to output
|
||||
boolean paddingByte = (byte2 % 2) != 0;
|
||||
while (byte2-- > 0) {
|
||||
mRow[mSrcX++] = (byte) checkEOF(pInput.read());
|
||||
row[srcX++] = (byte) checkEOF(pInput.read());
|
||||
}
|
||||
if (paddingByte) {
|
||||
checkEOF(pInput.read());
|
||||
@@ -90,26 +90,26 @@ final class RLE8Decoder extends AbstractRLEDecoder {
|
||||
// Replicate byte2 as many times as byte1 says
|
||||
byte value = (byte) byte2;
|
||||
while (byte1-- > 0) {
|
||||
mRow[mSrcX++] = value;
|
||||
row[srcX++] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're done with a complete row, copy the data
|
||||
if (mSrcX == mRow.length) {
|
||||
if (srcX == row.length) {
|
||||
|
||||
// Move to new position, either absolute (delta) or next line
|
||||
if (deltaX != 0 || deltaY != 0) {
|
||||
mSrcX = deltaX;
|
||||
if (deltaY != mSrcY) {
|
||||
mSrcY = deltaY;
|
||||
srcX = deltaX;
|
||||
if (deltaY != srcY) {
|
||||
srcY = deltaY;
|
||||
break;
|
||||
}
|
||||
deltaX = 0;
|
||||
deltaY = 0;
|
||||
}
|
||||
else {
|
||||
mSrcX = 0;
|
||||
mSrcY--;
|
||||
srcX = 0;
|
||||
srcY--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -60,28 +60,28 @@ public final class CompoundDocument {
|
||||
};
|
||||
public static final int HEADER_SIZE = 512;
|
||||
|
||||
private final DataInput mInput;
|
||||
private final DataInput input;
|
||||
|
||||
private UUID mUID;
|
||||
private UUID uUID;
|
||||
|
||||
private int mSectorSize;
|
||||
private int mShortSectorSize;
|
||||
private int sectorSize;
|
||||
private int shortSectorSize;
|
||||
|
||||
private int mDirectorySId;
|
||||
private int directorySId;
|
||||
|
||||
private int mMinStreamSize;
|
||||
private int minStreamSize;
|
||||
|
||||
private int mShortSATSID;
|
||||
private int mShortSATSize;
|
||||
private int shortSATSId;
|
||||
private int shortSATSize;
|
||||
|
||||
// Master Sector Allocation Table
|
||||
private int[] mMasterSAT;
|
||||
private int[] mSAT;
|
||||
private int[] mShortSAT;
|
||||
private int[] masterSAT;
|
||||
private int[] SAT;
|
||||
private int[] shortSAT;
|
||||
|
||||
private Entry mRootEntry;
|
||||
private SIdChain mShortStreamSIdChain;
|
||||
private SIdChain mDirectorySIdChain;
|
||||
private Entry rootEntry;
|
||||
private SIdChain shortStreamSIdChain;
|
||||
private SIdChain directorySIdChain;
|
||||
|
||||
private static final int END_OF_CHAIN_SID = -2;
|
||||
private static final int FREE_SID = -1;
|
||||
@@ -97,7 +97,7 @@ public final class CompoundDocument {
|
||||
* @throws IOException if an I/O exception occurs while reading the header
|
||||
*/
|
||||
public CompoundDocument(final File pFile) throws IOException {
|
||||
mInput = new LittleEndianRandomAccessFile(FileUtil.resolve(pFile), "r");
|
||||
input = new LittleEndianRandomAccessFile(FileUtil.resolve(pFile), "r");
|
||||
|
||||
// TODO: Might be better to read header on first read operation?!
|
||||
// OTOH: It's also good to be fail-fast, so at least we should make
|
||||
@@ -118,7 +118,7 @@ public final class CompoundDocument {
|
||||
|
||||
// For testing only, consider exposing later
|
||||
CompoundDocument(final SeekableInputStream pInput) throws IOException {
|
||||
mInput = new SeekableLittleEndianDataInputStream(pInput);
|
||||
input = new SeekableLittleEndianDataInputStream(pInput);
|
||||
|
||||
// TODO: Might be better to read header on first read operation?!
|
||||
// OTOH: It's also good to be fail-fast, so at least we should make
|
||||
@@ -134,7 +134,7 @@ public final class CompoundDocument {
|
||||
* @throws IOException if an I/O exception occurs while reading the header
|
||||
*/
|
||||
public CompoundDocument(final ImageInputStream pInput) throws IOException {
|
||||
mInput = pInput;
|
||||
input = pInput;
|
||||
|
||||
// TODO: Might be better to read header on first read operation?!
|
||||
// OTOH: It's also good to be fail-fast, so at least we should make
|
||||
@@ -210,74 +210,76 @@ public final class CompoundDocument {
|
||||
}
|
||||
|
||||
private void readHeader() throws IOException {
|
||||
if (mMasterSAT != null) {
|
||||
if (masterSAT != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canRead(mInput, false)) {
|
||||
if (!canRead(input, false)) {
|
||||
throw new CorruptDocumentException("Not an OLE 2 Compound Document");
|
||||
}
|
||||
|
||||
// UID (seems to be all 0s)
|
||||
mUID = new UUID(mInput.readLong(), mInput.readLong());
|
||||
uUID = new UUID(input.readLong(), input.readLong());
|
||||
|
||||
/*int version = */mInput.readUnsignedShort();
|
||||
/*int version = */
|
||||
input.readUnsignedShort();
|
||||
//System.out.println("version: " + version);
|
||||
/*int revision = */mInput.readUnsignedShort();
|
||||
/*int revision = */
|
||||
input.readUnsignedShort();
|
||||
//System.out.println("revision: " + revision);
|
||||
|
||||
int byteOrder = mInput.readUnsignedShort();
|
||||
int byteOrder = input.readUnsignedShort();
|
||||
if (byteOrder != 0xfffe) {
|
||||
// Reversed, as I'm allready reading little-endian
|
||||
throw new CorruptDocumentException("Cannot read big endian OLE 2 Compound Documents");
|
||||
}
|
||||
|
||||
mSectorSize = 1 << mInput.readUnsignedShort();
|
||||
//System.out.println("sectorSize: " + mSectorSize + " bytes");
|
||||
mShortSectorSize = 1 << mInput.readUnsignedShort();
|
||||
//System.out.println("shortSectorSize: " + mShortSectorSize + " bytes");
|
||||
sectorSize = 1 << input.readUnsignedShort();
|
||||
//System.out.println("sectorSize: " + sectorSize + " bytes");
|
||||
shortSectorSize = 1 << input.readUnsignedShort();
|
||||
//System.out.println("shortSectorSize: " + shortSectorSize + " bytes");
|
||||
|
||||
// Reserved
|
||||
if (mInput.skipBytes(10) != 10) {
|
||||
if (input.skipBytes(10) != 10) {
|
||||
throw new CorruptDocumentException();
|
||||
}
|
||||
|
||||
int SATSize = mInput.readInt();
|
||||
int SATSize = input.readInt();
|
||||
//System.out.println("normalSATSize: " + mSATSize);
|
||||
|
||||
mDirectorySId = mInput.readInt();
|
||||
//System.out.println("directorySId: " + mDirectorySId);
|
||||
directorySId = input.readInt();
|
||||
//System.out.println("directorySId: " + directorySId);
|
||||
|
||||
// Reserved
|
||||
if (mInput.skipBytes(4) != 4) {
|
||||
if (input.skipBytes(4) != 4) {
|
||||
throw new CorruptDocumentException();
|
||||
}
|
||||
|
||||
mMinStreamSize = mInput.readInt();
|
||||
//System.out.println("minStreamSize: " + mMinStreamSize + " bytes");
|
||||
minStreamSize = input.readInt();
|
||||
//System.out.println("minStreamSize: " + minStreamSize + " bytes");
|
||||
|
||||
mShortSATSID = mInput.readInt();
|
||||
//System.out.println("shortSATSID: " + mShortSATSID);
|
||||
mShortSATSize = mInput.readInt();
|
||||
//System.out.println("shortSATSize: " + mShortSATSize);
|
||||
int masterSATSId = mInput.readInt();
|
||||
shortSATSId = input.readInt();
|
||||
//System.out.println("shortSATSId: " + shortSATSId);
|
||||
shortSATSize = input.readInt();
|
||||
//System.out.println("shortSATSize: " + shortSATSize);
|
||||
int masterSATSId = input.readInt();
|
||||
//System.out.println("masterSATSId: " + mMasterSATSID);
|
||||
int masterSATSize = mInput.readInt();
|
||||
int masterSATSize = input.readInt();
|
||||
//System.out.println("masterSATSize: " + mMasterSATSize);
|
||||
|
||||
// Read masterSAT: 436 bytes, containing up to 109 SIDs
|
||||
//System.out.println("MSAT:");
|
||||
mMasterSAT = new int[SATSize];
|
||||
masterSAT = new int[SATSize];
|
||||
final int headerSIds = Math.min(SATSize, 109);
|
||||
for (int i = 0; i < headerSIds; i++) {
|
||||
mMasterSAT[i] = mInput.readInt();
|
||||
//System.out.println("\tSID(" + i + "): " + mMasterSAT[i]);
|
||||
masterSAT[i] = input.readInt();
|
||||
//System.out.println("\tSID(" + i + "): " + masterSAT[i]);
|
||||
}
|
||||
|
||||
if (masterSATSId == END_OF_CHAIN_SID) {
|
||||
// End of chain
|
||||
int freeSIdLength = 436 - (SATSize * 4);
|
||||
if (mInput.skipBytes(freeSIdLength) != freeSIdLength) {
|
||||
if (input.skipBytes(freeSIdLength) != freeSIdLength) {
|
||||
throw new CorruptDocumentException();
|
||||
}
|
||||
}
|
||||
@@ -288,17 +290,17 @@ public final class CompoundDocument {
|
||||
int index = headerSIds;
|
||||
for (int i = 0; i < masterSATSize; i++) {
|
||||
for (int j = 0; j < 127; j++) {
|
||||
int sid = mInput.readInt();
|
||||
int sid = input.readInt();
|
||||
switch (sid) {
|
||||
case FREE_SID:// Free
|
||||
break;
|
||||
default:
|
||||
mMasterSAT[index++] = sid;
|
||||
masterSAT[index++] = sid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int next = mInput.readInt();
|
||||
int next = input.readInt();
|
||||
if (next == END_OF_CHAIN_SID) {// End of chain
|
||||
break;
|
||||
}
|
||||
@@ -309,37 +311,37 @@ public final class CompoundDocument {
|
||||
}
|
||||
|
||||
private void readSAT() throws IOException {
|
||||
if (mSAT != null) {
|
||||
if (SAT != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int intsPerSector = mSectorSize / 4;
|
||||
final int intsPerSector = sectorSize / 4;
|
||||
|
||||
// Read the Sector Allocation Table
|
||||
mSAT = new int[mMasterSAT.length * intsPerSector];
|
||||
SAT = new int[masterSAT.length * intsPerSector];
|
||||
|
||||
for (int i = 0; i < mMasterSAT.length; i++) {
|
||||
seekToSId(mMasterSAT[i], FREE_SID);
|
||||
for (int i = 0; i < masterSAT.length; i++) {
|
||||
seekToSId(masterSAT[i], FREE_SID);
|
||||
|
||||
for (int j = 0; j < intsPerSector; j++) {
|
||||
int nextSID = mInput.readInt();
|
||||
int nextSID = input.readInt();
|
||||
int index = (j + (i * intsPerSector));
|
||||
|
||||
mSAT[index] = nextSID;
|
||||
SAT[index] = nextSID;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the short-stream Sector Allocation Table
|
||||
SIdChain chain = getSIdChain(mShortSATSID, FREE_SID);
|
||||
mShortSAT = new int[mShortSATSize * intsPerSector];
|
||||
for (int i = 0; i < mShortSATSize; i++) {
|
||||
SIdChain chain = getSIdChain(shortSATSId, FREE_SID);
|
||||
shortSAT = new int[shortSATSize * intsPerSector];
|
||||
for (int i = 0; i < shortSATSize; i++) {
|
||||
seekToSId(chain.get(i), FREE_SID);
|
||||
|
||||
for (int j = 0; j < intsPerSector; j++) {
|
||||
int nextSID = mInput.readInt();
|
||||
int nextSID = input.readInt();
|
||||
int index = (j + (i * intsPerSector));
|
||||
|
||||
mShortSAT[index] = nextSID;
|
||||
shortSAT[index] = nextSID;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -355,7 +357,7 @@ public final class CompoundDocument {
|
||||
private SIdChain getSIdChain(final int pSId, final long pStreamSize) throws IOException {
|
||||
SIdChain chain = new SIdChain();
|
||||
|
||||
int[] sat = isShortStream(pStreamSize) ? mShortSAT : mSAT;
|
||||
int[] sat = isShortStream(pStreamSize) ? shortSAT : SAT;
|
||||
|
||||
int sid = pSId;
|
||||
while (sid != END_OF_CHAIN_SID && sid != FREE_SID) {
|
||||
@@ -367,7 +369,7 @@ public final class CompoundDocument {
|
||||
}
|
||||
|
||||
private boolean isShortStream(final long pStreamSize) {
|
||||
return pStreamSize != FREE_SID && pStreamSize < mMinStreamSize;
|
||||
return pStreamSize != FREE_SID && pStreamSize < minStreamSize;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,56 +385,56 @@ public final class CompoundDocument {
|
||||
if (isShortStream(pStreamSize)) {
|
||||
// The short-stream is not continouos...
|
||||
Entry root = getRootEntry();
|
||||
if (mShortStreamSIdChain == null) {
|
||||
mShortStreamSIdChain = getSIdChain(root.startSId, root.streamSize);
|
||||
if (shortStreamSIdChain == null) {
|
||||
shortStreamSIdChain = getSIdChain(root.startSId, root.streamSize);
|
||||
}
|
||||
|
||||
int shortPerStd = mSectorSize / mShortSectorSize;
|
||||
int shortPerStd = sectorSize / shortSectorSize;
|
||||
int offset = pSId / shortPerStd;
|
||||
int shortOffset = pSId - (offset * shortPerStd);
|
||||
|
||||
pos = HEADER_SIZE
|
||||
+ (mShortStreamSIdChain.get(offset) * (long) mSectorSize)
|
||||
+ (shortOffset * (long) mShortSectorSize);
|
||||
+ (shortStreamSIdChain.get(offset) * (long) sectorSize)
|
||||
+ (shortOffset * (long) shortSectorSize);
|
||||
}
|
||||
else {
|
||||
pos = HEADER_SIZE + pSId * (long) mSectorSize;
|
||||
pos = HEADER_SIZE + pSId * (long) sectorSize;
|
||||
}
|
||||
|
||||
if (mInput instanceof LittleEndianRandomAccessFile) {
|
||||
((LittleEndianRandomAccessFile) mInput).seek(pos);
|
||||
if (input instanceof LittleEndianRandomAccessFile) {
|
||||
((LittleEndianRandomAccessFile) input).seek(pos);
|
||||
}
|
||||
else if (mInput instanceof ImageInputStream) {
|
||||
((ImageInputStream) mInput).seek(pos);
|
||||
else if (input instanceof ImageInputStream) {
|
||||
((ImageInputStream) input).seek(pos);
|
||||
}
|
||||
else {
|
||||
((SeekableLittleEndianDataInputStream) mInput).seek(pos);
|
||||
((SeekableLittleEndianDataInputStream) input).seek(pos);
|
||||
}
|
||||
}
|
||||
|
||||
private void seekToDId(final int pDId) throws IOException {
|
||||
if (mDirectorySIdChain == null) {
|
||||
mDirectorySIdChain = getSIdChain(mDirectorySId, FREE_SID);
|
||||
if (directorySIdChain == null) {
|
||||
directorySIdChain = getSIdChain(directorySId, FREE_SID);
|
||||
}
|
||||
|
||||
int dIdsPerSId = mSectorSize / Entry.LENGTH;
|
||||
int dIdsPerSId = sectorSize / Entry.LENGTH;
|
||||
|
||||
int sIdOffset = pDId / dIdsPerSId;
|
||||
int dIdOffset = pDId - (sIdOffset * dIdsPerSId);
|
||||
|
||||
int sId = mDirectorySIdChain.get(sIdOffset);
|
||||
int sId = directorySIdChain.get(sIdOffset);
|
||||
|
||||
seekToSId(sId, FREE_SID);
|
||||
if (mInput instanceof LittleEndianRandomAccessFile) {
|
||||
LittleEndianRandomAccessFile input = (LittleEndianRandomAccessFile) mInput;
|
||||
if (input instanceof LittleEndianRandomAccessFile) {
|
||||
LittleEndianRandomAccessFile input = (LittleEndianRandomAccessFile) this.input;
|
||||
input.seek(input.getFilePointer() + dIdOffset * Entry.LENGTH);
|
||||
}
|
||||
else if (mInput instanceof ImageInputStream) {
|
||||
ImageInputStream input = (ImageInputStream) mInput;
|
||||
else if (input instanceof ImageInputStream) {
|
||||
ImageInputStream input = (ImageInputStream) this.input;
|
||||
input.seek(input.getStreamPosition() + dIdOffset * Entry.LENGTH);
|
||||
}
|
||||
else {
|
||||
SeekableLittleEndianDataInputStream input = (SeekableLittleEndianDataInputStream) mInput;
|
||||
SeekableLittleEndianDataInputStream input = (SeekableLittleEndianDataInputStream) this.input;
|
||||
input.seek(input.getStreamPosition() + dIdOffset * Entry.LENGTH);
|
||||
}
|
||||
}
|
||||
@@ -442,7 +444,7 @@ public final class CompoundDocument {
|
||||
|
||||
// TODO: Detach? Means, we have to copy to a byte buffer, or keep track of
|
||||
// positions, and seek back and forth (would be cool, but difficult)..
|
||||
int sectorSize = pStreamSize < mMinStreamSize ? mShortSectorSize : mSectorSize;
|
||||
int sectorSize = pStreamSize < minStreamSize ? shortSectorSize : this.sectorSize;
|
||||
|
||||
return new Stream(chain, pStreamSize, sectorSize, this);
|
||||
}
|
||||
@@ -453,7 +455,7 @@ public final class CompoundDocument {
|
||||
byte[] bytes = new byte[Entry.LENGTH];
|
||||
|
||||
seekToDId(pDirectoryId);
|
||||
mInput.readFully(bytes);
|
||||
input.readFully(bytes);
|
||||
|
||||
return new ByteArrayInputStream(bytes);
|
||||
}
|
||||
@@ -462,8 +464,8 @@ public final class CompoundDocument {
|
||||
Entry entry = Entry.readEntry(new LittleEndianDataInputStream(
|
||||
getDirectoryStreamForDId(pDirectoryId)
|
||||
));
|
||||
entry.mParent = pParent;
|
||||
entry.mDocument = this;
|
||||
entry.parent = pParent;
|
||||
entry.document = this;
|
||||
return entry;
|
||||
}
|
||||
|
||||
@@ -527,21 +529,21 @@ public final class CompoundDocument {
|
||||
}
|
||||
|
||||
public Entry getRootEntry() throws IOException {
|
||||
if (mRootEntry == null) {
|
||||
if (rootEntry == null) {
|
||||
readSAT();
|
||||
|
||||
mRootEntry = getEntry(0, null);
|
||||
rootEntry = getEntry(0, null);
|
||||
|
||||
if (mRootEntry.type != Entry.ROOT_STORAGE) {
|
||||
throw new CorruptDocumentException("Invalid root storage type: " + mRootEntry.type);
|
||||
if (rootEntry.type != Entry.ROOT_STORAGE) {
|
||||
throw new CorruptDocumentException("Invalid root storage type: " + rootEntry.type);
|
||||
}
|
||||
}
|
||||
return mRootEntry;
|
||||
return rootEntry;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public int hashCode() {
|
||||
// return mUID.hashCode();
|
||||
// return uUID.hashCode();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
@@ -555,7 +557,7 @@ public final class CompoundDocument {
|
||||
// }
|
||||
//
|
||||
// if (pOther.getClass() == getClass()) {
|
||||
// return mUID.equals(((CompoundDocument) pOther).mUID);
|
||||
// return uUID.equals(((CompoundDocument) pOther).uUID);
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
@@ -565,7 +567,7 @@ public final class CompoundDocument {
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s[uuid: %s, sector size: %d/%d bytes, directory SID: %d, master SAT: %s entries]",
|
||||
getClass().getSimpleName(), mUID, mSectorSize, mShortSectorSize, mDirectorySId, mMasterSAT.length
|
||||
getClass().getSimpleName(), uUID, sectorSize, shortSectorSize, directorySId, masterSAT.length
|
||||
);
|
||||
}
|
||||
|
||||
@@ -638,11 +640,11 @@ public final class CompoundDocument {
|
||||
|
||||
private boolean fillBuffer() throws IOException {
|
||||
if (mNextSectorPos < mChain.length()) {
|
||||
// TODO: Sync on mDocument.mInput here, and we are completely detached... :-)
|
||||
// TODO: Sync on document.input here, and we are completely detached... :-)
|
||||
// TODO: We also need to sync other places...
|
||||
synchronized (mDocument) {
|
||||
mDocument.seekToSId(mChain.get(mNextSectorPos), mLength);
|
||||
mDocument.mInput.readFully(mBuffer);
|
||||
mDocument.input.readFully(mBuffer);
|
||||
}
|
||||
|
||||
mNextSectorPos++;
|
||||
|
@@ -61,9 +61,9 @@ public final class Entry implements Comparable<Entry> {
|
||||
int startSId;
|
||||
int streamSize;
|
||||
|
||||
CompoundDocument mDocument;
|
||||
Entry mParent;
|
||||
SortedSet<Entry> mChildren;
|
||||
CompoundDocument document;
|
||||
Entry parent;
|
||||
SortedSet<Entry> children;
|
||||
|
||||
public final static int LENGTH = 128;
|
||||
|
||||
@@ -190,7 +190,7 @@ public final class Entry implements Comparable<Entry> {
|
||||
return null;
|
||||
}
|
||||
|
||||
return mDocument.getInputStreamForSId(startSId, streamSize);
|
||||
return document.getInputStreamForSId(startSId, streamSize);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,7 +248,7 @@ public final class Entry implements Comparable<Entry> {
|
||||
* the root {@code Entry}
|
||||
*/
|
||||
public Entry getParentEntry() {
|
||||
return mParent;
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,7 +266,7 @@ public final class Entry implements Comparable<Entry> {
|
||||
|
||||
Entry dummy = new Entry();
|
||||
dummy.name = pName;
|
||||
dummy.mParent = this;
|
||||
dummy.parent = this;
|
||||
|
||||
SortedSet child = getChildEntries().tailSet(dummy);
|
||||
return (Entry) child.first();
|
||||
@@ -279,26 +279,26 @@ public final class Entry implements Comparable<Entry> {
|
||||
* @throws java.io.IOException if an I/O exception occurs
|
||||
*/
|
||||
public SortedSet<Entry> getChildEntries() throws IOException {
|
||||
if (mChildren == null) {
|
||||
if (children == null) {
|
||||
if (isFile() || rootNodeDId == -1) {
|
||||
mChildren = NO_CHILDREN;
|
||||
children = NO_CHILDREN;
|
||||
}
|
||||
else {
|
||||
// Start at root node in R/B tree, and raed to the left and right,
|
||||
// re-build tree, according to the docs
|
||||
mChildren = mDocument.getEntries(rootNodeDId, this);
|
||||
children = document.getEntries(rootNodeDId, this);
|
||||
}
|
||||
}
|
||||
|
||||
return mChildren;
|
||||
return children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "\"" + name + "\""
|
||||
+ " (" + (isFile() ? "Document" : (isDirectory() ? "Directory" : "Root"))
|
||||
+ (mParent != null ? ", parent: \"" + mParent.getName() + "\"" : "")
|
||||
+ (isFile() ? "" : ", children: " + (mChildren != null ? String.valueOf(mChildren.size()) : "(unknown)"))
|
||||
+ (parent != null ? ", parent: \"" + parent.getName() + "\"" : "")
|
||||
+ (isFile() ? "" : ", children: " + (children != null ? String.valueOf(children.size()) : "(unknown)"))
|
||||
+ ", SId=" + startSId + ", length=" + streamSize + ")";
|
||||
}
|
||||
|
||||
@@ -312,8 +312,8 @@ public final class Entry implements Comparable<Entry> {
|
||||
}
|
||||
|
||||
Entry other = (Entry) pOther;
|
||||
return name.equals(other.name) && (mParent == other.mParent
|
||||
|| (mParent != null && mParent.equals(other.mParent)));
|
||||
return name.equals(other.name) && (parent == other.parent
|
||||
|| (parent != null && parent.equals(other.parent)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -37,11 +37,10 @@ import java.net.*;
|
||||
* @see SimpleAuthenticator
|
||||
* @see java.net.Authenticator
|
||||
*
|
||||
* @author Harald Kuhr (haraldk@iconmedialab.no),
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface AuthenticatorFilter {
|
||||
public boolean accept(InetAddress pAddress, int pPort, String pProtocol,
|
||||
String pPrompt, String pScheme);
|
||||
public boolean accept(InetAddress pAddress, int pPort, String pProtocol, String pPrompt, String pScheme);
|
||||
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
package com.twelvemonkeys.net;
|
||||
|
||||
import com.twelvemonkeys.io.*;
|
||||
import com.twelvemonkeys.io.enc.Base64Decoder;
|
||||
@@ -41,8 +41,9 @@ import java.io.*;
|
||||
* @author unascribed
|
||||
* @author last modified by $Author: haku $
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/BASE64.java#1 $
|
||||
* @deprecated Use {@link com.twelvemonkeys.io.enc.Base64Encoder}/{@link Base64Decoder} instead
|
||||
*/
|
||||
public class BASE64 {
|
||||
class BASE64 {
|
||||
|
||||
/**
|
||||
* This array maps the characters to their 6 bit values
|
@@ -29,7 +29,6 @@
|
||||
package com.twelvemonkeys.net;
|
||||
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import com.twelvemonkeys.util.BASE64;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
@@ -65,18 +64,18 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
private final static String HTTP_HEADER_END = "\r\n\r\n";
|
||||
private static final String HEADER_WWW_AUTH = "WWW-Authenticate";
|
||||
private final static int BUF_SIZE = 8192;
|
||||
private int mMaxRedirects = (System.getProperty("http.maxRedirects") != null)
|
||||
private int maxRedirects = (System.getProperty("http.maxRedirects") != null)
|
||||
? Integer.parseInt(System.getProperty("http.maxRedirects"))
|
||||
: 20;
|
||||
protected int mTimeout = -1;
|
||||
protected int mConnectTimeout = -1;
|
||||
private Socket mSocket = null;
|
||||
protected InputStream mErrorStream = null;
|
||||
protected InputStream mInputStream = null;
|
||||
protected OutputStream mOutputStream = null;
|
||||
private String[] mResponseHeaders = null;
|
||||
protected Properties mResponseHeaderFields = null;
|
||||
protected Properties mRequestProperties = new Properties();
|
||||
protected int timeout = -1;
|
||||
protected int connectTimeout = -1;
|
||||
private Socket socket = null;
|
||||
protected InputStream errorStream = null;
|
||||
protected InputStream inputStream = null;
|
||||
protected OutputStream outputStream = null;
|
||||
private String[] responseHeaders = null;
|
||||
protected Properties responseHeaderFields = null;
|
||||
protected Properties requestProperties = new Properties();
|
||||
|
||||
/**
|
||||
* Creates a HttpURLConnection.
|
||||
@@ -114,7 +113,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
protected HttpURLConnection(URL pURL, int pTimeout, int pConnectTimeout) {
|
||||
super(pURL);
|
||||
setTimeout(pTimeout);
|
||||
mConnectTimeout = pConnectTimeout;
|
||||
connectTimeout = pConnectTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,13 +134,13 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
if (connected) {
|
||||
throw new IllegalAccessError("Already connected");
|
||||
}
|
||||
String oldValue = mRequestProperties.getProperty(pKey);
|
||||
String oldValue = requestProperties.getProperty(pKey);
|
||||
|
||||
if (oldValue == null) {
|
||||
mRequestProperties.setProperty(pKey, pValue);
|
||||
requestProperties.setProperty(pKey, pValue);
|
||||
}
|
||||
else {
|
||||
mRequestProperties.setProperty(pKey, oldValue + ", " + pValue);
|
||||
requestProperties.setProperty(pKey, oldValue + ", " + pValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +157,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
if (connected) {
|
||||
throw new IllegalAccessError("Already connected");
|
||||
}
|
||||
return mRequestProperties.getProperty(pKey);
|
||||
return requestProperties.getProperty(pKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,7 +211,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
* if there is no such field in the header.
|
||||
*/
|
||||
public String getHeaderField(String pName) {
|
||||
return mResponseHeaderFields.getProperty(StringUtil.toLowerCase(pName));
|
||||
return responseHeaderFields.getProperty(StringUtil.toLowerCase(pName));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,10 +229,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
*/
|
||||
public String getHeaderField(int pIndex) {
|
||||
// TODO: getInputStream() first, to make sure we have header fields
|
||||
if (pIndex >= mResponseHeaders.length) {
|
||||
if (pIndex >= responseHeaders.length) {
|
||||
return null;
|
||||
}
|
||||
String field = mResponseHeaders[pIndex];
|
||||
String field = responseHeaders[pIndex];
|
||||
|
||||
// pIndex == 0, means the response code etc (i.e. "HTTP/1.1 200 OK").
|
||||
if ((pIndex == 0) || (field == null)) {
|
||||
@@ -256,10 +255,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
*/
|
||||
public String getHeaderFieldKey(int pIndex) {
|
||||
// TODO: getInputStream() first, to make sure we have header fields
|
||||
if (pIndex >= mResponseHeaders.length) {
|
||||
if (pIndex >= responseHeaders.length) {
|
||||
return null;
|
||||
}
|
||||
String field = mResponseHeaders[pIndex];
|
||||
String field = responseHeaders[pIndex];
|
||||
|
||||
if (StringUtil.isEmpty(field)) {
|
||||
return null;
|
||||
@@ -283,10 +282,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
if (pTimeout < 0) { // Must be positive
|
||||
throw new IllegalArgumentException("Timeout must be positive.");
|
||||
}
|
||||
mTimeout = pTimeout;
|
||||
if (mSocket != null) {
|
||||
timeout = pTimeout;
|
||||
if (socket != null) {
|
||||
try {
|
||||
mSocket.setSoTimeout(pTimeout);
|
||||
socket.setSoTimeout(pTimeout);
|
||||
}
|
||||
catch (SocketException se) {
|
||||
// Not much to do about that...
|
||||
@@ -305,12 +304,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
public int getTimeout() {
|
||||
|
||||
try {
|
||||
return ((mSocket != null)
|
||||
? mSocket.getSoTimeout()
|
||||
: mTimeout);
|
||||
return ((socket != null)
|
||||
? socket.getSoTimeout()
|
||||
: timeout);
|
||||
}
|
||||
catch (SocketException se) {
|
||||
return mTimeout;
|
||||
return timeout;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,24 +331,24 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
}
|
||||
int length;
|
||||
|
||||
if (mInputStream == null) {
|
||||
if (inputStream == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// "De-chunk" the output stream
|
||||
else if ("chunked".equalsIgnoreCase(getHeaderField("Transfer-Encoding"))) {
|
||||
if (!(mInputStream instanceof ChunkedInputStream)) {
|
||||
mInputStream = new ChunkedInputStream(mInputStream);
|
||||
if (!(inputStream instanceof ChunkedInputStream)) {
|
||||
inputStream = new ChunkedInputStream(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we don't wait forever, if the content-length is known
|
||||
else if ((length = getHeaderFieldInt("Content-Length", -1)) >= 0) {
|
||||
if (!(mInputStream instanceof FixedLengthInputStream)) {
|
||||
mInputStream = new FixedLengthInputStream(mInputStream, length);
|
||||
if (!(inputStream instanceof FixedLengthInputStream)) {
|
||||
inputStream = new FixedLengthInputStream(inputStream, length);
|
||||
}
|
||||
}
|
||||
return mInputStream;
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,7 +363,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
if (!connected) {
|
||||
connect();
|
||||
}
|
||||
return mOutputStream;
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,15 +373,15 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
* instance can be reused for other requests.
|
||||
*/
|
||||
public void disconnect() {
|
||||
if (mSocket != null) {
|
||||
if (socket != null) {
|
||||
try {
|
||||
mSocket.close();
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
|
||||
// Does not matter, I guess.
|
||||
}
|
||||
mSocket = null;
|
||||
socket = null;
|
||||
}
|
||||
connected = false;
|
||||
}
|
||||
@@ -397,37 +396,37 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
: HTTP_DEFAULT_PORT;
|
||||
|
||||
// Create socket if we don't have one
|
||||
if (mSocket == null) {
|
||||
//mSocket = new Socket(pURL.getHost(), port); // Blocks...
|
||||
mSocket = createSocket(pURL, port, mConnectTimeout);
|
||||
mSocket.setSoTimeout(mTimeout);
|
||||
if (socket == null) {
|
||||
//socket = new Socket(pURL.getHost(), port); // Blocks...
|
||||
socket = createSocket(pURL, port, connectTimeout);
|
||||
socket.setSoTimeout(timeout);
|
||||
}
|
||||
|
||||
// Get Socket output stream
|
||||
OutputStream os = mSocket.getOutputStream();
|
||||
OutputStream os = socket.getOutputStream();
|
||||
|
||||
// Connect using HTTP
|
||||
writeRequestHeaders(os, pURL, method, mRequestProperties, usingProxy(), pAuth, pAuthType);
|
||||
writeRequestHeaders(os, pURL, method, requestProperties, usingProxy(), pAuth, pAuthType);
|
||||
|
||||
// Get response input stream
|
||||
InputStream sis = mSocket.getInputStream();
|
||||
InputStream sis = socket.getInputStream();
|
||||
BufferedInputStream is = new BufferedInputStream(sis);
|
||||
|
||||
// Detatch reponse headers from reponse input stream
|
||||
InputStream header = detatchResponseHeader(is);
|
||||
|
||||
// Parse headers and set response code/message
|
||||
mResponseHeaders = parseResponseHeader(header);
|
||||
mResponseHeaderFields = parseHeaderFields(mResponseHeaders);
|
||||
responseHeaders = parseResponseHeader(header);
|
||||
responseHeaderFields = parseHeaderFields(responseHeaders);
|
||||
|
||||
//System.err.println("Headers fields:");
|
||||
//mResponseHeaderFields.list(System.err);
|
||||
//responseHeaderFields.list(System.err);
|
||||
// Test HTTP response code, to see if further action is needed
|
||||
switch (getResponseCode()) {
|
||||
case HTTP_OK:
|
||||
// 200 OK
|
||||
mInputStream = is;
|
||||
mErrorStream = null;
|
||||
inputStream = is;
|
||||
errorStream = null;
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -472,7 +471,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
|
||||
// Avoid infinite loop
|
||||
if (pRetries++ <= 0) {
|
||||
throw new ProtocolException("Server redirected too many times (" + mMaxRedirects + ") (Authentication required: " + auth + ")"); // This is what sun.net.www.protocol.http.HttpURLConnection does
|
||||
throw new ProtocolException("Server redirected too many times (" + maxRedirects + ") (Authentication required: " + auth + ")"); // This is what sun.net.www.protocol.http.HttpURLConnection does
|
||||
}
|
||||
else if (pa != null) {
|
||||
connect(pURL, pa, method, pRetries);
|
||||
@@ -506,8 +505,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
|
||||
// Test if we can reuse the Socket
|
||||
if (!(newLoc.getAuthority().equals(pURL.getAuthority()) && (newLoc.getPort() == pURL.getPort()))) {
|
||||
mSocket.close(); // Close the socket, won't need it anymore
|
||||
mSocket = null;
|
||||
socket.close(); // Close the socket, won't need it anymore
|
||||
socket = null;
|
||||
}
|
||||
if (location != null) {
|
||||
//System.err.println("Redirecting to " + location);
|
||||
@@ -526,22 +525,22 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
default :
|
||||
// Not 200 OK, or any of the redirect responses
|
||||
// Probably an error...
|
||||
mErrorStream = is;
|
||||
mInputStream = null;
|
||||
errorStream = is;
|
||||
inputStream = null;
|
||||
}
|
||||
|
||||
// --- Need rethinking...
|
||||
// No further questions, let the Socket wait forever (until the server
|
||||
// closes the connection)
|
||||
//mSocket.setSoTimeout(0);
|
||||
//socket.setSoTimeout(0);
|
||||
// Probably not... The timeout should only kick if the read BLOCKS.
|
||||
// Shutdown output, meaning any writes to the outputstream below will
|
||||
// probably fail...
|
||||
//mSocket.shutdownOutput();
|
||||
//socket.shutdownOutput();
|
||||
// Not a good idea at all... POSTs need the outputstream to send the
|
||||
// form-data.
|
||||
// --- /Need rethinking.
|
||||
mOutputStream = os;
|
||||
outputStream = os;
|
||||
}
|
||||
|
||||
private static interface SocketConnector extends Runnable {
|
||||
@@ -663,7 +662,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
return; // Ignore
|
||||
}
|
||||
connected = true;
|
||||
connect(url, null, null, mMaxRedirects);
|
||||
connect(url, null, null, maxRedirects);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -3,7 +3,6 @@ package com.twelvemonkeys.net;
|
||||
import com.twelvemonkeys.io.FileUtil;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import com.twelvemonkeys.lang.DateUtil;
|
||||
import com.twelvemonkeys.util.BASE64;
|
||||
import com.twelvemonkeys.util.CollectionUtil;
|
||||
|
||||
import java.io.*;
|
||||
|
@@ -28,29 +28,31 @@
|
||||
|
||||
package com.twelvemonkeys.net;
|
||||
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
import java.net.Authenticator;
|
||||
import java.net.InetAddress;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.URL;
|
||||
import java.util.Hashtable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple Authenticator implementation.
|
||||
* Singleton class, obtain reference through the static
|
||||
* Singleton class, obtain reference through the static
|
||||
* {@code getInstance} method.
|
||||
* <P>
|
||||
* <p/>
|
||||
* <EM>After swearing, sweating, pulling my hair, banging my head repeatedly
|
||||
* into the walls and reading the java.net.Authenticator API documentation
|
||||
* into the walls and reading the java.net.Authenticator API documentation
|
||||
* once more, an idea came to my mind. This is the result. I hope you find it
|
||||
* useful. -- Harald K.</EM>
|
||||
*
|
||||
* @see java.net.Authenticator
|
||||
*
|
||||
* @author Harald Kuhr (haraldk@iconmedialab.no)
|
||||
* @version 1.0
|
||||
* @version 1.0
|
||||
* @see java.net.Authenticator
|
||||
*/
|
||||
public class SimpleAuthenticator extends Authenticator {
|
||||
|
||||
|
||||
/** The reference to the single instance of this class. */
|
||||
private static SimpleAuthenticator sInstance = null;
|
||||
/** Keeps track of the state of this class. */
|
||||
@@ -63,237 +65,179 @@ public class SimpleAuthenticator extends Authenticator {
|
||||
/** Basic authentication scheme. */
|
||||
public final static String BASIC = "Basic";
|
||||
|
||||
/**
|
||||
* The hastable that keeps track of the PasswordAuthentications.
|
||||
*/
|
||||
/** The hastable that keeps track of the PasswordAuthentications. */
|
||||
protected Map<AuthKey, PasswordAuthentication> passwordAuthentications = null;
|
||||
|
||||
protected Hashtable mPasswordAuthentications = null;
|
||||
|
||||
/**
|
||||
* The hastable that keeps track of the Authenticators.
|
||||
*/
|
||||
|
||||
protected Hashtable mAuthenticators = null;
|
||||
|
||||
/**
|
||||
* Creates a SimpleAuthenticator.
|
||||
*/
|
||||
/** The hastable that keeps track of the Authenticators. */
|
||||
protected Map<PasswordAuthenticator, AuthenticatorFilter> authenticators = null;
|
||||
|
||||
/** Creates a SimpleAuthenticator. */
|
||||
private SimpleAuthenticator() {
|
||||
mPasswordAuthentications = new Hashtable();
|
||||
mAuthenticators = new Hashtable();
|
||||
passwordAuthentications = new HashMap<AuthKey, PasswordAuthentication>();
|
||||
authenticators = new HashMap<PasswordAuthenticator, AuthenticatorFilter>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SimpleAuthenticator instance and registers it through the
|
||||
* Gets the SimpleAuthenticator instance and registers it through the
|
||||
* Authenticator.setDefault(). If there is no current instance
|
||||
* of the SimpleAuthenticator in the VM, one is created. This method will
|
||||
* try to figure out if the setDefault() succeeded (a hack), and will
|
||||
* try to figure out if the setDefault() succeeded (a hack), and will
|
||||
* return null if it was not able to register the instance as default.
|
||||
*
|
||||
* @return The single instance of this class, or null, if another
|
||||
* Authenticator is allready registered as default.
|
||||
* @return The single instance of this class, or null, if another
|
||||
* Authenticator is allready registered as default.
|
||||
*/
|
||||
|
||||
public static synchronized SimpleAuthenticator getInstance() {
|
||||
if (!sInitialized) {
|
||||
// Create an instance
|
||||
sInstance = new SimpleAuthenticator();
|
||||
if (!sInitialized) {
|
||||
// Create an instance
|
||||
sInstance = new SimpleAuthenticator();
|
||||
|
||||
// Try to set default (this may quietly fail...)
|
||||
Authenticator.setDefault(sInstance);
|
||||
// Try to set default (this may quietly fail...)
|
||||
Authenticator.setDefault(sInstance);
|
||||
|
||||
// A hack to figure out if we really did set the authenticator
|
||||
PasswordAuthentication pa =
|
||||
Authenticator.requestPasswordAuthentication(null, FOURTYTWO,
|
||||
null, null, MAGIC);
|
||||
// A hack to figure out if we really did set the authenticator
|
||||
PasswordAuthentication pa = Authenticator.requestPasswordAuthentication(null, FOURTYTWO, null, null, MAGIC);
|
||||
|
||||
// If this test returns false, we didn't succeed, so we set the
|
||||
// instance back to null.
|
||||
if (pa == null || !MAGIC.equals(pa.getUserName()) ||
|
||||
!("" + FOURTYTWO).equals(new String(pa.getPassword())))
|
||||
sInstance = null;
|
||||
// If this test returns false, we didn't succeed, so we set the
|
||||
// instance back to null.
|
||||
if (pa == null || !MAGIC.equals(pa.getUserName()) || !("" + FOURTYTWO).equals(new String(pa.getPassword()))) {
|
||||
sInstance = null;
|
||||
}
|
||||
|
||||
// Done
|
||||
sInitialized = true;
|
||||
}
|
||||
// Done
|
||||
sInitialized = true;
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PasswordAuthentication for the request. Called when password
|
||||
* Gets the PasswordAuthentication for the request. Called when password
|
||||
* authorization is needed.
|
||||
*
|
||||
* @return The PasswordAuthentication collected from the user, or null if
|
||||
* @return The PasswordAuthentication collected from the user, or null if
|
||||
* none is provided.
|
||||
*/
|
||||
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
// Don't worry, this is just a hack to figure out if we were able
|
||||
// to set this Authenticator through the setDefault method.
|
||||
if (!sInitialized && MAGIC.equals(getRequestingScheme())
|
||||
&& getRequestingPort() == FOURTYTWO)
|
||||
return new PasswordAuthentication(MAGIC, ("" + FOURTYTWO)
|
||||
.toCharArray());
|
||||
/*
|
||||
System.err.println("getPasswordAuthentication");
|
||||
System.err.println(getRequestingSite());
|
||||
System.err.println(getRequestingPort());
|
||||
System.err.println(getRequestingProtocol());
|
||||
System.err.println(getRequestingPrompt());
|
||||
System.err.println(getRequestingScheme());
|
||||
*/
|
||||
// Don't worry, this is just a hack to figure out if we were able
|
||||
// to set this Authenticator through the setDefault method.
|
||||
if (!sInitialized && MAGIC.equals(getRequestingScheme()) && getRequestingPort() == FOURTYTWO) {
|
||||
return new PasswordAuthentication(MAGIC, ("" + FOURTYTWO).toCharArray());
|
||||
}
|
||||
/*
|
||||
System.err.println("getPasswordAuthentication");
|
||||
System.err.println(getRequestingSite());
|
||||
System.err.println(getRequestingPort());
|
||||
System.err.println(getRequestingProtocol());
|
||||
System.err.println(getRequestingPrompt());
|
||||
System.err.println(getRequestingScheme());
|
||||
*/
|
||||
|
||||
// TODO:
|
||||
// Look for a more specific PasswordAuthenticatior before using
|
||||
// Default:
|
||||
//
|
||||
// if (...)
|
||||
// return pa.requestPasswordAuthentication(getRequestingSite(),
|
||||
// getRequestingPort(),
|
||||
// getRequestingProtocol(),
|
||||
// getRequestingPrompt(),
|
||||
// getRequestingScheme());
|
||||
// TODO:
|
||||
// Look for a more specific PasswordAuthenticatior before using
|
||||
// Default:
|
||||
//
|
||||
// if (...)
|
||||
// return pa.requestPasswordAuthentication(getRequestingSite(),
|
||||
// getRequestingPort(),
|
||||
// getRequestingProtocol(),
|
||||
// getRequestingPrompt(),
|
||||
// getRequestingScheme());
|
||||
|
||||
return (PasswordAuthentication)
|
||||
mPasswordAuthentications.get(new AuthKey(getRequestingSite(),
|
||||
getRequestingPort(),
|
||||
getRequestingProtocol(),
|
||||
getRequestingPrompt(),
|
||||
getRequestingScheme()));
|
||||
return passwordAuthentications.get(new AuthKey(getRequestingSite(),
|
||||
getRequestingPort(),
|
||||
getRequestingProtocol(),
|
||||
getRequestingPrompt(),
|
||||
getRequestingScheme()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a PasswordAuthentication with a given URL address.
|
||||
*
|
||||
*/
|
||||
|
||||
public PasswordAuthentication registerPasswordAuthentication(URL pURL,
|
||||
PasswordAuthentication pPA) {
|
||||
return registerPasswordAuthentication(NetUtil.createInetAddressFromURL(pURL),
|
||||
pURL.getPort(),
|
||||
pURL.getProtocol(),
|
||||
null, // Prompt/Realm
|
||||
BASIC,
|
||||
pPA);
|
||||
/** Registers a PasswordAuthentication with a given URL address. */
|
||||
public PasswordAuthentication registerPasswordAuthentication(URL pURL, PasswordAuthentication pPA) {
|
||||
return registerPasswordAuthentication(NetUtil.createInetAddressFromURL(pURL),
|
||||
pURL.getPort(),
|
||||
pURL.getProtocol(),
|
||||
null, // Prompt/Realm
|
||||
BASIC,
|
||||
pPA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a PasswordAuthentication with a given net address.
|
||||
*
|
||||
*/
|
||||
/** Registers a PasswordAuthentication with a given net address. */
|
||||
public PasswordAuthentication registerPasswordAuthentication(InetAddress pAddress, int pPort, String pProtocol, String pPrompt, String pScheme, PasswordAuthentication pPA) {
|
||||
/*
|
||||
System.err.println("registerPasswordAuthentication");
|
||||
System.err.println(pAddress);
|
||||
System.err.println(pPort);
|
||||
System.err.println(pProtocol);
|
||||
System.err.println(pPrompt);
|
||||
System.err.println(pScheme);
|
||||
*/
|
||||
|
||||
public PasswordAuthentication registerPasswordAuthentication(
|
||||
InetAddress pAddress, int pPort, String pProtocol,
|
||||
String pPrompt, String pScheme, PasswordAuthentication pPA)
|
||||
{
|
||||
/*
|
||||
System.err.println("registerPasswordAuthentication");
|
||||
System.err.println(pAddress);
|
||||
System.err.println(pPort);
|
||||
System.err.println(pProtocol);
|
||||
System.err.println(pPrompt);
|
||||
System.err.println(pScheme);
|
||||
*/
|
||||
|
||||
return (PasswordAuthentication)
|
||||
mPasswordAuthentications.put(new AuthKey(pAddress, pPort,
|
||||
pProtocol, pPrompt,
|
||||
pScheme),
|
||||
pPA);
|
||||
return passwordAuthentications.put(new AuthKey(pAddress, pPort, pProtocol, pPrompt, pScheme), pPA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a PasswordAuthentication with a given URL address.
|
||||
*
|
||||
*/
|
||||
|
||||
/** Unregisters a PasswordAuthentication with a given URL address. */
|
||||
public PasswordAuthentication unregisterPasswordAuthentication(URL pURL) {
|
||||
return unregisterPasswordAuthentication(NetUtil.createInetAddressFromURL(pURL),
|
||||
pURL.getPort(),
|
||||
pURL.getProtocol(),
|
||||
null,
|
||||
BASIC);
|
||||
return unregisterPasswordAuthentication(NetUtil.createInetAddressFromURL(pURL), pURL.getPort(), pURL.getProtocol(), null, BASIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a PasswordAuthentication with a given net address.
|
||||
*
|
||||
*/
|
||||
|
||||
public PasswordAuthentication unregisterPasswordAuthentication(
|
||||
InetAddress pAddress, int pPort, String pProtocol,
|
||||
String pPrompt, String pScheme)
|
||||
{
|
||||
return (PasswordAuthentication)
|
||||
mPasswordAuthentications.remove(new AuthKey(pAddress, pPort,
|
||||
pProtocol, pPrompt,
|
||||
pScheme));
|
||||
/** Unregisters a PasswordAuthentication with a given net address. */
|
||||
public PasswordAuthentication unregisterPasswordAuthentication(InetAddress pAddress, int pPort, String pProtocol, String pPrompt, String pScheme) {
|
||||
return passwordAuthentications.remove(new AuthKey(pAddress, pPort, pProtocol, pPrompt, pScheme));
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Registers a PasswordAuthenticator that can answer authentication
|
||||
* requests.
|
||||
*
|
||||
*
|
||||
* @see PasswordAuthenticator
|
||||
*/
|
||||
|
||||
public void registerPasswordAuthenticator(PasswordAuthenticator pPA,
|
||||
AuthenticatorFilter pFilter) {
|
||||
mAuthenticators.put(pPA, pFilter);
|
||||
public void registerPasswordAuthenticator(PasswordAuthenticator pPA, AuthenticatorFilter pFilter) {
|
||||
authenticators.put(pPA, pFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Unregisters a PasswordAuthenticator that can answer authentication
|
||||
* requests.
|
||||
*
|
||||
*
|
||||
* @see PasswordAuthenticator
|
||||
*/
|
||||
|
||||
public void unregisterPasswordAuthenticator(PasswordAuthenticator pPA) {
|
||||
mAuthenticators.remove(pPA);
|
||||
authenticators.remove(pPA);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class, used for caching the PasswordAuthentication objects.
|
||||
* Everything but address may be null
|
||||
*/
|
||||
|
||||
class AuthKey {
|
||||
|
||||
InetAddress mAddress = null;
|
||||
int mPort = -1;
|
||||
String mProtocol = null;
|
||||
String mPrompt = null;
|
||||
String mScheme = null;
|
||||
|
||||
AuthKey(InetAddress pAddress, int pPort, String pProtocol,
|
||||
String pPrompt, String pScheme) {
|
||||
if (pAddress == null)
|
||||
throw new IllegalArgumentException("Address argument can't be null!");
|
||||
InetAddress address = null;
|
||||
int port = -1;
|
||||
String protocol = null;
|
||||
String prompt = null;
|
||||
String scheme = null;
|
||||
|
||||
mAddress = pAddress;
|
||||
mPort = pPort;
|
||||
mProtocol = pProtocol;
|
||||
mPrompt = pPrompt;
|
||||
mScheme = pScheme;
|
||||
AuthKey(InetAddress pAddress, int pPort, String pProtocol, String pPrompt, String pScheme) {
|
||||
Validate.notNull(pAddress, "address");
|
||||
|
||||
// System.out.println("Created: " + this);
|
||||
address = pAddress;
|
||||
port = pPort;
|
||||
protocol = pProtocol;
|
||||
prompt = pPrompt;
|
||||
scheme = pScheme;
|
||||
|
||||
// System.out.println("Created: " + this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string representation of this object.
|
||||
*/
|
||||
/** Creates a string representation of this object. */
|
||||
|
||||
public String toString() {
|
||||
return "AuthKey[" + mAddress + ":" + mPort + "/" + mProtocol + " \"" + mPrompt + "\" (" + mScheme + ")]";
|
||||
return "AuthKey[" + address + ":" + port + "/" + protocol + " \"" + prompt + "\" (" + scheme + ")]";
|
||||
}
|
||||
|
||||
public boolean equals(Object pObj) {
|
||||
return (pObj instanceof AuthKey ? equals((AuthKey) pObj) : false);
|
||||
return (pObj instanceof AuthKey && equals((AuthKey) pObj));
|
||||
}
|
||||
|
||||
// Ahem.. Breaks the rule from Object.equals(Object):
|
||||
@@ -302,25 +246,25 @@ class AuthKey {
|
||||
// should return true.
|
||||
|
||||
public boolean equals(AuthKey pKey) {
|
||||
// Maybe allow nulls, and still be equal?
|
||||
return (mAddress.equals(pKey.mAddress)
|
||||
&& (mPort == -1
|
||||
|| pKey.mPort == -1
|
||||
|| mPort == pKey.mPort)
|
||||
&& (mProtocol == null
|
||||
|| pKey.mProtocol == null
|
||||
|| mProtocol.equals(pKey.mProtocol))
|
||||
&& (mPrompt == null
|
||||
|| pKey.mPrompt == null
|
||||
|| mPrompt.equals(pKey.mPrompt))
|
||||
&& (mScheme == null
|
||||
|| pKey.mScheme == null
|
||||
|| mScheme.equalsIgnoreCase(pKey.mScheme)));
|
||||
// Maybe allow nulls, and still be equal?
|
||||
return (address.equals(pKey.address)
|
||||
&& (port == -1
|
||||
|| pKey.port == -1
|
||||
|| port == pKey.port)
|
||||
&& (protocol == null
|
||||
|| pKey.protocol == null
|
||||
|| protocol.equals(pKey.protocol))
|
||||
&& (prompt == null
|
||||
|| pKey.prompt == null
|
||||
|| prompt.equals(pKey.prompt))
|
||||
&& (scheme == null
|
||||
|| pKey.scheme == null
|
||||
|| scheme.equalsIgnoreCase(pKey.scheme)));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
// There won't be too many pr address, will it? ;-)
|
||||
return mAddress.hashCode();
|
||||
// There won't be too many pr address, will it? ;-)
|
||||
return address.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -52,13 +52,13 @@ public final class DOMSerializer {
|
||||
private static final String PARAM_PRETTY_PRINT = "format-pretty-print";
|
||||
private static final String PARAM_XML_DECLARATION = "xml-declaration";
|
||||
|
||||
private final LSSerializer mSerializer;
|
||||
private final LSOutput mOutput;
|
||||
private final LSSerializer serializer;
|
||||
private final LSOutput output;
|
||||
|
||||
private DOMSerializer() {
|
||||
DOMImplementationLS domImpl = Support.getImplementation();
|
||||
mSerializer = domImpl.createLSSerializer();
|
||||
mOutput = domImpl.createLSOutput();
|
||||
serializer = domImpl.createLSSerializer();
|
||||
output = domImpl.createLSOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,8 +71,8 @@ public final class DOMSerializer {
|
||||
public DOMSerializer(final OutputStream pStream, final String pEncoding) {
|
||||
this();
|
||||
|
||||
mOutput.setByteStream(pStream);
|
||||
mOutput.setEncoding(pEncoding);
|
||||
output.setByteStream(pStream);
|
||||
output.setEncoding(pEncoding);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,17 +84,17 @@ public final class DOMSerializer {
|
||||
public DOMSerializer(final Writer pStream) {
|
||||
this();
|
||||
|
||||
mOutput.setCharacterStream(pStream);
|
||||
output.setCharacterStream(pStream);
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: Is it useful?
|
||||
public void setNewLine(final String pNewLine) {
|
||||
mSerializer.setNewLine(pNewLine);
|
||||
serializer.setNewLine(pNewLine);
|
||||
}
|
||||
|
||||
public String getNewLine() {
|
||||
return mSerializer.getNewLine();
|
||||
return serializer.getNewLine();
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -107,18 +107,18 @@ public final class DOMSerializer {
|
||||
* @param pPrettyPrint {@code true} to enable pretty printing
|
||||
*/
|
||||
public void setPrettyPrint(final boolean pPrettyPrint) {
|
||||
DOMConfiguration configuration = mSerializer.getDomConfig();
|
||||
DOMConfiguration configuration = serializer.getDomConfig();
|
||||
if (configuration.canSetParameter(PARAM_PRETTY_PRINT, pPrettyPrint)) {
|
||||
configuration.setParameter(PARAM_PRETTY_PRINT, pPrettyPrint);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getPrettyPrint() {
|
||||
return Boolean.TRUE.equals(mSerializer.getDomConfig().getParameter(PARAM_PRETTY_PRINT));
|
||||
return Boolean.TRUE.equals(serializer.getDomConfig().getParameter(PARAM_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
private void setXMLDeclaration(boolean pXMLDeclaration) {
|
||||
mSerializer.getDomConfig().setParameter(PARAM_XML_DECLARATION, pXMLDeclaration);
|
||||
serializer.getDomConfig().setParameter(PARAM_XML_DECLARATION, pXMLDeclaration);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,7 +142,7 @@ public final class DOMSerializer {
|
||||
|
||||
private void serializeImpl(final Node pNode, final boolean pOmitDecl) {
|
||||
setXMLDeclaration(pOmitDecl);
|
||||
mSerializer.write(pNode, mOutput);
|
||||
serializer.write(pNode, output);
|
||||
}
|
||||
|
||||
private static class Support {
|
||||
|
@@ -65,22 +65,22 @@ public class XMLSerializer {
|
||||
// Store user options here too
|
||||
// TODO: Push/pop?
|
||||
|
||||
private final OutputStream mOutput;
|
||||
private final Charset mEncoding;
|
||||
private final SerializationContext mContext;
|
||||
private final OutputStream output;
|
||||
private final Charset encoding;
|
||||
private final SerializationContext context;
|
||||
|
||||
public XMLSerializer(final OutputStream pOutput, final String pEncoding) {
|
||||
mOutput = pOutput;
|
||||
mEncoding = Charset.forName(pEncoding);
|
||||
mContext = new SerializationContext();
|
||||
output = pOutput;
|
||||
encoding = Charset.forName(pEncoding);
|
||||
context = new SerializationContext();
|
||||
}
|
||||
|
||||
public final void setIndentation(String pIndent) {
|
||||
mContext.indent = pIndent != null ? pIndent : " ";
|
||||
context.indent = pIndent != null ? pIndent : " ";
|
||||
}
|
||||
|
||||
public final void setStripComments(boolean pStrip) {
|
||||
mContext.stripComments = pStrip;
|
||||
context.stripComments = pStrip;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,12 +101,12 @@ public class XMLSerializer {
|
||||
* @param pWriteXMLDeclaration {@code true} if the XML declaration should be included, otherwise {@code false}.
|
||||
*/
|
||||
public void serialize(final Node pRootNode, final boolean pWriteXMLDeclaration) {
|
||||
PrintWriter out = new PrintWriter(new OutputStreamWriter(mOutput, mEncoding));
|
||||
PrintWriter out = new PrintWriter(new OutputStreamWriter(output, encoding));
|
||||
try {
|
||||
if (pWriteXMLDeclaration) {
|
||||
writeXMLDeclaration(out);
|
||||
}
|
||||
writeXML(out, pRootNode, mContext.copy());
|
||||
writeXML(out, pRootNode, context.copy());
|
||||
}
|
||||
finally {
|
||||
out.flush();
|
||||
@@ -115,7 +115,7 @@ public class XMLSerializer {
|
||||
|
||||
private void writeXMLDeclaration(final PrintWriter pOut) {
|
||||
pOut.print("<?xml version=\"1.0\" encoding=\"");
|
||||
pOut.print(mEncoding.name());
|
||||
pOut.print(encoding.name());
|
||||
pOut.println("\"?>");
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user