crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/DataBuffer/Primer/DataBufferPrimer.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/DataBuffer/Primer/DataBufferPrimer.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,193 @@
+/*
+* 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.Collections.Generic;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.IO;
+using SymbianUtils.DataBuffer.Entry;
+
+namespace SymbianUtils.DataBuffer.Primer
+{
+    public class DataBufferPrimer
+    {
+        #region Delegates & Events
+        public delegate void DataBufferPrimerUnhandledLine( DataBufferPrimer aPrimer, DataBuffer aBuffer, string aLine );
+        public event DataBufferPrimerUnhandledLine LineNotHandled;
+
+        public delegate void DataBufferPrimerCompleteHandler( DataBufferPrimer aPrimer, DataBuffer aBuffer, uint aFirstByteAddress, uint aLastByteAddress );
+        public event DataBufferPrimerCompleteHandler PrimerComplete;
+        #endregion
+
+        #region Constructors
+        public DataBufferPrimer( DataBuffer aBuffer )
+        {
+            iDataBuffer = aBuffer;
+        }
+        #endregion
+
+        #region API
+        public void Prime( IEnumerable<string> aLines )
+        {
+            iDataBuffer.Clear();
+            //
+            foreach ( string line in aLines )
+            {
+                PrimeLine( line );
+            }
+
+            Primed = true;
+        }
+
+        public void PrimeLine( string aLine )
+        {
+            Match m = iRawDataRegEx.Match( aLine );
+            //
+            if ( m.Success )
+            {
+                uint startOfLineAddress = ExtractDataSourceEntryFromMatch( m );
+                
+                // If the data buffer has never had an address applied to it, then set it now
+                if ( iHaveSetFirstAddress == false )
+                {
+                    iDataBuffer.AddressOffset = startOfLineAddress;
+                    iHaveSetFirstAddress = true;
+                }
+            }
+            else if ( LineNotHandled != null )
+            {
+                LineNotHandled( this, iDataBuffer, aLine );
+            }
+        }
+
+        public void Prime( string aBinaryFileName )
+        {
+            Prime( aBinaryFileName, 0 );
+        }
+
+        public void Prime( string aBinaryFileName, uint aAddressOfFirstByte )
+        {
+            FileInfo info = new FileInfo( aBinaryFileName );
+            if ( info.Exists )
+            {
+                int length = (int) info.Length;
+                //
+                byte[] bytes = new byte[ length ];
+                using ( FileStream stream = new FileStream( aBinaryFileName, FileMode.Open, FileAccess.Read, FileShare.Read ) )
+                {
+                    stream.Read( bytes, 0, length );
+                }
+                //
+                Prime( bytes, aAddressOfFirstByte );
+            }
+        }
+
+        public void Prime( IEnumerable<byte> aBytes, uint aAddressOfFirstByte )
+        {
+            iDataBuffer.Clear();
+
+            // Set the starting address
+            iDataBuffer.AddressOffset = aAddressOfFirstByte;
+
+            // Read bytes
+            uint offset = 0;
+            foreach ( byte b in aBytes )
+            {
+                DataBufferByte entry = new DataBufferByte( b, offset++ );
+                iDataBuffer.Add( entry );
+            }
+
+            Primed = true;
+        }
+
+        public void Prime( DataBuffer aBuffer )
+        {
+            iDataBuffer.Clear();
+            iDataBuffer.Set( aBuffer );
+            Primed = true;
+        }
+        #endregion
+
+        #region Properties
+        public bool Primed
+        {
+            get { return iPrimed; }
+            private set
+            {
+                iPrimed = value;
+                if ( Primed )
+                {
+                    uint firstByte = ( iDataBuffer.Count > 0 ) ? iDataBuffer.First.Address : 0;
+                    uint lastByte = ( iDataBuffer.Count > 0 ) ? iDataBuffer.Last.Address : 0;
+                    //
+                    if ( PrimerComplete != null )
+                    {
+                        PrimerComplete( this, iDataBuffer, firstByte, lastByte );
+                    }
+                }
+            }
+        }
+        #endregion
+
+        #region Internal methods
+        private uint ExtractDataSourceEntryFromMatch( Match aMatch )
+        {
+            System.Diagnostics.Debug.Assert( aMatch.Success );
+
+            uint address = 0;
+            uint nextExpectedAddress = 0;
+            if ( iDataBuffer.Count > 0 )
+            {
+                nextExpectedAddress = iDataBuffer.Last.Address + 1;
+            }
+            //
+            GroupCollection groups = aMatch.Groups;
+            CaptureCollection data = groups[ "Data" ].Captures;
+
+            if ( data.Count > 0 )
+            {
+                address = System.Convert.ToUInt32( groups[ "Address" ].Value, 16 );
+
+                // Validate the address
+                if ( nextExpectedAddress != 0 && address != nextExpectedAddress )
+                {
+                    throw new Exception( string.Format( "Data is corrupt - expected: 0x{0:x8}, actual: 0x{1:x8}", nextExpectedAddress, address ) );
+                }
+                else
+                {
+                    foreach ( Capture capture in data )
+                    {
+                        string val = capture.Value.Trim();
+                        byte b = System.Convert.ToByte( val, 16 );
+                        DataBufferByte entry = new DataBufferByte( b, (uint) iDataBuffer.Count );
+                        iDataBuffer.Add( entry );
+                    }
+                }
+            }
+
+            return address;
+        }
+        #endregion
+
+        #region Data members
+        private static readonly Regex iRawDataRegEx = new Regex( "(?:.*)\r\n(?<Address>[a-fA-F0-9]{8})\r\n\\:\\s{1}\r\n(?<Data>(?:[a-fA-F0-9]{2})\\s{1}){1,16}\r\n(?:.*)", RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled );
+        private readonly DataBuffer iDataBuffer;
+        private bool iPrimed = false;
+        private bool iHaveSetFirstAddress = false;
+        #endregion
+    }
+}