File: Framework\System\Windows\Markup\BamlVersionHeader.cs
Project: wpf\src\PresentationBuildTasks.csproj (PresentationBuildTasks)

/***************************************************************************\
*
* File: BamlVersionHeader.cs
*
* Copyright (C) 2005 by Microsoft Corporation.  All rights reserved.
*
\***************************************************************************/
 
using System;
using System.IO;
using System.Globalization;
using System.Diagnostics;
 
using MS.Internal.IO.Packaging.CompoundFile;
 
#if PBTCOMPILER
namespace MS.Internal.Markup
#else
namespace System.Windows.Markup
#endif
{
    internal class BamlVersionHeader
    {
        // The current BAML record version.  This is incremented whenever
        // the BAML format changes
        // Baml Format Breaking Changes should change this.
 
        internal static readonly VersionPair BamlWriterVersion;
 
        static BamlVersionHeader()
        {
            // Initialize the Version number this way so that it can be
            // seen in the Lutz Reflector.
            BamlWriterVersion = new VersionPair(0, 96);
        }
 
        public BamlVersionHeader()
        {
            _bamlVersion = new FormatVersion("MSBAML", BamlWriterVersion);
        }
 
        public FormatVersion BamlVersion
        {
            get { return _bamlVersion; }
#if !PBTCOMPILER
            set { _bamlVersion = value; }
#endif
        }
 
 
        // This is used by Async loading to measure if the whole record is present
        static public int BinarySerializationSize
        {
            get
            {
                // Unicode "MSBAML" = 12
                // + 4 bytes length header = 12 + 4 = 16
                // + 3*(16bit MinorVer + 16bit MajorVer) = 16+(3*(2+2))= 28
                // For product stability the size of this data structure
                // shouldn't change anyway.
                return 28;
            }
        }
 
 
#if !PBTCOMPILER
        internal void  LoadVersion(BinaryReader bamlBinaryReader)
        {
#if DEBUG
            long posStart = bamlBinaryReader.BaseStream.Position;
#endif

            BamlVersion = FormatVersion.LoadFromStream(bamlBinaryReader.BaseStream);
 
#if DEBUG
            long posEnd = bamlBinaryReader.BaseStream.Position;
            Debug.Assert((posEnd-posStart) == BamlVersionHeader.BinarySerializationSize,
                             "Incorrect Baml Version Header Size");
#endif

            // We're assuming that only major versions are significant for compatibility,
            // so if we have a major version in the file that is higher than that in
            // the code, we can't read it.
            if (BamlVersion.ReaderVersion != BamlWriterVersion)
            {
                throw new InvalidOperationException(SR.Get(SRID.ParserBamlVersion,
                                         (BamlVersion.ReaderVersion.Major.ToString(CultureInfo.CurrentCulture) + "." +
                                          BamlVersion.ReaderVersion.Minor.ToString(CultureInfo.CurrentCulture)),
                                         (BamlWriterVersion.Major.ToString(CultureInfo.CurrentCulture) + "." +
                                          BamlWriterVersion.Minor.ToString(CultureInfo.CurrentCulture))));
            }
        }
#endif
 
 
        internal void WriteVersion(BinaryWriter bamlBinaryWriter)
        {
#if DEBUG
            long posStart = bamlBinaryWriter.BaseStream.Position;
#endif
            BamlVersion.SaveToStream(bamlBinaryWriter.BaseStream);
 
#if DEBUG
            long posEnd = bamlBinaryWriter.BaseStream.Position;
            if(-1 == posStart)
            {
                long length = bamlBinaryWriter.BaseStream.Length;
                Debug.Assert(length == BamlVersionHeader.BinarySerializationSize,
                                 "Incorrect Baml Version Header Size");
            }
            else
            {
                Debug.Assert((posEnd-posStart) == BamlVersionHeader.BinarySerializationSize,
                                 "Incorrect Baml Version Header Size");
            }
#endif
 
        }
 
        FormatVersion _bamlVersion;
    }
}