diff -r ed1c9f64298a -r 5b9d4d8641ce trace/traceviewer/com.nokia.traceviewer/src/com/nokia/traceviewer/engine/PlainTextScrollReader.java --- /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; + } +}