MetricEntry.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / Ink / InkSerializedFormat / MetricEntry.cs / 1305600 / MetricEntry.cs

                            using System; 
using System.IO;
using System.Windows.Input;
using System.Windows.Ink;
 
namespace MS.Internal.Ink.InkSerializedFormat
{ 
    ///  
    /// Summary description for MetricEnty.
    ///  
    internal enum MetricEntryType
    {
        Optional = 0,
        Must, 
        Never,
        Custom, 
    } 

    // This is used while comparing two Metric Collections. This defines the relationship between 
    // two collections when one is superset of the other and can replace the other in the global
    // list of collections
    internal enum SetType
    { 
        SubSet = 0,
        SuperSet, 
    } 

    internal struct MetricEntryList 
    {
        public KnownTagCache.KnownTagIndex Tag;
        public StylusPointPropertyInfo PropertyMetrics;
 
        public MetricEntryList (KnownTagCache.KnownTagIndex tag, StylusPointPropertyInfo prop)
        { 
            Tag = tag; 
            PropertyMetrics = prop;
        } 
    }

    /// 
    /// This class holds the MetricEntries corresponding to a PacketProperty in the form of a link list 
    /// 
    internal class MetricEntry 
    { 
        //Maximum buffer size required to store the largest MetricEntry
        private static int MAX_METRIC_DATA_BUFF = 24; 

        private KnownTagCache.KnownTagIndex _tag = 0;
        private uint _size = 0;
        private MetricEntry _next; 
        private byte[] _data = new Byte[MAX_METRIC_DATA_BUFF]; // We always allocate the max buffer needed to store the largest possible Metric Information blob
        private static MetricEntryList[] _metricEntryOptional; 
 
        // helpers for Ink-local property metrics for X/Y coordiantes
        public static StylusPointPropertyInfo DefaultXMetric = MetricEntry_Optional[0].PropertyMetrics; 

