File: FrameworkFork\System.Runtime.Serialization\System\Xml\ValueHandle.cs
Web Access
Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib)
// 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 System.Runtime.Serialization;
using System.Diagnostics;
using System.Globalization;
using System.Text;
 
 
namespace Microsoft.Xml
{
    using System;
 
    internal enum ValueHandleConstStringType
    {
        String = 0,
        Number = 1,
        Array = 2,
        Object = 3,
        Boolean = 4,
        Null = 5,
    }
 
    internal static class ValueHandleLength
    {
        public const int Int8 = 1;
        public const int Int16 = 2;
        public const int Int32 = 4;
        public const int Int64 = 8;
        public const int UInt64 = 8;
        public const int Single = 4;
        public const int Double = 8;
        public const int Decimal = 16;
        public const int DateTime = 8;
        public const int TimeSpan = 8;
        public const int Guid = 16;
        public const int UniqueId = 16;
    }
 
    internal enum ValueHandleType
    {
        Empty,
        True,
        False,
        Zero,
        One,
        Int8,
        Int16,
        Int32,
        Int64,
        UInt64,
        Single,
        Double,
        Decimal,
        DateTime,
        TimeSpan,
        Guid,
        UniqueId,
        UTF8,
        EscapedUTF8,
        Base64,
        Dictionary,
        List,
        Char,
        Unicode,
        QName,
        ConstString
    }
 
    internal class ValueHandle
    {
        private XmlBufferReader _bufferReader;
        private ValueHandleType _type;
        private int _offset;
        private int _length;
        private static Base64Encoding s_base64Encoding;
        private static string[] s_constStrings = {
                                        "string",
                                        "number",
                                        "array",
                                        "object",
                                        "boolean",
                                        "null",
                                       };
 
        public ValueHandle(XmlBufferReader bufferReader)
        {
            _bufferReader = bufferReader;
            _type = ValueHandleType.Empty;
        }
 
        private static Base64Encoding Base64Encoding
        {
            get
            {
                if (s_base64Encoding == null)
                    s_base64Encoding = new Base64Encoding();
                return s_base64Encoding;
            }
        }
        public void SetConstantValue(ValueHandleConstStringType constStringType)
        {
            _type = ValueHandleType.ConstString;
            _offset = (int)constStringType;
        }
 
        public void SetValue(ValueHandleType type)
        {
            _type = type;
        }
 
        public void SetDictionaryValue(int key)
        {
            SetValue(ValueHandleType.Dictionary, key, 0);
        }
 
        public void SetCharValue(int ch)
        {
            SetValue(ValueHandleType.Char, ch, 0);
        }
 
        public void SetQNameValue(int prefix, int key)
        {
            SetValue(ValueHandleType.QName, key, prefix);
        }
        public void SetValue(ValueHandleType type, int offset, int length)
        {
            _type = type;
            _offset = offset;
            _length = length;
        }
 
        public bool IsWhitespace()
        {
            switch (_type)
            {
                case ValueHandleType.UTF8:
                    return _bufferReader.IsWhitespaceUTF8(_offset, _length);
 
                case ValueHandleType.Dictionary:
                    return _bufferReader.IsWhitespaceKey(_offset);
 
                case ValueHandleType.Char:
                    int ch = GetChar();
                    if (ch > char.MaxValue)
                        return false;
                    return XmlConverter.IsWhitespace((char)ch);
 
                case ValueHandleType.EscapedUTF8:
                    return _bufferReader.IsWhitespaceUTF8(_offset, _length);
 
                case ValueHandleType.Unicode:
                    return _bufferReader.IsWhitespaceUnicode(_offset, _length);
 
                case ValueHandleType.True:
                case ValueHandleType.False:
                case ValueHandleType.Zero:
                case ValueHandleType.One:
                    return false;
 
                case ValueHandleType.ConstString:
                    return s_constStrings[_offset].Length == 0;
 
                default:
                    return _length == 0;
            }
        }
 
