diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/Libraries/Engine/CrashItemLib/PluginAPI/FW/CFFReader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/Libraries/Engine/CrashItemLib/PluginAPI/FW/CFFReader.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,311 @@ +/* +* Copyright (c) 2009 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: +* +*/ +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; +using SymbianUtils; +using SymbianDebugLib.Engine; +using CrashItemLib.Crash; +using CrashItemLib.Engine; + +namespace CrashItemLib.PluginAPI +{ + public abstract class CFFReader + { + #region Enumerations + public enum TState + { + EStateUninitialised = 0, + EStateProcessing, + EStateReady, + EStateCorrupt + } + #endregion + + #region Delegates & events + public enum TEvent + { + EReadingStarted = 0, + EReadingProgress, + EReadingContainerCreated, + EReadingComplete, + } + + public delegate void ReaderObserver( TEvent aEvent, CFFReader aReader, object aContext ); + public event ReaderObserver Observer; + + public delegate void ReaderExceptionHandler( Exception aException, CFFReader aReader ); + public event ReaderExceptionHandler ExceptionHandler; + #endregion + + #region Constructors + protected CFFReader( CFFPlugin aEngine, CFFSource aDescriptor ) + { + iPlugin = aEngine; + iDescriptor = aDescriptor; + } + #endregion + + #region API - abstract + /// + /// Called when Crash Analyser wants this plugin to read a + /// native, i.e. format-specific crash file (i.e. not a trace file) + /// synchronously. + /// + public virtual void NativeReadInit() + { + } + + /// + /// Called when Crash Analyser is going to start to send + /// trace lines (that it will read on behalf of the plugin) + /// that should be processed in order to identify embedded + /// traces. + /// + /// This method will only be called if the plugin claims to have + /// some confidence in reading trace data. + /// + public virtual void TraceReadInit() + { + } + + /// + /// Receive an individual trace line and process it if relevant + /// + /// + public virtual bool TraceReadOffer( CFFTraceLine aLine ) + { + // Nothing to do + return false; + } + + /// + /// Called when all trace lines have been delivered + /// + public virtual void TraceReadComplete() + { + } + #endregion + + #region API - framework + protected byte[] RawData + { + get { return Descriptor.RawData; } + } + + protected void RawDataAdd() + { + // Save entire file + RawDataClear(); + RawDataAdd( Descriptor.MasterFile ); + } + + protected void RawDataAdd( FileInfo aFile ) + { + byte[] bytes = File.ReadAllBytes( aFile.FullName ); + RawDataAdd( bytes ); + } + + protected void RawDataClear() + { + Descriptor.RawDataClear(); + } + + protected void RawDataAdd( byte[] aRawData ) + { + Descriptor.RawDataAdd( aRawData ); + } + #endregion + + #region Properties + public TState State + { + get + { + lock ( this ) + { + return iState; + } + } + set + { + lock ( this ) + { + iState = value; + } + } + } + + public CFFPlugin Plugin + { + get { return iPlugin; } + } + + public CFFSource Descriptor + { + get { return iDescriptor; } + } + + public CIEngine CIEngine + { + get { return Plugin.DataProvider.Engine; } + } + #endregion + + #region Internal methods + protected void NotifyEvent( TEvent aEvent ) + { + NotifyEvent( aEvent, null ); + } + + protected void NotifyEvent( TEvent aEvent, object aContext ) + { + // We must notify about "reading started" and "reading complete" only + // once. + // + // When the plugin sends the "reading started" event, we must transition + // to 'EStateProcessing.' + // + // When the plugin sends the "reading complete" event, we must transition + // to 'EStateReady' except if there was an exception during processing, + // in which case we remain as 'EStateCorrupt.' + // + // NB: NotifyException makes the transition to EStateCorrupt. + // + TState oldState = State; + // + bool notify = false; + switch ( aEvent ) + { + case TEvent.EReadingContainerCreated: + notify = true; + break; + case TEvent.EReadingStarted: + State = TState.EStateProcessing; + notify = ( State != oldState ); + break; + case TEvent.EReadingProgress: + notify = true; + break; + case TEvent.EReadingComplete: + if ( State == TState.EStateCorrupt ) + { + // There was an exception during processing. Do not + // change to 'ready' state in this situation. + // + // However, we must still notify about the completion event! + notify = true; + } + else + { + State = TState.EStateReady; + notify = ( State != oldState ); + } + break; + default: + throw new NotSupportedException(); + } + + if ( notify ) + { + if ( Observer != null ) + { + Observer( aEvent, this, aContext ); + } + } + } + + protected void NotifyException( Exception aException ) + { + State = TState.EStateCorrupt; + // + if ( ExceptionHandler != null ) + { + ExceptionHandler( aException, this ); + } + } + #endregion + + #region Internal methods - called by CIEngineSource to carry out operations + internal void OnNativeReadInit() + { + // Indicate reading started + NotifyEvent( TEvent.EReadingStarted ); + try + { + NativeReadInit(); + } + catch ( Exception e ) + { + NotifyException( e ); + NotifyEvent( TEvent.EReadingComplete ); + } + } + + internal void OnTraceReadInit() + { + // Indicate reading started + NotifyEvent( TEvent.EReadingStarted ); + try + { + TraceReadInit(); + } + catch ( Exception e ) + { + NotifyException( e ); + NotifyEvent( TEvent.EReadingComplete ); + } + } + + internal void OnTraceReadOffer( CFFTraceLine aLine ) + { + try + { + bool consumed = TraceReadOffer( aLine ); + if ( consumed ) + { + RawDataAdd( aLine.ToBinary() ); + } + } + catch ( Exception e ) + { + NotifyException( e ); + } + } + + internal void OnTraceReadComplete() + { + try + { + TraceReadComplete(); + } + catch ( Exception e ) + { + NotifyException( e ); + NotifyEvent( TEvent.EReadingComplete ); + } + } + #endregion + + #region Data members + private TState iState = TState.EStateUninitialised; + private readonly CFFPlugin iPlugin; + private readonly CFFSource iDescriptor; + #endregion + } +}