trace/traceviewer/com.nokia.traceviewer.ost/src/com/nokia/traceviewer/ost/OstScrollReader.java
changeset 11 5b9d4d8641ce
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trace/traceviewer/com.nokia.traceviewer.ost/src/com/nokia/traceviewer/ost/OstScrollReader.java	Wed Jun 23 14:49:59 2010 +0300
@@ -0,0 +1,346 @@
+/*
+ * 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:
+ *
+ * OST ScrollReader class
+ *
+ */
+package com.nokia.traceviewer.ost;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import com.nokia.traceviewer.engine.DataScrollReader;
+import com.nokia.traceviewer.engine.MediaCallback;
+import com.nokia.traceviewer.engine.TraceConfiguration;
+import com.nokia.traceviewer.engine.TraceProperties;
+import com.nokia.traceviewer.engine.TraceViewerGlobals;
+
+/**
+ * OST ScrollReader class
+ */
+public class OstScrollReader extends OstBaseReader implements DataScrollReader,
+		OstMessageCallback {
+
+	/**
+	 * 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;
+
+	/**
+	 * Number of bytes received
+	 */
+	private int bytesRead;
+
+	/**
+	 * Number of bytes in previous message
+	 */
+	private int previousMessageBytes;
+
+	/**
+	 * Is this reader blocking
+	 */
+	private boolean blocking;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param mediaCallback
+	 *            callback
+	 * @param configuration
+	 *            Trace Configuration
+	 */
+	public OstScrollReader(MediaCallback mediaCallback,
+			TraceConfiguration configuration) {
+		// OstBaseReader constructor
+		super();
+
+		filePath = TraceViewerGlobals.getTraceViewer().getDataReaderAccess()
+				.getCurrentDataReader().getFilePath();
+		createFileChannel();
+
+		this.mediaCallback = mediaCallback;
+		receiveBuffer = ByteBuffer.allocateDirect(RECEIVE_BUFFER_SIZE);
+		messageProcessor = new OstMessageProcessor(this, receiveBuffer);
+		traceConfiguration = configuration;
+		trace = new TraceProperties(configuration);
+		trace.byteBuffer = receiveBuffer;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Thread#run()
+	 */
+	@Override
+	public synchronized void run() {
+		try {
+			running = true;
+			receiveBuffer.position(0);
+			while (running) {
+				// Get bytes in buffer before read operation
+				if (receiveBuffer.position() != 0) {
+					previousMessageBytes = receiveBuffer.position();
+				} else {
+					previousMessageBytes = 0;
+				}
+
+				// Reads data to buffer
+				bytesRead = sourceChannel.read(receiveBuffer);
+				if (bytesRead > 0) {
+
+					// If data is found, the processor is used to split
+					// thedata into OST messages. processMessage is
+					// called for each message found from the buffer and
+					// the buffer is re-positioned for next read
+					// operation
+					messageProcessor.processBuffer();
+				} else {
+					putToSleep();
+				}
+			}
+		} catch (Throwable t) {
+			t.printStackTrace();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.traceviewer.ost.OstMessageCallback#processMessage(int,
+	 * int, int)
+	 */
+	public boolean processMessage(int msgStart, int msgLen, int headerLen,
+			int headerVersion) throws IOException {
+		boolean valid = true;
+		boolean returnValue = true;
+		int protocolId = 0;
+
+		// Create new TraceProperties
+		trace = new TraceProperties(traceConfiguration);
+
+		// Save buffer and message and data offsets
+		trace.byteBuffer = receiveBuffer;
+		trace.messageStart = msgStart;
+		trace.messageLength = msgLen;
+
+		// Get protocol ID offset
+		int protocolIdOffset = 0;
+		if (headerVersion == OST_V01) {
+			protocolIdOffset = OST_V01_PROTOCOLID_OFFSET;
+		} else if (headerVersion == OST_V05) {
+			protocolIdOffset = OST_V05_PROTOCOLID_OFFSET;
+		} else if (headerVersion == OST_V10) {
+			protocolIdOffset = OST_V10_PROTOCOLID_OFFSET;
+		} else if (headerVersion == OST_V00) {
+			protocolIdOffset = OST_V00_PROTOCOLID_OFFSET;
+		} else {
+			// Unsupported header version
+			System.out.println("Unsupported header version: " + headerVersion); //$NON-NLS-1$
+		}
+
+		// Read protocol ID
+		protocolId |= receiveBuffer.get(msgStart + protocolIdOffset)
+				& BYTE_MASK;
+
+		// OST Ascii Trace (0x02)
+		if (protocolId == OST_ASCII_TRACE_ID && msgLen >= headerLen) {
+
+			// Get the timestamp
+			trace.timestamp = messageProcessor.parseTimeStampToNanosecs(
+					msgStart, headerLen + OST_ASCII_TRACE_TIMESTAMP_OFFSET);
+
+			// Process the trace
+			processOstAsciiTrace(msgStart, msgLen, headerLen);
+
+			// OST Simple Application Trace Protocol (0x03)
+		} else if (protocolId == OST_SIMPLE_TRACE_ID) {
+
+			// Get the timestamp
+			trace.timestamp = messageProcessor.parseTimeStampToNanosecs(
+					msgStart, headerLen + OST_SIMPLE_TRACE_TIMESTAMP_OFFSET);
+
+			// Process the trace
+			valid = processOstSimpleTrace(msgStart, headerLen);
+
+			// Unknown protocol ID
+		} else {
+			trace.binaryTrace = true;
+			valid = false;
+		}
+
+		// Trace is valid
+		if (valid) {
+			returnValue = processScrolledTrace(msgStart, msgLen, returnValue);
+
+		}
+		return returnValue;
+	}
+
+	/**
+	 * Processes scrolled trace
+	 * 
+	 * @param msgStart
+	 *            message start offset
+	 * @param msgLen
+	 *            message length
+	 * @param returnValue
+	 *            implication of success of processing trace
+	 * @return implication of success of processing trace
+	 * @throws IOException
+	 */
+	public boolean processScrolledTrace(int msgStart, int msgLen,
+			boolean returnValue) throws IOException {
+
+		// In case of multi part trace, set trace properties now so
+		// that DataProcessor can use it properly
+		if (trace.bTraceInformation.getMultiPart() != 0) {
+			int initialHeaderSize = trace.dataStart - trace.messageStart;
+			trace.messageStart = 0;
+			trace.messageLength = trace.byteBuffer.capacity();
+			trace.dataStart = initialHeaderSize;
+			trace.dataLength = trace.messageLength - initialHeaderSize;
+		}
+
+		numberOfTracesRead++;
+		trace.traceNumber = startReadingTracesFrom + numberOfTracesRead;
+
+		// Not processed full block of traces yet, keep processing
+		if (!lastTrace(msgStart, msgLen)) {
+
+			trace.lastTrace = false;
+			mediaCallback.processTrace(trace);
+
+			// Last trace
+		} else {
+			trace.lastTrace = true;
+			blocking = true;
+			numberOfTracesRead = 0;
+			mediaCallback.processTrace(trace);
+
+			putToSleep();
+			returnValue = false;
+		}
+		return returnValue;
+	}
+
+	/**
+	 * Tells if this trace is the last one to process
+	 * 
+	 * @param msgStart
+	 *            message start offset
+	 * @param msgLen
+	 *            message length
+	 * @return true if this is the last trace
+	 * @throws IOException
+	 */
+	public boolean lastTrace(int msgStart, int msgLen) throws IOException {
+		return sourceChannelPosition(msgStart, msgLen) >= sourceChannel.size()
+				|| lastTraceToShow() || isBlockSizeRead();
+	}
+
+	/**
+	 * Checks if we are now read the whole block what we want
+	 * 
+	 * @return true if block is fully read
+	 */
+	private boolean isBlockSizeRead() {
+		boolean isBlockRead = false;
+		if (numberOfTracesRead == TraceViewerGlobals.blockSize * numberOfBlocks) {
+			isBlockRead = true;
+		}
+		return isBlockRead;
+	}
+
+	/**
+	 * Tells if this is the last trace we want to show during pause because
+	 * there propably is more traces in the file
+	 * 
+	 * @return true if this is the last trace to show during pause
+	 */
+	public boolean lastTraceToShow() {
+		boolean lastTraceToShow = (startReadingTracesFrom + numberOfTracesRead
+				+ 1 > TraceViewerGlobals.getTraceViewer().getDataReaderAccess()
+				.getCurrentDataReader().getTraceCount());
+
+		return lastTraceToShow;
+	}
+
+	/**
+	 * Gets position of source channel after this trace
+	 * 
+	 * @param msgStart
+	 *            message start offset
+	 * @param msgLen
+	 *            message length
+	 * @return source channel position after this trace
+	 * @throws IOException
+	 */
+	public long sourceChannelPosition(int msgStart, int msgLen)
+			throws IOException {
+		return sourceChannel.position() - bytesRead + msgStart + msgLen
+				- previousMessageBytes;
+	}
+
+	/**
+	 * Puts this thread to sleep
+	 */
+	public void putToSleep() {
+		try {
+			// Null variables if this reader is only for blocks
+			if (TraceViewerGlobals.getTraceViewer().getStateHolder()
+					.isScrolling()) {
+				receiveBuffer.position(receiveBuffer.capacity());
+				numberOfTracesRead = 0;
+			}
+			if (blocking) {
+				this.notifyAll();
+				this.wait();
+			}
+		} catch (InterruptedException 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.DataReader#getTracePositionInFile()
+	 */
+	public long getTracePositionInFile() {
+		return 0;
+	}
+}