        public Type ToType()
        {
            switch (_type)
            {
                case ValueHandleType.False:
                case ValueHandleType.True:
                    return typeof(bool);
                case ValueHandleType.Zero:
                case ValueHandleType.One:
                case ValueHandleType.Int8:
                case ValueHandleType.Int16:
                case ValueHandleType.Int32:
                    return typeof(int);
                case ValueHandleType.Int64:
                    return typeof(long);
                case ValueHandleType.UInt64:
                    return typeof(ulong);
                case ValueHandleType.Single:
                    return typeof(float);
                case ValueHandleType.Double:
                    return typeof(double);
                case ValueHandleType.Decimal:
                    return typeof(decimal);
                case ValueHandleType.DateTime:
                    return typeof(DateTime);
                case ValueHandleType.Empty:
                case ValueHandleType.UTF8:
                case ValueHandleType.Unicode:
                case ValueHandleType.EscapedUTF8:
                case ValueHandleType.Dictionary:
                case ValueHandleType.Char:
                case ValueHandleType.QName:
                case ValueHandleType.ConstString:
                    return typeof(string);
                case ValueHandleType.Base64:
                    return typeof(byte[]);
                case ValueHandleType.List:
                    return typeof(object[]);
                case ValueHandleType.UniqueId:
                    return typeof(UniqueId);
                case ValueHandleType.Guid:
                    return typeof(Guid);
                case ValueHandleType.TimeSpan:
                    return typeof(TimeSpan);
                default:
                    throw /*System.Runtime.Serialization.*/DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
            }
        }
 
        public Boolean ToBoolean()
        {
            ValueHandleType type = _type;
            if (type == ValueHandleType.False)
                return false;
            if (type == ValueHandleType.True)
                return true;
            if (type == ValueHandleType.UTF8)
                return XmlConverter.ToBoolean(_bufferReader.Buffer, _offset, _length);
            if (type == ValueHandleType.Int8)
            {
                int value = GetInt8();
                if (value == 0)
                    return false;
                if (value == 1)
                    return true;
            }
            return XmlConverter.ToBoolean(GetString());
        }
 
        public int ToInt()
        {
            ValueHandleType type = _type;
            if (type == ValueHandleType.Zero)
                return 0;
            if (type == ValueHandleType.One)
                return 1;
            if (type == ValueHandleType.Int8)
                return GetInt8();
            if (type == ValueHandleType.Int16)
                return GetInt16();
            if (type == ValueHandleType.Int32)
                return GetInt32();
            if (type == ValueHandleType.Int64)
            {
                long value = GetInt64();
                if (value >= int.MinValue && value <= int.MaxValue)
                {
                    return (int)value;
                }
            }
            if (type == ValueHandleType.UInt64)
            {
                ulong value = GetUInt64();
                if (value <= int.MaxValue)
                {
                    return (int)value;
                }
            }
            if (type == ValueHandleType.UTF8)
                return XmlConverter.ToInt32(_bufferReader.Buffer, _offset, _length);
            return XmlConverter.ToInt32(GetString());
        }
 
        public long ToLong()
        {
            ValueHandleType type = _type;
            if (type == ValueHandleType.Zero)
                return 0;
            if (type == ValueHandleType.One)
                return 1;
            if (type == ValueHandleType.Int8)
                return GetInt8();
            if (type == ValueHandleType.Int16)
                return GetInt16();
            if (type == ValueHandleType.Int32)
                return GetInt32();
            if (type == ValueHandleType.Int64)
                return GetInt64();
            if (type == ValueHandleType.UInt64)
            {
                ulong value = GetUInt64();
                if (value <= long.MaxValue)
                {
                    return (long)value;
                }
            }
            if (type == ValueHandleType.UTF8)
            {
                return XmlConverter.ToInt64(_bufferReader.Buffer, _offset, _length);
            }
            return XmlConverter.ToInt64(GetString());
        }
 
