File: MS\Internal\Ink\InkSerializedFormat\MultiByteCodec.cs
Web Access
Project: src\src\Microsoft.DotNet.Wpf\src\PresentationCore\PresentationCore.csproj (PresentationCore)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using MS.Utility;
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Globalization;
using System.Windows;
using System.Windows.Input;
using System.Windows.Ink;
using System.Collections.Generic;
using MS.Internal.Ink.InkSerializedFormat;
using System.Diagnostics;
 
using SR = MS.Internal.PresentationCore.SR;
 
namespace MS.Internal.Ink.InkSerializedFormat
{
    /// <summary>
    /// MultiByteCodec
    /// </summary>
    internal class MultiByteCodec
    {
        /// <summary>
        /// MultiByteCodec
        /// </summary>
        internal MultiByteCodec()
        {
        }
 
        /// <summary>
        /// Encode
        /// </summary>
        /// <param name="data"></param>
        /// <param name="output"></param>
        internal void Encode(uint data, List<byte> output)
        {
            ArgumentNullException.ThrowIfNull(output);
            while (data > 0x7f)
            {
                byte byteToAdd = (byte)(0x80 | (byte)data & 0x7f);
                output.Add(byteToAdd);
                data >>= 7;
            }
            byte finalByteToAdd = (byte)(data & 0x7f);
            output.Add(finalByteToAdd);
        }
 
        /// <summary>
        /// SignEncode
        /// </summary>
        /// <param name="data"></param>
        /// <param name="output"></param>
        internal void SignEncode(int data, List<byte> output)
        {
            uint xfData = 0;
            if (data < 0)
            {
                xfData = (uint)( (-data << 1) | 0x01 );
            }
            else
            {
                xfData = (uint)data << 1;
            }
            Encode(xfData, output);
        }
 
        /// <summary>
        /// Decode
        /// </summary>
        /// <param name="input"></param>
        /// <param name="inputIndex"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        internal uint Decode(byte[] input, int inputIndex, ref uint data)
        {
            Debug.Assert(input != null);
            Debug.Assert(inputIndex < input.Length);
 
            // We care about first 5 bytes
            uint cb = (input.Length - inputIndex > 5) ? 5 : (uint)(input.Length - inputIndex);
            uint index = 0;
            data = 0;
            while ((index < cb) && (input[index] > 0x7f))
            {
                int leftShift = (int)(index * 7);
                data |= (uint)((input[index] & 0x7f) << leftShift);
                ++index;
            }
            if (index < cb)
            {
                int leftShift = (int)(index * 7);
                data |= (uint)((input[index] & 0x7f) << leftShift);
            }
            else
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("invalid input in MultiByteCodec.Decode"));
            }
            return (index + 1);
        }
 
 
        /// <summary>
        /// SignDecode
        /// </summary>
        /// <param name="input"></param>
        /// <param name="inputIndex"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        internal uint SignDecode(byte[] input, int inputIndex, ref int data)
        {
            Debug.Assert(input != null); //already validated at the AlgoModule level
            ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(inputIndex, input.Length);
            uint xfData = 0;
            uint cb = Decode(input, inputIndex, ref xfData);
            data = (0 != (0x01 & xfData)) ? -(int)(xfData >> 1) : (int)(xfData >> 1);
            return cb;
        }
}
}