diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/DataBuffer/DataBuffer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/DataBuffer/DataBuffer.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,316 @@ +/* +* 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 System.Text.RegularExpressions; +using SymbianUtils.DataBuffer.Entry; +using SymbianUtils.Range; + +namespace SymbianUtils.DataBuffer +{ + public class DataBuffer : IEnumerable + { + #region Constructors + public DataBuffer() + { + } + #endregion + + #region API + public void Add( byte aByte ) + { + uint address = 0; + // + if ( Count > 0 ) + { + address = ( Last.Address - AddressOffset ) + 1; + } + // + DataBufferByte entry = new DataBufferByte( aByte, address ); + Add( entry ); + } + + public void Add( IEnumerable aBytes ) + { + foreach ( byte b in aBytes ) + { + Add( b ); + } + } + + public void Add( uint aDWord ) + { + // Make 4 bytes + byte b0 = (byte) (( aDWord & 0x000000FF ) >> 00); + byte b1 = (byte) (( aDWord & 0x0000FF00 ) >> 08); + byte b2 = (byte) (( aDWord & 0x00FF0000 ) >> 16); + byte b3 = (byte) (( aDWord & 0xFF000000 ) >> 24); + // + Add( b0 ); + Add( b1 ); + Add( b2 ); + Add( b3 ); + } + + public void Add( DataBufferByte aEntry ) + { + aEntry.Buffer = this; + iData.Add( aEntry ); + } + + public void Set( DataBuffer aCopyFrom ) + { + iAddressOffset = aCopyFrom.AddressOffset; + iData = aCopyFrom.iData; + } + + public void Save( Stream aStream ) + { + byte[] bytes = this; + aStream.Write( bytes, 0, bytes.Length ); + } + + public void Read( Stream aStream ) + { + } + + public void Read( Stream aStream, int aOffset, int aLength ) + { + byte[] bytes = new byte[ aLength ]; + aStream.Seek( aOffset, SeekOrigin.Begin ); + aStream.Read( bytes, 0, bytes.Length ); + Add( bytes ); + } + + public void Clear() + { + iData.Clear(); + iAddressOffset = 0; + } + + public byte[] ToArray() + { + List ret = new List( iData.Count + 1 ); + // + int count = iData.Count; + for ( int i = 0; i < count; i++ ) + { + ret.Add( iData[ i ].Byte ); + } + // + return ret.ToArray(); + } + #endregion + + #region Properties + public int Count + { + get { return iData.Count; } + } + + public uint AddressOffset + { + get { return iAddressOffset; } + set { iAddressOffset = value; } + } + + public DataBufferByte First + { + get + { + DataBufferByte ret = new DataBufferByte( 0, 0 ); + // + if ( Count > 0 ) + { + ret = iData[ 0 ]; + } + // + return ret; + } + } + + public DataBufferByte Last + { + get + { + DataBufferByte ret = new DataBufferByte( 0, 0 ); + // + if ( Count > 0 ) + { + ret = iData[ Count - 1 ]; + } + // + return ret; + } + } + + public AddressRange Range + { + get + { + AddressRange ret = new AddressRange(); + if ( First != null ) + { + ret.Min = First.Address; + } + if ( Last != null ) + { + ret.Max = Last.Address; + } + return ret; + } + } + + public DataBufferUint this[ uint aAddress ] + { + get + { + DataBufferUint ret = new DataBufferUint( 0, aAddress ); + // + foreach ( DataBufferUint uintEntry in GetUintEnumerator() ) + { + if ( uintEntry.Address == aAddress ) + { + ret = uintEntry; + break; + } + } + // + return ret; + } + } + #endregion + + #region Enumerator API + public IEnumerable GetUintEnumerator() + { + // This iterator works from the bottom of the stack + // upwards, just like Symbian OS/ARM stack allocation + // + // + // Count = 12 + // + // [0123][4567][89AB] + // + int count = iData.Count; + // + for ( int i = count - 4; i >= 0; i -= 4 ) + { + DataBufferByte e0 = iData[ i + 0 ]; + DataBufferByte e1 = iData[ i + 1 ]; + DataBufferByte e2 = iData[ i + 2 ]; + DataBufferByte e3 = iData[ i + 3 ]; + // + uint value = Combine( e0, e1, e2, e3 ); + DataBufferUint ret = new DataBufferUint( value, e0.Address ); + yield return ret; + } + } + + public IEnumerable GetByteEnumerator() + { + int count = iData.Count; + for ( int i = count - 1; i >= 0; i-- ) + { + DataBufferByte entry = iData[ i ]; + yield return entry; + } + } + #endregion + + #region From IEnumerable + public IEnumerator GetEnumerator() + { + foreach ( DataBufferByte b in iData ) + { + yield return b.Byte; + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + foreach ( DataBufferByte b in iData ) + { + yield return b.Byte; + } + } + #endregion + + #region Operators + public static implicit operator byte[]( DataBuffer aBuffer ) + { + byte[] ret = aBuffer.ToArray(); + return ret; + } + #endregion + + #region Internal methods + private List GetRawBytes() + { + List ret = new List( iData.Count + 1 ); + // + foreach ( DataBufferByte b in iData ) + { + ret.Add( b.Byte ); + } + // + return ret; + } + + private uint Combine( params DataBufferByte[] aItems ) + { + if ( aItems.Length != 4 ) + { + throw new ArgumentException( "Expected 4 items" ); + } + // + uint ret = + ( (uint) aItems[ 0 ].Byte ) + + ( (uint) aItems[ 1 ].Byte << 8 ) + + ( (uint) aItems[ 2 ].Byte << 16 ) + + ( (uint) aItems[ 3 ].Byte << 24 ) + ; + return ret; + } + #endregion + + #region From System.Object + public override string ToString() + { + string ret = string.Empty; + // + List rawBytes = GetRawBytes(); + if ( rawBytes.Count > 0 ) + { + DataBufferByte firstByte = First; + uint startingAddress = firstByte.Address; + // + ret = SymbianUtils.Utilities.RawByteUtility.ConvertDataToText( rawBytes, true, ref startingAddress ); + } + // + return ret; + } + #endregion + + #region Data members + private uint iAddressOffset = 0; + private List iData = new List(); + #endregion + } +}