        public ulong ToULong()
        {
            ValueHandleType type = _type;
            if (type == ValueHandleType.Zero)
                return 0;
            if (type == ValueHandleType.One)
                return 1;
            if (type >= ValueHandleType.Int8 && type <= ValueHandleType.Int64)
            {
                long value = ToLong();
                if (value >= 0)
                    return (ulong)value;
            }
            if (type == ValueHandleType.UInt64)
                return GetUInt64();
            if (type == ValueHandleType.UTF8)
                return XmlConverter.ToUInt64(_bufferReader.Buffer, _offset, _length);
            return XmlConverter.ToUInt64(GetString());
        }
 
        public Single ToSingle()
        {
            ValueHandleType type = _type;
            if (type == ValueHandleType.Single)
                return GetSingle();
            if (type == ValueHandleType.Double)
            {
                double value = GetDouble();
                if ((value >= Single.MinValue && value <= Single.MaxValue) || double.IsInfinity(value) || double.IsNaN(value))
                    return (Single)value;
            }
            if (type == ValueHandleType.Zero)
                return 0;
            if (type == ValueHandleType.One)
                return 1;
            if (type == ValueHandleType.Int8)
                return GetInt8();
            if (type == ValueHandleType.Int16)
                return GetInt16();
            if (type == ValueHandleType.UTF8)
                return XmlConverter.ToSingle(_bufferReader.Buffer, _offset, _length);
            return XmlConverter.ToSingle(GetString());
        }
 
        public Double ToDouble()
        {
            ValueHandleType type = _type;
            if (type == ValueHandleType.Double)
                return GetDouble();
            if (type == ValueHandleType.Single)
                return GetSingle();
            if (type == ValueHandleType.Zero)
                return 0;
            if (type == ValueHandleType.One)
                return 1;
            if (type == ValueHandleType.Int8)
                return GetInt8();
            if (type == ValueHandleType.Int16)
                return GetInt16();
            if (type == ValueHandleType.Int32)
                return GetInt32();
            if (type == ValueHandleType.UTF8)
                return XmlConverter.ToDouble(_bufferReader.Buffer, _offset, _length);
            return XmlConverter.ToDouble(GetString());
        }
 
        public Decimal ToDecimal()
        {
            ValueHandleType type = _type;
            if (type == ValueHandleType.Decimal)
                return GetDecimal();
            if (type == ValueHandleType.Zero)
                return 0;
            if (type == ValueHandleType.One)
                return 1;
            if (type >= ValueHandleType.Int8 && type <= ValueHandleType.Int64)
                return ToLong();
            if (type == ValueHandleType.UInt64)
                return GetUInt64();
            if (type == ValueHandleType.UTF8)
                return XmlConverter.ToDecimal(_bufferReader.Buffer, _offset, _length);
            return XmlConverter.ToDecimal(GetString());
        }
 
        public DateTime ToDateTime()
        {
            if (_type == ValueHandleType.DateTime)
            {
                return XmlConverter.ToDateTime(GetInt64());
            }
            if (_type == ValueHandleType.UTF8)
            {
                return XmlConverter.ToDateTime(_bufferReader.Buffer, _offset, _length);
            }
            return XmlConverter.ToDateTime(GetString());
        }
 
        public UniqueId ToUniqueId()
        {
            if (_type == ValueHandleType.UniqueId)
                return GetUniqueId();
            if (_type == ValueHandleType.UTF8)
                return XmlConverter.ToUniqueId(_bufferReader.Buffer, _offset, _length);
            return XmlConverter.ToUniqueId(GetString());
        }
 
        public TimeSpan ToTimeSpan()
        {
            if (_type == ValueHandleType.TimeSpan)
                return new TimeSpan(GetInt64());
            if (_type == ValueHandleType.UTF8)
                return XmlConverter.ToTimeSpan(_bufferReader.Buffer, _offset, _length);
            return XmlConverter.ToTimeSpan(GetString());
        }
 
