crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianImageLib/ROM/Content/SIContentROM.cs
changeset 0 818e61de6cd1
equal deleted inserted replaced
-1:000000000000 0:818e61de6cd1
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 * 
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 using System;
       
    18 using System.Collections.Generic;
       
    19 using System.Text;
       
    20 using System.IO;
       
    21 using SymbianUtils;
       
    22 using SymbianUtils.Tracer;
       
    23 using SymbianUtils.Streams;
       
    24 using SymbianStructuresLib.Uids;
       
    25 using SymbianStructuresLib.Compression.Common;
       
    26 using SymbianImageLib.Common.Content;
       
    27 using SymbianImageLib.Common.Image;
       
    28 using SymbianImageLib.Common.Header;
       
    29 using SymbianImageLib.Common.Streams;
       
    30 using SymbianImageLib.Common.Factory;
       
    31 using SymbianImageLib.ROM.Image;
       
    32 using SymbianImageLib.ROM.Header;
       
    33 using SymbianImageLib.ROM.Structures;
       
    34 
       
    35 namespace SymbianImageLib.ROM.Content
       
    36 {
       
    37     internal class SIContentROM : SIContent
       
    38     {
       
    39         #region Constructors
       
    40         public SIContentROM( SIROM aImage )
       
    41             : base( aImage )
       
    42         {
       
    43             SIHeaderROM header = (SIHeaderROM) aImage.Header;
       
    44             base.RelocationAddress = header.RomBaseAddress;
       
    45         }
       
    46         #endregion
       
    47 
       
    48         #region From SymbianImageContentFile
       
    49         public override TSymbianCompressionType CompressionType
       
    50         {
       
    51             get
       
    52             {
       
    53                 // Compression type comes from overall image header
       
    54                 TSymbianCompressionType ret = base.ImageHeader.CompressionType;
       
    55                 return ret;
       
    56             }
       
    57         }
       
    58 
       
    59         public override bool IsRelocationSupported
       
    60         {
       
    61             get { return false; }
       
    62         }
       
    63 
       
    64         public override string FileName
       
    65         {
       
    66             get { return Image.Name; }
       
    67         }
       
    68 
       
    69         public override uint FileSize
       
    70         {
       
    71             get { return (uint) base.Image.Stream.Length; }
       
    72         }
       
    73 
       
    74         public override uint ContentSize
       
    75         {
       
    76             get
       
    77             {
       
    78                 // This is not 100% accurate, but hopefully good enough...
       
    79                 uint size = (uint) base.ImageStream.Length;
       
    80                 return size;
       
    81             }
       
    82         }
       
    83 
       
    84         public override byte[] GetAllData()
       
    85         {
       
    86             // The image ownes a memory stream (if the image has been decompressed)
       
    87             byte[] ret = new byte[ 0 ];
       
    88             //
       
    89             if ( base.ImageStream is SIMemoryStream )
       
    90             {
       
    91                 SIMemoryStream memStream = (SIMemoryStream) base.ImageStream;
       
    92                 ret = memStream.Data;
       
    93             }
       
    94             //
       
    95             return ret;
       
    96         }
       
    97 
       
    98         protected override uint DoProvideDataUInt32( uint aTranslatedAddress )
       
    99         {
       
   100             using ( SymbianStreamReaderLE reader = Image.Stream.CreateReader( SymbianStreamReaderLE.TCloseOperation.ENone ) )
       
   101             {
       
   102                 reader.Seek( aTranslatedAddress );
       
   103                 uint ret = reader.ReadUInt32();
       
   104                 return ret;
       
   105             }
       
   106         }
       
   107 
       
   108         protected override ushort DoProvideDataUInt16( uint aTranslatedAddress )
       
   109         {
       
   110             using ( SymbianStreamReaderLE reader = Image.Stream.CreateReader( SymbianStreamReaderLE.TCloseOperation.ENone ) )
       
   111             {
       
   112                 reader.Seek( aTranslatedAddress );
       
   113                 ushort ret = reader.ReadUInt16();
       
   114                 return ret;
       
   115             }
       
   116         }
       
   117 
       
   118         protected override void DoDecompress()
       
   119         {
       
   120             base.Trace( "[SymbianImageContentFileROM] DoDecompress() - START - compression type: {0}", CompressionType );
       
   121             //
       
   122             switch ( CompressionType )
       
   123             {
       
   124             case TSymbianCompressionType.ENone:
       
   125                 base.Trace( "[SymbianImageContentFileROM] DoDecompress() - not compressed" );
       
   126                 break;
       
   127             case TSymbianCompressionType.EBytePair:
       
   128                 base.Trace( "[SymbianImageContentFileROM] DoDecompress() - byte pair" );
       
   129                 DoDecompressBytePair();
       
   130                 break;
       
   131             default:
       
   132             case TSymbianCompressionType.EDeflate:
       
   133                 base.Trace( "[SymbianImageContentFileROM] DoDecompress() - unsuporrted compression type" );
       
   134                 throw new NotSupportedException();
       
   135             }
       
   136             //
       
   137             base.Trace( "[SymbianImageROM] DoDecompress() - END" );
       
   138         }
       
   139 
       
   140         protected override bool GetIsContentPrepared()
       
   141         {
       
   142             return iContentIsPrepared;
       
   143         }
       
   144         #endregion
       
   145 
       
   146         #region Properties
       
   147         public new SIHeaderROM ImageHeader
       
   148         {
       
   149             get
       
   150             {
       
   151                 SIHeaderROM header = (SIHeaderROM) base.ImageHeader;
       
   152                 return header;
       
   153             }
       
   154         }
       
   155         #endregion
       
   156 
       
   157         #region Internal methods
       
   158         private void DoDecompressBytePair()
       
   159         {
       
   160             if ( iContentIsPrepared == false )
       
   161             {
       
   162                 SIHeaderROM imageHeader = ImageHeader;
       
   163                 base.Trace( "[SymbianImageROM] DoDecompressBytePair() - START - header uncompressed rom size: {0}", imageHeader.UncompressedRomSize );
       
   164 
       
   165                 // Create new buffer and copy over rom image header
       
   166                 SIMemoryStream resultantDataStream = new SIMemoryStream( imageHeader.UncompressedRomSize );
       
   167 
       
   168                 int numPages = imageHeader.NumberOfPages;
       
   169                 uint pageTableOffset = imageHeader.RomPageIndexOffset;
       
   170                 uint romDataOffset = imageHeader.HeaderSizeLoader;
       
   171                 base.Trace( "[SymbianImageROM] DoDecompressBytePair() - numPages: {0}, pageTableOffset: {1}, romDataOffset: {2}", numPages, pageTableOffset, romDataOffset );
       
   172                 //
       
   173                 SymbianDecompressor decompressor = SymbianDecompressor.NewByType( TSymbianCompressionType.EBytePair );
       
   174                 //
       
   175                 List<SRomPageInfo> pages = new List<SRomPageInfo>( numPages + 1 );
       
   176                 for ( int i = 0; i < numPages; i++ )
       
   177                 {
       
   178                     // Read a page table entry
       
   179                     long pageOffsetWithinFile = pageTableOffset + ( i * SRomPageInfo.Size );
       
   180 
       
   181                     //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - pageOffsetWithinFile: {1}", i, pageOffsetWithinFile );
       
   182                     base.ImageStream.Seek( pageOffsetWithinFile, SeekOrigin.Begin );
       
   183                     SRomPageInfo pageInfo = SRomPageInfo.New( (Stream) base.ImageStream, romDataOffset );
       
   184 
       
   185                     // Process the entry based upon the compression type
       
   186                     //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - pageInfo.DataSize: {1}, pageInfo.DataStart: {2}, pageInfo.CompressionType: {3}", i, pageInfo.DataSize, pageInfo.DataStart, pageInfo.CompressionType );
       
   187                     base.ImageStream.Seek( pageInfo.DataStart, SeekOrigin.Begin );
       
   188 
       
   189                     if ( pageInfo.CompressionType == SRomPageInfo.TSymbianCompressionType.ENoCompression )
       
   190                     {
       
   191                         // Read data - no decompression needed
       
   192                         //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - PAGE NOT COMPRESSED", i );
       
   193                         resultantDataStream.Write( base.ImageStream, (int) pageInfo.DataSize );
       
   194                     }
       
   195                     else if ( pageInfo.CompressionType == SRomPageInfo.TSymbianCompressionType.EBytePair )
       
   196                     {
       
   197                         //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - BYTE PAIR PAGE", i );
       
   198 
       
   199                         // Read data - need to decompress it
       
   200                         byte[] compressedData = new byte[ pageInfo.DataSize ];
       
   201                         base.ImageStream.Read( compressedData, 0, compressedData.Length );
       
   202 
       
   203                         // Make destination buffer - which is a page big
       
   204                         byte[] uncompressedData = new byte[ SRomPageInfo.KPageSize ];
       
   205 
       
   206                         // Decompress to buffer - we're handling the page management, so we want raw decompression
       
   207                         int error = decompressor.DecompressRaw( compressedData, uncompressedData );
       
   208 
       
   209                         // Save it
       
   210                         if ( error < 0 )
       
   211                         {
       
   212                             base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - Exception - bytepair decompression error", i );
       
   213                             throw new Exception( "BytePair decompression error: " + error.ToString() );
       
   214                         }
       
   215                         else if ( error != SRomPageInfo.KPageSize )
       
   216                         {
       
   217                             base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - Exception - bytepair underflow error", i );
       
   218                             throw new Exception( "Decompressor underflow - only created " + error.ToString() + " bytes" );
       
   219                         }
       
   220                         else
       
   221                         {
       
   222                             resultantDataStream.Write( uncompressedData );
       
   223                         }
       
   224                     }
       
   225                     else
       
   226                     {
       
   227                         base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - UNSUPPORTED COMPRESSION TYPE - Exception!", i );
       
   228                         throw new NotSupportedException( "Unsupported page compression type" );
       
   229                     }
       
   230 
       
   231                     // Report progress
       
   232                     base.ReportDecompressionEvent( TDecompressionEvent.EEventDecompressionProgress, ( (float) i / (float) numPages ) * 100 );
       
   233                 }
       
   234 
       
   235                 // Now we can replace the base class stream (which is just the raw compressed file data) with the new uncompressed version
       
   236                 base.ImageStream = resultantDataStream;
       
   237                 iContentIsPrepared = true;
       
   238 
       
   239                 base.Trace( "[SymbianImageROM] DoDecompressBytePair() - END" );
       
   240             }
       
   241         }
       
   242         #endregion
       
   243 
       
   244         #region Data members
       
   245         private bool iContentIsPrepared = false;
       
   246         #endregion
       
   247     }
       
   248 }