crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianImageLib/ROM/Content/SIContentROM.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianImageLib/ROM/Content/SIContentROM.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,248 @@
+/*
+* 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.IO;
+using SymbianUtils;
+using SymbianUtils.Tracer;
+using SymbianUtils.Streams;
+using SymbianStructuresLib.Uids;
+using SymbianStructuresLib.Compression.Common;
+using SymbianImageLib.Common.Content;
+using SymbianImageLib.Common.Image;
+using SymbianImageLib.Common.Header;
+using SymbianImageLib.Common.Streams;
+using SymbianImageLib.Common.Factory;
+using SymbianImageLib.ROM.Image;
+using SymbianImageLib.ROM.Header;
+using SymbianImageLib.ROM.Structures;
+
+namespace SymbianImageLib.ROM.Content
+{
+    internal class SIContentROM : SIContent
+    {
+        #region Constructors
+        public SIContentROM( SIROM aImage )
+            : base( aImage )
+        {
+            SIHeaderROM header = (SIHeaderROM) aImage.Header;
+            base.RelocationAddress = header.RomBaseAddress;
+        }
+        #endregion
+
+        #region From SymbianImageContentFile
+        public override TSymbianCompressionType CompressionType
+        {
+            get
+            {
+                // Compression type comes from overall image header
+                TSymbianCompressionType ret = base.ImageHeader.CompressionType;
+                return ret;
+            }
+        }
+
+        public override bool IsRelocationSupported
+        {
+            get { return false; }
+        }
+
+        public override string FileName
+        {
+            get { return Image.Name; }
+        }
+
+        public override uint FileSize
+        {
+            get { return (uint) base.Image.Stream.Length; }
+        }
+
+        public override uint ContentSize
+        {
+            get
+            {
+                // This is not 100% accurate, but hopefully good enough...
+                uint size = (uint) base.ImageStream.Length;
+                return size;
+            }
+        }
+
+        public override byte[] GetAllData()
+        {
+            // The image ownes a memory stream (if the image has been decompressed)
+            byte[] ret = new byte[ 0 ];
+            //
+            if ( base.ImageStream is SIMemoryStream )
+            {
+                SIMemoryStream memStream = (SIMemoryStream) base.ImageStream;
+                ret = memStream.Data;
+            }
+            //
+            return ret;
+        }
+
+        protected override uint DoProvideDataUInt32( uint aTranslatedAddress )
+        {
+            using ( SymbianStreamReaderLE reader = Image.Stream.CreateReader( SymbianStreamReaderLE.TCloseOperation.ENone ) )
+            {
+                reader.Seek( aTranslatedAddress );
+                uint ret = reader.ReadUInt32();
+                return ret;
+            }
+        }
+
+        protected override ushort DoProvideDataUInt16( uint aTranslatedAddress )
+        {
+            using ( SymbianStreamReaderLE reader = Image.Stream.CreateReader( SymbianStreamReaderLE.TCloseOperation.ENone ) )
+            {
+                reader.Seek( aTranslatedAddress );
+                ushort ret = reader.ReadUInt16();
+                return ret;
+            }
+        }
+
+        protected override void DoDecompress()
+        {
+            base.Trace( "[SymbianImageContentFileROM] DoDecompress() - START - compression type: {0}", CompressionType );
+            //
+            switch ( CompressionType )
+            {
+            case TSymbianCompressionType.ENone:
+                base.Trace( "[SymbianImageContentFileROM] DoDecompress() - not compressed" );
+                break;
+            case TSymbianCompressionType.EBytePair:
+                base.Trace( "[SymbianImageContentFileROM] DoDecompress() - byte pair" );
+                DoDecompressBytePair();
+                break;
+            default:
+            case TSymbianCompressionType.EDeflate:
+                base.Trace( "[SymbianImageContentFileROM] DoDecompress() - unsuporrted compression type" );
+                throw new NotSupportedException();
+            }
+            //
+            base.Trace( "[SymbianImageROM] DoDecompress() - END" );
+        }
+
+        protected override bool GetIsContentPrepared()
+        {
+            return iContentIsPrepared;
+        }
+        #endregion
+
+        #region Properties
+        public new SIHeaderROM ImageHeader
+        {
+            get
+            {
+                SIHeaderROM header = (SIHeaderROM) base.ImageHeader;
+                return header;
+            }
+        }
+        #endregion
+
+        #region Internal methods
+        private void DoDecompressBytePair()
+        {
+            if ( iContentIsPrepared == false )
+            {
+                SIHeaderROM imageHeader = ImageHeader;
+                base.Trace( "[SymbianImageROM] DoDecompressBytePair() - START - header uncompressed rom size: {0}", imageHeader.UncompressedRomSize );
+
+                // Create new buffer and copy over rom image header
+                SIMemoryStream resultantDataStream = new SIMemoryStream( imageHeader.UncompressedRomSize );
+
+                int numPages = imageHeader.NumberOfPages;
+                uint pageTableOffset = imageHeader.RomPageIndexOffset;
+                uint romDataOffset = imageHeader.HeaderSizeLoader;
+                base.Trace( "[SymbianImageROM] DoDecompressBytePair() - numPages: {0}, pageTableOffset: {1}, romDataOffset: {2}", numPages, pageTableOffset, romDataOffset );
+                //
+                SymbianDecompressor decompressor = SymbianDecompressor.NewByType( TSymbianCompressionType.EBytePair );
+                //
+                List<SRomPageInfo> pages = new List<SRomPageInfo>( numPages + 1 );
+                for ( int i = 0; i < numPages; i++ )
+                {
+                    // Read a page table entry
+                    long pageOffsetWithinFile = pageTableOffset + ( i * SRomPageInfo.Size );
+
+                    //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - pageOffsetWithinFile: {1}", i, pageOffsetWithinFile );
+                    base.ImageStream.Seek( pageOffsetWithinFile, SeekOrigin.Begin );
+                    SRomPageInfo pageInfo = SRomPageInfo.New( (Stream) base.ImageStream, romDataOffset );
+
+                    // Process the entry based upon the compression type
+                    //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - pageInfo.DataSize: {1}, pageInfo.DataStart: {2}, pageInfo.CompressionType: {3}", i, pageInfo.DataSize, pageInfo.DataStart, pageInfo.CompressionType );
+                    base.ImageStream.Seek( pageInfo.DataStart, SeekOrigin.Begin );
+
+                    if ( pageInfo.CompressionType == SRomPageInfo.TSymbianCompressionType.ENoCompression )
+                    {
+                        // Read data - no decompression needed
+                        //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - PAGE NOT COMPRESSED", i );
+                        resultantDataStream.Write( base.ImageStream, (int) pageInfo.DataSize );
+                    }
+                    else if ( pageInfo.CompressionType == SRomPageInfo.TSymbianCompressionType.EBytePair )
+                    {
+                        //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - BYTE PAIR PAGE", i );
+
+                        // Read data - need to decompress it
+                        byte[] compressedData = new byte[ pageInfo.DataSize ];
+                        base.ImageStream.Read( compressedData, 0, compressedData.Length );
+
+                        // Make destination buffer - which is a page big
+                        byte[] uncompressedData = new byte[ SRomPageInfo.KPageSize ];
+
+                        // Decompress to buffer - we're handling the page management, so we want raw decompression
+                        int error = decompressor.DecompressRaw( compressedData, uncompressedData );
+
+                        // Save it
+                        if ( error < 0 )
+                        {
+                            base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - Exception - bytepair decompression error", i );
+                            throw new Exception( "BytePair decompression error: " + error.ToString() );
+                        }
+                        else if ( error != SRomPageInfo.KPageSize )
+                        {
+                            base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - Exception - bytepair underflow error", i );
+                            throw new Exception( "Decompressor underflow - only created " + error.ToString() + " bytes" );
+                        }
+                        else
+                        {
+                            resultantDataStream.Write( uncompressedData );
+                        }
+                    }
+                    else
+                    {
+                        base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - UNSUPPORTED COMPRESSION TYPE - Exception!", i );
+                        throw new NotSupportedException( "Unsupported page compression type" );
+                    }
+
+                    // Report progress
+                    base.ReportDecompressionEvent( TDecompressionEvent.EEventDecompressionProgress, ( (float) i / (float) numPages ) * 100 );
+                }
+
+                // Now we can replace the base class stream (which is just the raw compressed file data) with the new uncompressed version
+                base.ImageStream = resultantDataStream;
+                iContentIsPrepared = true;
+
+                base.Trace( "[SymbianImageROM] DoDecompressBytePair() - END" );
+            }
+        }
+        #endregion
+
+        #region Data members
+        private bool iContentIsPrepared = false;
+        #endregion
+    }
+}