        public Guid ToGuid()
        {
            if (_type == ValueHandleType.Guid)
                return GetGuid();
            if (_type == ValueHandleType.UTF8)
                return XmlConverter.ToGuid(_bufferReader.Buffer, _offset, _length);
            return XmlConverter.ToGuid(GetString());
        }
        public override string ToString()
        {
            return GetString();
        }
 
        public byte[] ToByteArray()
        {
            if (_type == ValueHandleType.Base64)
            {
                byte[] buffer = new byte[_length];
                GetBase64(buffer, 0, _length);
                return buffer;
            }
            if (_type == ValueHandleType.UTF8 && (_length % 4) == 0)
            {
                try
                {
                    int expectedLength = _length / 4 * 3;
                    if (_length > 0)
                    {
                        if (_bufferReader.Buffer[_offset + _length - 1] == '=')
                        {
                            expectedLength--;
                            if (_bufferReader.Buffer[_offset + _length - 2] == '=')
                                expectedLength--;
                        }
                    }
                    byte[] buffer = new byte[expectedLength];
                    int actualLength = Base64Encoding.GetBytes(_bufferReader.Buffer, _offset, _length, buffer, 0);
                    if (actualLength != buffer.Length)
                    {
                        byte[] newBuffer = new byte[actualLength];
                        Buffer.BlockCopy(buffer, 0, newBuffer, 0, actualLength);
                        buffer = newBuffer;
                    }
                    return buffer;
                }
                catch (FormatException)
                {
                    // Something unhappy with the characters, fall back to the hard way
                }
            }
            try
            {
                return Base64Encoding.GetBytes(XmlConverter.StripWhitespace(GetString()));
            }
            catch (FormatException exception)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(exception.Message, exception.InnerException));
            }
        }
 
        public string GetString()
        {
            ValueHandleType type = _type;
            if (type == ValueHandleType.UTF8)
                return GetCharsText();
 
            switch (type)
            {
                case ValueHandleType.False:
                    return "false";
                case ValueHandleType.True:
                    return "true";
                case ValueHandleType.Zero:
                    return "0";
                case ValueHandleType.One:
                    return "1";
                case ValueHandleType.Int8:
                case ValueHandleType.Int16:
                case ValueHandleType.Int32:
                    return XmlConverter.ToString(ToInt());
                case ValueHandleType.Int64:
                    return XmlConverter.ToString(GetInt64());
                case ValueHandleType.UInt64:
                    return XmlConverter.ToString(GetUInt64());
                case ValueHandleType.Single:
                    return XmlConverter.ToString(GetSingle());
                case ValueHandleType.Double:
                    return XmlConverter.ToString(GetDouble());
                case ValueHandleType.Decimal:
                    return XmlConverter.ToString(GetDecimal());
                case ValueHandleType.DateTime:
                    return XmlConverter.ToString(ToDateTime());
                case ValueHandleType.Empty:
                    return string.Empty;
                case ValueHandleType.UTF8:
                    return GetCharsText();
                case ValueHandleType.Unicode:
                    return GetUnicodeCharsText();
                case ValueHandleType.EscapedUTF8:
                    return GetEscapedCharsText();
                case ValueHandleType.Char:
                    return GetCharText();
                case ValueHandleType.Dictionary:
                    return GetDictionaryString().Value;
                case ValueHandleType.Base64:
                    byte[] bytes = ToByteArray();
                    DiagnosticUtility.DebugAssert(bytes != null, "");
                    return Base64Encoding.GetString(bytes, 0, bytes.Length);
                case ValueHandleType.List:
                    return XmlConverter.ToString(ToList());
                case ValueHandleType.UniqueId:
                    return XmlConverter.ToString(ToUniqueId());
                case ValueHandleType.Guid:
                    return XmlConverter.ToString(ToGuid());
                case ValueHandleType.TimeSpan:
                    return XmlConverter.ToString(ToTimeSpan());
                case ValueHandleType.QName:
                    return GetQNameDictionaryText();
                case ValueHandleType.ConstString:
                    return s_constStrings[_offset];
                default:
                    throw /*System.Runtime.Serialization.*/DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
            }
        }
 
        // ASSUMPTION (Microsoft): all chars in str will be ASCII
        public bool Equals2(string str, bool checkLower)
        {
            if (_type != ValueHandleType.UTF8)
                return GetString() == str;
 
            if (_length != str.Length)
                return false;
 
            byte[] buffer = _bufferReader.Buffer;
            for (int i = 0; i < _length; ++i)
            {
                DiagnosticUtility.DebugAssert(str[i] < 128, "");
                byte ch = buffer[i + _offset];
                if (ch == str[i])
                    continue;
 
                if (checkLower && char.ToLowerInvariant((char)ch) == str[i])
                    continue;
 
                return false;
            }
 
            return true;
        }
 
 
        public object[] ToList()
        {
            return _bufferReader.GetList(_offset, _length);
        }
 
        public object ToObject()
        {
            switch (_type)
            {
                case ValueHandleType.False:
                case ValueHandleType.True:
                    return ToBoolean();
                case ValueHandleType.Zero:
                case ValueHandleType.One:
                case ValueHandleType.Int8:
                case ValueHandleType.Int16:
                case ValueHandleType.Int32:
                    return ToInt();
                case ValueHandleType.Int64:
                    return ToLong();
                case ValueHandleType.UInt64:
                    return GetUInt64();
                case ValueHandleType.Single:
                    return ToSingle();
                case ValueHandleType.Double:
                    return ToDouble();
                case ValueHandleType.Decimal:
                    return ToDecimal();
                case ValueHandleType.DateTime:
                    return ToDateTime();
                case ValueHandleType.Empty:
                case ValueHandleType.UTF8:
                case ValueHandleType.Unicode:
                case ValueHandleType.EscapedUTF8:
                case ValueHandleType.Dictionary:
                case ValueHandleType.Char:
                case ValueHandleType.ConstString:
                    return ToString();
                case ValueHandleType.Base64:
                    return ToByteArray();
                case ValueHandleType.List:
                    return ToList();
                case ValueHandleType.UniqueId:
                    return ToUniqueId();
                case ValueHandleType.Guid:
                    return ToGuid();
                case ValueHandleType.TimeSpan:
                    return ToTimeSpan();
                default:
                    throw /*System.Runtime.Serialization.*/DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
            }
        }
 
        public bool TryReadBase64(byte[] buffer, int offset, int count, out int actual)
        {
            if (_type == ValueHandleType.Base64)
            {
                actual = Math.Min(_length, count);
                GetBase64(buffer, offset, actual);
                _offset += actual;
                _length -= actual;
                return true;
            }
            if (_type == ValueHandleType.UTF8 && count >= 3 && (_length % 4) == 0)
            {
                try
                {
                    int charCount = Math.Min(count / 3 * 4, _length);
                    actual = Base64Encoding.GetBytes(_bufferReader.Buffer, _offset, charCount, buffer, offset);
                    _offset += charCount;
                    _length -= charCount;
                    return true;
                }
                catch (FormatException)
                {
                    // Something unhappy with the characters, fall back to the hard way
                }
            }
            actual = 0;
            return false;
        }
 
        public bool TryReadChars(char[] chars, int offset, int count, out int actual)
        {
            DiagnosticUtility.DebugAssert(offset + count <= chars.Length, string.Format("offset '{0}' + count '{1}' MUST BE <= chars.Length '{2}'", offset, count, chars.Length));
 
            if (_type == ValueHandleType.Unicode)
                return TryReadUnicodeChars(chars, offset, count, out actual);
 
            if (_type != ValueHandleType.UTF8)
            {
                actual = 0;
                return false;
            }
 
            int charOffset = offset;
            int charCount = count;
            byte[] bytes = _bufferReader.Buffer;
            int byteOffset = _offset;
            int byteCount = _length;
            bool insufficientSpaceInCharsArray = false;
 
            while (true)
            {
                while (charCount > 0 && byteCount > 0)
                {
                    // fast path for codepoints U+0000 - U+007F
                    byte b = bytes[byteOffset];
                    if (b >= 0x80)
                        break;
                    chars[charOffset] = (char)b;
                    byteOffset++;
                    byteCount--;
                    charOffset++;
                    charCount--;
                }
 
                if (charCount == 0 || byteCount == 0 || insufficientSpaceInCharsArray)
                    break;
 
                int actualByteCount;
                int actualCharCount;
 
                UTF8Encoding encoding = new UTF8Encoding(false, true);
                try
                {
                    // If we're asking for more than are possibly available, or more than are truly available then we can return the entire thing
                    if (charCount >= encoding.GetMaxCharCount(byteCount) || charCount >= encoding.GetCharCount(bytes, byteOffset, byteCount))
                    {
                        actualCharCount = encoding.GetChars(bytes, byteOffset, byteCount, chars, charOffset);
                        actualByteCount = byteCount;
                    }
                    else
                    {
                        Decoder decoder = encoding.GetDecoder();
 
                        // Since x bytes can never generate more than x characters this is a safe estimate as to what will fit
                        actualByteCount = Math.Min(charCount, byteCount);
 
                        // We use a decoder so we don't error if we fall across a character boundary
                        actualCharCount = decoder.GetChars(bytes, byteOffset, actualByteCount, chars, charOffset);
 
                        // We might've gotten zero characters though if < 4 bytes were requested because
                        // codepoints from U+0000 - U+FFFF can be up to 3 bytes in UTF-8, and represented as ONE char
                        // codepoints from U+10000 - U+10FFFF (last Unicode codepoint representable in UTF-8) are represented by up to 4 bytes in UTF-8 
                        //                                    and represented as TWO chars (high+low surrogate)
                        // (e.g. 1 char requested, 1 char in the buffer represented in 3 bytes)
                        while (actualCharCount == 0)
                        {
                            // Note the by the time we arrive here, if actualByteCount == 3, the next decoder.GetChars() call will read the 4th byte
                            // if we don't bail out since the while loop will advance actualByteCount only after reading the byte. 
                            if (actualByteCount >= 3 && charCount < 2)
                            {
                                // If we reach here, it means that we're: 
                                // - trying to decode more than 3 bytes and, 
                                // - there is only one char left of charCount where we're stuffing decoded characters. 
                                // In this case, we need to back off since decoding > 3 bytes in UTF-8 means that we will get 2 16-bit chars 
                                // (a high surrogate and a low surrogate) - the Decoder will attempt to provide both at once 
                                // and an ArgumentException will be thrown complaining that there's not enough space in the output char array.  
 
                                // actualByteCount = 0 when the while loop is broken out of; decoder goes out of scope so its state no longer matters
 
                                insufficientSpaceInCharsArray = true;
                                break;
                            }
                            else
                            {
                                DiagnosticUtility.DebugAssert(byteOffset + actualByteCount < bytes.Length,
                                    string.Format("byteOffset {0} + actualByteCount {1} MUST BE < bytes.Length {2}", byteOffset, actualByteCount, bytes.Length));
 
                                // Request a few more bytes to get at least one character
                                actualCharCount = decoder.GetChars(bytes, byteOffset + actualByteCount, 1, chars, charOffset);
                                actualByteCount++;
                            }
                        }
 
                        // Now that we actually retrieved some characters, figure out how many bytes it actually was
                        actualByteCount = encoding.GetByteCount(chars, charOffset, actualCharCount);
                    }
                }
                catch (FormatException exception)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateEncodingException(bytes, byteOffset, byteCount, exception));
                }
 
                // Advance
                byteOffset += actualByteCount;
                byteCount -= actualByteCount;
 
                charOffset += actualCharCount;
                charCount -= actualCharCount;
            }
 
            _offset = byteOffset;
            _length = byteCount;
 
            actual = (count - charCount);
            return true;
        }
 
        private bool TryReadUnicodeChars(char[] chars, int offset, int count, out int actual)
        {
            int charCount = Math.Min(count, _length / sizeof(char));
            for (int i = 0; i < charCount; i++)
            {
                chars[offset + i] = (char)_bufferReader.GetInt16(_offset + i * sizeof(char));
            }
            _offset += charCount * sizeof(char);
            _length -= charCount * sizeof(char);
            actual = charCount;
            return true;
        }
 
        public bool TryGetDictionaryString(out XmlDictionaryString value)
        {
            if (_type == ValueHandleType.Dictionary)
            {
                value = GetDictionaryString();
                return true;
            }
            else
            {
                value = null;
                return false;
            }
        }
 
        public bool TryGetByteArrayLength(out int length)
        {
            if (_type == ValueHandleType.Base64)
            {
                length = _length;
                return true;
            }
            length = 0;
            return false;
        }
        private string GetCharsText()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.UTF8, "");
            if (_length == 1 && _bufferReader.GetByte(_offset) == '1')
                return "1";
            return _bufferReader.GetString(_offset, _length);
        }
 
        private string GetUnicodeCharsText()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Unicode, "");
            return _bufferReader.GetUnicodeString(_offset, _length);
        }
 
        private string GetEscapedCharsText()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.EscapedUTF8, "");
            return _bufferReader.GetEscapedString(_offset, _length);
        }
        private string GetCharText()
        {
            int ch = GetChar();
            if (ch > char.MaxValue)
            {
                SurrogateChar surrogate = new SurrogateChar(ch);
                char[] chars = new char[2];
                chars[0] = surrogate.HighChar;
                chars[1] = surrogate.LowChar;
                return new string(chars, 0, 2);
            }
            else
            {
                return ((char)ch).ToString();
            }
        }
 
        private int GetChar()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Char, "");
            return _offset;
        }
 
        private int GetInt8()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Int8, "");
            return _bufferReader.GetInt8(_offset);
        }
 
        private int GetInt16()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Int16, "");
            return _bufferReader.GetInt16(_offset);
        }
 
        private int GetInt32()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Int32, "");
            return _bufferReader.GetInt32(_offset);
        }
 
        private long GetInt64()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Int64 || _type == ValueHandleType.TimeSpan || _type == ValueHandleType.DateTime, "");
            return _bufferReader.GetInt64(_offset);
        }
 
        private ulong GetUInt64()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.UInt64, "");
            return _bufferReader.GetUInt64(_offset);
        }
 
        private float GetSingle()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Single, "");
            return _bufferReader.GetSingle(_offset);
        }
 
        private double GetDouble()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Double, "");
            return _bufferReader.GetDouble(_offset);
        }
 
        private decimal GetDecimal()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Decimal, "");
            return _bufferReader.GetDecimal(_offset);
        }
 
        private UniqueId GetUniqueId()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.UniqueId, "");
            return _bufferReader.GetUniqueId(_offset);
        }
 
        private Guid GetGuid()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Guid, "");
            return _bufferReader.GetGuid(_offset);
        }
 
        private void GetBase64(byte[] buffer, int offset, int count)
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Base64, "");
            _bufferReader.GetBase64(_offset, buffer, offset, count);
        }
 
        private XmlDictionaryString GetDictionaryString()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.Dictionary, "");
            return _bufferReader.GetDictionaryString(_offset);
        }
 
        private string GetQNameDictionaryText()
        {
            DiagnosticUtility.DebugAssert(_type == ValueHandleType.QName, "");
            return string.Concat(PrefixHandle.GetString(PrefixHandle.GetAlphaPrefix(_length)), ":", _bufferReader.GetDictionaryString(_offset));
        }
    }
}