crashanalysercmd/Libraries/Engine/CrashItemLib/PluginAPI/FW/CFFReader.cs
changeset 0 818e61de6cd1
--- /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
+        /// <summary>
+        /// Called when Crash Analyser wants this plugin to read a
+        /// native, i.e. format-specific crash file (i.e. not a trace file) 
+        /// synchronously.
+        /// </summary>
+        public virtual void NativeReadInit()
+        {
+        }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        public virtual void TraceReadInit()
+        {
+        }
+
+        /// <summary>
+        /// Receive an individual trace line and process it if relevant
+        /// </summary>
+        /// <param name="aLine"></param>
+        public virtual bool TraceReadOffer( CFFTraceLine aLine )
+        {
+            // Nothing to do
+            return false;
+        }
+
+        /// <summary>
+        /// Called when all trace lines have been delivered
+        /// </summary>
+        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
+	}
+}