/** * This file is part of OSM2ShareNav * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * * Copyright (C) 2008 Kai Krueger */ package net.sharenav.osmToShareNav; import java.io.IOException; import java.io.InputStream; public class ThreadBufferedInputStream extends InputStream implements Runnable { private InputStream is; private byte[][] buffer; private int bufferReadIdx; private int bufferWriteIdx; private int readIdx; private int writeIdx; private boolean writeSwappReady; private boolean readSwappReady; private int readLength; private Thread workerThread; private boolean eof; private boolean eofIn; public ThreadBufferedInputStream(InputStream in) { is = in; buffer = new byte[2][]; buffer[0] = new byte[1024 * 1024]; buffer[1] = new byte[1024 * 1024]; writeSwappReady = false; readSwappReady = false; bufferReadIdx = 0; bufferWriteIdx = 1; readLength = 0; readIdx = 0; writeIdx = 0; eof = false; eofIn = false; workerThread = new Thread(this, "ThreadBuffered-reader"); workerThread.start(); } /* (non-Javadoc) * @see java.io.InputStream#read() */ @Override public int read() throws IOException { if (readLength <= readIdx ) { synchronized (this) { if (eof) { return -1; } readSwappReady = true; if (writeSwappReady) { swapBuffers(); } else { try { wait(); } catch (InterruptedException e) { System.out.println("Something went horribly wrong " + e.getMessage()); System.exit(3); } } } } byte res = buffer[bufferReadIdx][readIdx++]; return res; } public int read(byte[] buf) { if (readLength <= readIdx ) { synchronized (this) { if (eof) { return -1; } readSwappReady = true; if (writeSwappReady) { swapBuffers(); } else { try { wait(); } catch (InterruptedException e) { System.out.println("Something went horribly wrong " + e.getMessage()); System.exit(3); } } } } int noRead = buf.length; if (noRead + readIdx > readLength) { noRead = readLength - readIdx; } System.arraycopy(buffer[bufferReadIdx], readIdx, buf, 0, noRead); readIdx += noRead; return noRead; } public int read(byte[] buf, int off, int len) { if (readLength <= readIdx ) { synchronized (this) { readSwappReady = true; if (eof) { return -1; } if (writeSwappReady) swapBuffers(); else { try { wait(); } catch (InterruptedException e) { System.out.println("Something went horribly wrong " + e.getMessage()); System.exit(3); } } } } int noRead = len; if (noRead + readIdx > readLength) { noRead = readLength - readIdx; } System.arraycopy(buffer[bufferReadIdx], readIdx, buf, off, noRead); readIdx += noRead; return noRead; } /* (non-Javadoc) * @see java.lang.Runnable#run() */ public void run() { int noRead = 0; while (noRead != -1) { try { noRead = is.read(buffer[bufferWriteIdx],writeIdx,buffer[bufferWriteIdx].length - writeIdx); if (noRead == -1) { eofIn = true; //System.out.println("finished reading is"); } } catch (IOException e) { System.out.println("Something went horribly wrong " + e.getMessage()); System.exit(2); } if (!eofIn) { writeIdx += noRead; } if (buffer[bufferWriteIdx].length <= writeIdx || eofIn) { synchronized (this) { writeSwappReady = true; if (readSwappReady) { swapBuffers(); } else { try { wait(); } catch (InterruptedException e) { System.out.println("Something went horribly wrong " + e.getMessage()); System.exit(3); } } } } } } private void swapBuffers () { readLength = writeIdx; readSwappReady = false; writeSwappReady = false; readIdx = 0; writeIdx= 0; int tmp = bufferReadIdx; bufferReadIdx = bufferWriteIdx; bufferWriteIdx = tmp; if (eofIn) { eof = true; } notifyAll(); } }