        public static StylusPointPropertyInfo DefaultYMetric = MetricEntry_Optional[1].PropertyMetrics;

 
        /// 
        /// List of MetricEntry that may or may not appear in the serialized form depending on their default Metrics. 
        ///  
        public static MetricEntryList[] MetricEntry_Optional
        { 
            get
            {
                if (_metricEntryOptional == null)
                { 
                    _metricEntryOptional = new MetricEntryList[] {
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.X,                     StylusPointPropertyInfoDefaults.X), 
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.Y,                     StylusPointPropertyInfoDefaults.Y), 
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.Z,                     StylusPointPropertyInfoDefaults.Z),
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.NormalPressure,        StylusPointPropertyInfoDefaults.NormalPressure), 
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.TangentPressure,       StylusPointPropertyInfoDefaults.TangentPressure),
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.ButtonPressure,        StylusPointPropertyInfoDefaults.ButtonPressure),
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.XTiltOrientation,      StylusPointPropertyInfoDefaults.XTiltOrientation),
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.YTiltOrientation,      StylusPointPropertyInfoDefaults.YTiltOrientation), 
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.AzimuthOrientation,    StylusPointPropertyInfoDefaults.AzimuthOrientation),
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.AltitudeOrientation,   StylusPointPropertyInfoDefaults.AltitudeOrientation), 
                        new MetricEntryList (KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.TwistOrientation,      StylusPointPropertyInfoDefaults.TwistOrientation)}; 

                } 
                return _metricEntryOptional;
            }
        }
 
        /// 
        /// List of MetricEntry whose Metric Information must appear in the serialized form and always written as they do not have proper default 
        ///  
        static KnownTagCache.KnownTagIndex[] MetricEntry_Must = new KnownTagCache.KnownTagIndex[]
        { 
            (KnownTagCache.KnownTagIndex)((uint)KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.PitchRotation),
            (KnownTagCache.KnownTagIndex)((uint)KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.RollRotation),
            (KnownTagCache.KnownTagIndex)((uint)KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.YawRotation),
        }; 

        ///  
        /// List of MetricEntry whose Metric information will never appear in the Serialized format and always ignored 
        /// 
        static KnownTagCache.KnownTagIndex[] MetricEntry_Never = new KnownTagCache.KnownTagIndex[] 
        {
            (KnownTagCache.KnownTagIndex)((uint)KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.PacketStatus),
            (KnownTagCache.KnownTagIndex)((uint)KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.TimerTick),
            (KnownTagCache.KnownTagIndex)((uint)KnownIdCache.KnownGuidBaseIndex + (uint)KnownIdCache.OriginalISFIdIndex.SerialNumber), 
        };
 
        ///  
        /// Default StylusPointPropertyInfo for any property
        ///  
        static StylusPointPropertyInfo DefaultPropertyMetrics = StylusPointPropertyInfoDefaults.DefaultValue;

        /// 
        /// Gets or sets the Tag associated with this entry 
        /// 
        public KnownTagCache.KnownTagIndex Tag 
        { 
            get
            { 
                return _tag;
            }
            set
            { 
                _tag = value;
            } 
        } 

        ///  
        /// Gets the size associated with this entry
        /// 
        public uint Size
        { 
            get
            { 
                return _size; 
            }
        } 

        /// 
        /// Gets or Sets the data associated with this metric entry
        ///  
        public byte[] Data
        { 
            get 
            {
                return _data; 
            }
            set
            {
                byte [] data = (byte[])value; 
                if( data.Length > MAX_METRIC_DATA_BUFF )
                    _size = (uint)MAX_METRIC_DATA_BUFF; 
                else 
                    _size = (uint)data.Length;
                for( int i = 0; i < (int)_size; i++ ) 
                    _data[i] = data[i];
            }
        }
 
        /// 
        /// Compares a metricEntry object with this one and returns true or false 
        ///  
        /// 
        ///  
        public bool Compare(MetricEntry metricEntry)
        {
            if( Tag != metricEntry.Tag )
                return false; 
            if( Size != metricEntry.Size )
                return false; 
            for( int i = 0; i < Size; i++ ) 
            {
                if( Data[i] != metricEntry.Data[i] ) 
                    return false;
            }
            return true;
        } 

        ///  
        /// Gets/Sets the next entry in the list 
        /// 
        public MetricEntry Next 
        {
            get
            {
                return _next; 
            }
            set 
            { 
                _next = value;
            } 
        }

        /// 
        /// Constructro 
        /// 
        public MetricEntry() 
        { 
        }
 
        /// 
        /// Adds an entry in the list
        /// 
        ///  
        public void Add(MetricEntry next)
        { 
            if( null == _next ) 
            {
                _next = next; 
                return;
            }
            MetricEntry prev = _next;
            while( null != prev.Next ) 
            {
                prev = prev.Next; 
            } 
            prev.Next = next;
        } 

        /// 
        /// Initializes a MetricEntry based on StylusPointPropertyInfo and default StylusPointPropertyInfo for the property
        ///  
        /// 
        ///  
        ///  
        public void Initialize(StylusPointPropertyInfo originalInfo, StylusPointPropertyInfo defaultInfo)
        { 
            _size = 0;
            using (MemoryStream strm = new MemoryStream(_data))
            {
                if (!DoubleUtil.AreClose(originalInfo.Resolution, defaultInfo.Resolution)) 
                {
                    // First min value 
                    _size += SerializationHelper.SignEncode(strm, originalInfo.Minimum); 
                    // Max value
                    _size += SerializationHelper.SignEncode(strm, originalInfo.Maximum); 
                    // Units
                    _size += SerializationHelper.Encode(strm, (uint)originalInfo.Unit);
                    // resolution
                    using (BinaryWriter bw = new BinaryWriter(strm)) 
                    {
                        bw.Write(originalInfo.Resolution); 
                        _size += 4; // sizeof(float) 
                    }
                } 
                else if (originalInfo.Unit != defaultInfo.Unit)
                {
                    // First min value
                    _size += SerializationHelper.SignEncode(strm, originalInfo.Minimum); 
                    // Max value
                    _size += SerializationHelper.SignEncode(strm, originalInfo.Maximum); 
                    // Units 
                    _size += SerializationHelper.Encode(strm, (uint)originalInfo.Unit);
                } 
                else if (originalInfo.Maximum != defaultInfo.Maximum)
                {
                    // First min value
                    _size += SerializationHelper.SignEncode(strm, originalInfo.Minimum); 
                    // Max value
                    _size += SerializationHelper.SignEncode(strm, originalInfo.Maximum); 
                } 
                else if (originalInfo.Minimum != defaultInfo.Minimum)
                { 
                    _size += SerializationHelper.SignEncode(strm, originalInfo.Minimum);
                }
            }
        } 

        ///  
        /// Creates a metric entry based on a PropertyInfo and Tag and returns the Metric Entry Type created 
        /// 
        ///  
        /// 
        /// 
        public MetricEntryType CreateMetricEntry(StylusPointPropertyInfo propertyInfo, KnownTagCache.KnownTagIndex tag)
        { 
            // First create the default Metric entry based on the property and type of metric entry and then use that to initialize the
            // metric entry data. 
            uint index = 0; 
            Tag = tag;
 
            MetricEntryType type;
            if( IsValidMetricEntry(propertyInfo, Tag, out type, out index) )
            {
                switch(type) 
                {
                    case MetricEntryType.Optional: 
                    { 
                        Initialize(propertyInfo, MetricEntry_Optional[index].PropertyMetrics);
                        break; 
                    }
                    case MetricEntryType.Must :
                    case MetricEntryType.Custom:
                        Initialize(propertyInfo, DefaultPropertyMetrics); 
                        break;
                    default: 
                        throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("MetricEntryType was persisted with Never flag which should never happen")); 
                }
            } 
            return type;
        }
        /// 
        /// This function checks if this packet property results in a valid metric entry. This will be a valid entry if 
        /// 1. it is a custom property, 2. Does not belong to the global list of gaMetricEntry_Never, 3. Belongs to the
        /// global list of gaMetricEntry_Must and 4. Belongs to global list of gaMetricEntry_Optional and at least one of 
        /// its metric values is different from the corresponding default. 
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  

        static bool IsValidMetricEntry(StylusPointPropertyInfo propertyInfo, KnownTagCache.KnownTagIndex tag, out MetricEntryType metricEntryType, out uint index) 
        { 
            index = 0;
            // If this is a custom property, check if all the Metric values are null or not. If they are then this is not a 
            // valid metric entry
            if (tag >= (KnownTagCache.KnownTagIndex)KnownIdCache.CustomGuidBaseIndex)
            {
                metricEntryType = MetricEntryType.Custom; 
                if( Int32.MinValue == propertyInfo.Minimum &&
                    Int32.MaxValue == propertyInfo.Maximum && 
                    StylusPointPropertyUnit.None == propertyInfo.Unit && 
                    DoubleUtil.AreClose(1.0, propertyInfo.Resolution) )
                    return false; 
                else
                    return true;
            }
            else 
            {
                int ul; 
                // First find the property in the gaMetricEntry_Never. If it belongs to this list, 
                // we will never write the metric table for this prop. So return FALSE;
                for( ul = 0; ul < MetricEntry_Never.Length ; ul++ ) 
                {
                    if( MetricEntry_Never[ul] == tag )
                    {
                        metricEntryType = MetricEntryType.Never; 
                        return false;
                    } 
                } 

                // Then search the property in the gaMetricEntry_Must list. If it belongs to this list, 
                // we must always write the metric table for this prop. So return TRUE;
                for( ul = 0; ul 
    /// CMetricBlock owns CMetricEntry which is created based on the Packet Description of the stroke. It also
    /// stores the pointer of the next Block. This is not used in the context of a stroke but is used in the 
    /// context of WispInk. Wispink forms a linked list based on the CMetricBlocks of all the strokes.
    /// 

        internal class MetricBlock 
    {
        private MetricEntry _Entry; 
        private uint        _Count; 
        private uint        _size;
 
        /// 
        /// Constructor
        /// 
        public MetricBlock() 
        {
        } 
 
        /// 
        /// Gets the MetricEntry list associated with this instance 
        /// 
        /// 
        public MetricEntry GetMetricEntryList()
        { 
            return _Entry;
        } 
 
        /// 
        /// Gets the count of MetricEntry for this instance 
        /// 
        public uint MetricEntryCount
        {
            get 
            {
                return _Count; 
            } 
        }
 
        // Returns the size required to serialize this instance
        public uint Size
        {
            get 
            {
                return (_size + SerializationHelper.VarSize(_size)); 
            } 
        }
 
        /// 
        /// Adds a new metric entry in the existing list of metric entries
        /// 
        ///  
        /// 
        public void AddMetricEntry(MetricEntry newEntry) 
        { 
            if (null == newEntry)
            { 
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("MetricEntry cannot be null"));
            }
            if( null == _Entry )
                _Entry = newEntry; 
            else
                _Entry.Add(newEntry);  // tack on at the end 
            _Count ++; 
            _size += newEntry.Size + SerializationHelper.VarSize(newEntry.Size) + SerializationHelper.VarSize((uint)newEntry.Tag);
        } 

        /// 
        /// Adds a new metric entry in the existing list of metric entries
        ///  
        /// 
        ///  
        ///  
        public MetricEntryType AddMetricEntry(StylusPointPropertyInfo property, KnownTagCache.KnownTagIndex tag)
        { 
            // Create a new metric entry based on the packet information passed.
            MetricEntry entry = new MetricEntry();
            MetricEntryType type = entry.CreateMetricEntry(property, tag);
 
            // Don't add this entry to the global list if size is 0, means default metric values!
            if( 0 == entry.Size ) 
            { 
                return type;
            } 

            MetricEntry start = _Entry;
            if( null == start )
            { 
                _Entry = entry;
            } 
            else    // tack on data at the end, want to keep x,y at the beginning 
            {
                while(start.Next != null) 
                {
                    start = start.Next;
                }
                start.Next = entry; 
            }
            _Count++; 
            _size += entry.Size + SerializationHelper.VarSize(entry.Size) + SerializationHelper.VarSize((uint)_Entry.Tag); 
            return type;
        } 

        /// 
        /// This function Packs the data in the buffer provided. The
        /// function is being called during the save loop and caller 
        /// must call GetSize for the block before calling this function.
        /// The buffer must be preallocated and buffer size must be at 
        /// least the size of the block. 
        /// On return cbBuffer contains the size of the data written.
        /// Called only by BuildMetricTable funtion 
        /// 
        /// 
        /// 
        public uint Pack(Stream strm) 
        {
            // Write the size of the Block at the begining of the buffer. 
            // But first check the validity of the buffer & its size 
            uint cbWrite  = 0;
            // First write the size of the block 
            cbWrite = SerializationHelper.Encode(strm, _size);

            // Now write each entry for the block
            MetricEntry entry = _Entry; 
            while( null != entry )
            { 
                cbWrite += SerializationHelper.Encode(strm, (uint)entry.Tag); 
                cbWrite += SerializationHelper.Encode(strm, entry.Size);
                strm.Write(entry.Data, 0, (int)entry.Size); 
                cbWrite += entry.Size;
                entry = entry.Next;
            }
            return cbWrite; 
        }
        // 
        // 

        ///  
        /// This function compares pMetricColl with the current one. If pMetricColl has more entries apart from the one
        /// in the current list with which some of its entries are identical, setType is set as SUPERSET.
        /// 
        ///  
        /// 
        ///  
        public bool CompareMetricBlock( MetricBlock metricColl, ref SetType setType) 
        {
            if( null == metricColl ) 
                return false;

            // if both have null entry, implies default metric Block for both of them
            // and it already exists in the list. Return TRUE 
            // If only one of the blocks is empty, return FALSE - they cannot be merged
            // because the other block may have customized GUID_X or GUID_Y. 
 
            if (null == GetMetricEntryList())
                return (metricColl.GetMetricEntryList() == null); 

            if (null == metricColl.GetMetricEntryList())
                return false;
 
            // Else compare the entries
 
            bool  fTagFound = false; 
            uint cbLhs = this.MetricEntryCount;    // No of entries in this block
            uint cbRhs = metricColl.MetricEntryCount;   // No of entries in the block to be compared 

            MetricEntry outside, inside;
            if( metricColl.MetricEntryCount <= MetricEntryCount )
            { 
                outside = metricColl.GetMetricEntryList();
                inside  = GetMetricEntryList(); 
            } 
            else
            { 
                inside   = metricColl.GetMetricEntryList();
                outside  = GetMetricEntryList();
                setType   = SetType.SuperSet;
            } 

            // For each entry in metricColl, search for the same in this Block. 
            // If it is found, continue with the next entry of smaller Block. 
            while( null != outside )
            { 
                fTagFound = false;
                // Always start at the begining of the larger block
                MetricEntry temp = inside;
                while( null != temp ) 
                {
                    if( outside.Compare(temp) ) 
                    { 
                        fTagFound = true;
                        break; 
                    }
                    else
                        temp = temp.Next;
                } 
                if( !fTagFound )
                    return false; 
 
                // Found the entry; Continue with the next entry in the outside block
                outside = outside.Next; 
            }

            return true;
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK