trace/traceviewer/com.nokia.traceviewer/src/com/nokia/traceviewer/engine/PlainTextScrollReader.java
changeset 11 5b9d4d8641ce
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trace/traceviewer/com.nokia.traceviewer/src/com/nokia/traceviewer/engine/PlainTextScrollReader.java	Wed Jun 23 14:49:59 2010 +0300
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). 
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:
+ *
+ * PlainTextScrollReader class
+ *
+ */
+package com.nokia.traceviewer.engine;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * PlainText Scroll Reader class
+ * 
+ */
+public class PlainTextScrollReader extends BaseDataReader implements
+		DataScrollReader {
+
+	/**
+	 * Running boolean
+	 */
+	private boolean running;
+
+	/**
+	 * Number of blocks to process when reader is block-reader
+	 */
+	private int numberOfBlocks = 1;
+
+	/**
+	 * Starting offset when reader is block-reader
+	 */
+	private int startReadingTracesFrom;
+
+	/**
+	 * Number of traces read when reader is block-reader
+	 */
+	private int numberOfTracesRead;
+
+	/**
+	 * Indicates that not all traces can be fit in one buffer
+	 */
+	private boolean tracesDontFitInBuffer;
+
+	/**
+	 * Is this reader blocking
+	 */
+	private boolean blocking;
+
+	/**
+	 * Possible middle of line break
+	 */
+	private boolean middleOfLineBreak;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param mediaCallback
+	 *            callback
+	 * @param configuration
+	 *            trace configuration used in this reader
+	 */
+	public PlainTextScrollReader(MediaCallback mediaCallback,
+			TraceConfiguration configuration) {
+		filePath = TraceViewerGlobals.getTraceViewer().getDataReaderAccess()
+				.getCurrentDataReader().getFilePath();
+		createFileChannel();
+		this.mediaCallback = mediaCallback;
+		trace = new TraceProperties(configuration);
+		traceConfiguration = configuration;
+
+		receiveBuffer = ByteBuffer.allocateDirect(RECEIVE_BUFFER_SIZE);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Thread#run()
+	 */
+	@Override
+	public synchronized void run() {
+		try {
+			running = true;
+			receiveBuffer.position(0);
+			while (running) {
+
+				// Set buffer limit
+				if (!tracesDontFitInBuffer) {
+					tracesDontFitInBuffer = setBufferLimit();
+				}
+
+				// Reads data to buffer. ReceiveBuffer position is always zero
+				// here so readBytes will read until the limit or to the end of
+				// file
+				int readBytes = readFile.getChannel().read(receiveBuffer);
+				if (readBytes <= 0) {
+					putToSleep();
+					// If data is found, process buffer
+				} else {
+					// If file is at end, set limit according
+					if (readBytes < receiveBuffer.limit()) {
+						receiveBuffer.limit(readBytes);
+					}
+					// Start processing
+					processBuffer();
+				}
+			}
+		} catch (Throwable t) {
+			t.printStackTrace();
+		}
+	}
+
+	/**
+	 * Sets buffer limit
+	 * 
+	 * @return true if traces fitted into the buffer
+	 * @throws IOException
+	 */
+	private boolean setBufferLimit() throws IOException {
+		boolean tracesDontFitInBuffer = false;
+		FileMap fileMap = TraceViewerGlobals.getTraceViewer()
+				.getDataReaderAccess().getCurrentDataReader().getFileMap();
+		int index = startReadingTracesFrom / TraceViewerGlobals.blockSize;
+
+		// Filemap must have the offset for end trace
+		if (fileMap.size() > index + numberOfBlocks) {
+
+			// Get positions and the difference
+			long pos = readFile.getFilePointer();
+			long pos2 = fileMap.getItem(index + numberOfBlocks).longValue();
+			long limit = pos2 - pos;
+
+			// If difference is smaller than capacity, set as limit
+			if (limit < receiveBuffer.capacity()) {
+				receiveBuffer.limit((int) limit);
+			} else {
+				receiveBuffer.limit(receiveBuffer.capacity());
+				tracesDontFitInBuffer = true;
+			}
+		} else {
+			receiveBuffer.limit(receiveBuffer.capacity());
+			tracesDontFitInBuffer = true;
+		}
+		return tracesDontFitInBuffer;
+	}
+
+	/**
+	 * Process character buffer
+	 */
+	private void processBuffer() {
+		receiveBuffer.position(0);
+		StringBuffer buf = new StringBuffer();
+		boolean traceReady = false;
+
+		// Loop until there is characters left
+		while (receiveBuffer.hasRemaining()) {
+			byte c = receiveBuffer.get();
+
+			// If in the middle of a line break from previous buffer, skip first
+			// character
+			if (middleOfLineBreak && c == '\n' && receiveBuffer.hasRemaining()) {
+				c = receiveBuffer.get();
+			}
+			middleOfLineBreak = false;
+
+			// Check the character
+			switch ((char) c) {
+			case '\n':
+				traceReady = true;
+				break;
+			case '\r':
+				if (!receiveBuffer.hasRemaining()) {
+					middleOfLineBreak = true;
+				} else if (((char) receiveBuffer.get()) == '\n') {
+				} else {
+					receiveBuffer.position(receiveBuffer.position() - 1);
+				}
+				traceReady = true;
+				break;
+			default:
+				buf.append((char) c);
+				traceReady = false;
+			}
+
+			// Trace is ready, insert it
+			if (traceReady) {
+				String traceString = buf.toString();
+				buf.setLength(0);
+				processTrace(traceString);
+				traceReady = false;
+			}
+		}
+
+		// File at end, process last trace
+		try {
+			if (readFile.getFilePointer() >= readFile.length()) {
+				String traceString = buf.toString();
+				buf.setLength(0);
+				processTrace(traceString);
+				traceReady = false;
+			}
+
+			// If data left in buffer, move file backwards the same amount
+			else if (buf.length() > 0) {
+				setFilePosition(readFile.getFilePointer() - buf.length());
+
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		receiveBuffer.position(0);
+	}
+
+	/**
+	 * Process plain text trace line
+	 * 
+	 * @param traceString
+	 *            trace string
+	 */
+	private void processTrace(String traceString) {
+		numberOfTracesRead++;
+		trace = new TraceProperties(traceConfiguration);
+		trace.traceString = traceString;
+		trace.traceNumber = startReadingTracesFrom + numberOfTracesRead;
+
+		// Not the last trace yet
+		if (!lastTrace()) {
+			trace.lastTrace = false;
+			mediaCallback.processTrace(trace);
+
+			// Last trace
+		} else {
+			tracesDontFitInBuffer = false;
+			trace.lastTrace = true;
+			blocking = true;
+			numberOfTracesRead = 0;
+
+			mediaCallback.processTrace(trace);
+
+			putToSleep();
+		}
+	}
+
+	/**
+	 * Tells if this is the last trace
+	 * 
+	 * @return indication of if this is the last trace or not
+	 */
+	public boolean lastTrace() {
+		boolean lastTrace = false;
+
+		// 1 or 2 blocks read
+		if (numberOfTracesRead >= TraceViewerGlobals.blockSize * numberOfBlocks) {
+			lastTrace = true;
+			// Last block
+		} else if (startReadingTracesFrom + numberOfTracesRead >= TraceViewerGlobals
+				.getTraceViewer().getDataReaderAccess().getCurrentDataReader()
+				.getTraceCount()) {
+			lastTrace = true;
+		}
+		return lastTrace;
+	}
+
+	/**
+	 * Puts this thread to sleep
+	 */
+	public void putToSleep() {
+		try {
+			// Null variables if this reader is only for blocks
+			if (TraceViewerGlobals.getTraceViewer().getStateHolder()
+					.isScrolling()) {
+				numberOfTracesRead = 0;
+				receiveBuffer.limit(receiveBuffer.capacity());
+				receiveBuffer.position(receiveBuffer.capacity());
+			}
+			if (blocking) {
+				this.notifyAll();
+				this.wait();
+			}
+
+		} catch (InterruptedException e) {
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.traceviewer.engine.DataReader#shutdown()
+	 */
+	public void shutdown() {
+		running = false;
+		try {
+			sourceChannel.close();
+			readFile.close();
+		} catch (IOException e) {
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.traceviewer.engine.DataScrollReader#setBlockReader(int,
+	 * int, boolean)
+	 */
+	public void setBlockReader(int numberOfBlocks, int startingTrace,
+			boolean blocking) {
+		this.numberOfBlocks = numberOfBlocks;
+		this.startReadingTracesFrom = startingTrace;
+		this.blocking = blocking;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.traceviewer.engine.DataScrollReader#setFilePosition(long)
+	 */
+	@Override
+	public void setFilePosition(long filePos) {
+		try {
+			readFile.seek(filePos);
+
+			if (filePos == fileStartOffset) {
+				receiveBuffer.limit(receiveBuffer.capacity());
+				receiveBuffer.position(receiveBuffer.capacity());
+			}
+
+		} catch (IOException e) {
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.traceviewer.engine.DataReader#pause(boolean)
+	 */
+	public void pause(boolean pause) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.traceviewer.engine.DataReader#isPaused()
+	 */
+	public boolean isPaused() {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.traceviewer.engine.DataReader#getTracePositionInFile()
+	 */
+	public long getTracePositionInFile() {
+		return 0;
+	}
+
+	@Override
+	protected byte[] setProtocolSpecificStuffToMultiPartTrace(byte[] byteArr,
+			TraceProperties trace) {
+		// There isn't any multipart traces in plain text
+		return byteArr;
+	}
+}