|  | @@ -481,7 +481,33 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  |          public double ReadDouble()
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());
 | 
	
		
			
				|  |  | +            if (bufferPos + 8 <= bufferSize)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                if (BitConverter.IsLittleEndian)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    var result = BitConverter.ToDouble(buffer, bufferPos);
 | 
	
		
			
				|  |  | +                    bufferPos += 8;
 | 
	
		
			
				|  |  | +                    return result;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    var bytes = new byte[8];
 | 
	
		
			
				|  |  | +                    bytes[0] = buffer[bufferPos + 7];
 | 
	
		
			
				|  |  | +                    bytes[1] = buffer[bufferPos + 6];
 | 
	
		
			
				|  |  | +                    bytes[2] = buffer[bufferPos + 5];
 | 
	
		
			
				|  |  | +                    bytes[3] = buffer[bufferPos + 4];
 | 
	
		
			
				|  |  | +                    bytes[4] = buffer[bufferPos + 3];
 | 
	
		
			
				|  |  | +                    bytes[5] = buffer[bufferPos + 2];
 | 
	
		
			
				|  |  | +                    bytes[6] = buffer[bufferPos + 1];
 | 
	
		
			
				|  |  | +                    bytes[7] = buffer[bufferPos];
 | 
	
		
			
				|  |  | +                    bufferPos += 8;
 | 
	
		
			
				|  |  | +                    return BitConverter.ToDouble(bytes, 0);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                return BitConverter.Int64BitsToDouble((long)ReadRawLittleEndian64());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -711,7 +737,126 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |              return false;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        #endregion
 | 
	
		
			
				|  |  | +        internal static double? ReadDoubleWrapperLittleEndian(CodedInputStream input)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            // tag:1 + value:8 = 9 bytes
 | 
	
		
			
				|  |  | +            const int expectedLength = 9;
 | 
	
		
			
				|  |  | +            // field=1, type=64-bit = tag of 9
 | 
	
		
			
				|  |  | +            const int expectedTag = 9;
 | 
	
		
			
				|  |  | +            // length:1 + tag:1 + value:8 = 10 bytes
 | 
	
		
			
				|  |  | +            if (input.bufferPos + 10 <= input.bufferSize)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                int length = input.buffer[input.bufferPos];
 | 
	
		
			
				|  |  | +                if (length == 0)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    input.bufferPos++;
 | 
	
		
			
				|  |  | +                    return 0D;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (length != expectedLength)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    throw InvalidProtocolBufferException.InvalidWrapperMessageLength();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                // field=1, type=64-bit = tag of 9
 | 
	
		
			
				|  |  | +                if (input.buffer[input.bufferPos + 1] != expectedTag)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    throw InvalidProtocolBufferException.InvalidWrapperMessageTag();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                var result = BitConverter.ToDouble(input.buffer, input.bufferPos + 2);
 | 
	
		
			
				|  |  | +                input.bufferPos += 10;
 | 
	
		
			
				|  |  | +                return result;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                int length = input.ReadLength();
 | 
	
		
			
				|  |  | +                if (length == 0)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    return 0D;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (length != expectedLength)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    throw InvalidProtocolBufferException.InvalidWrapperMessageLength();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (input.ReadTag() != expectedTag)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    throw InvalidProtocolBufferException.InvalidWrapperMessageTag();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                return input.ReadDouble();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        internal static double? ReadDoubleWrapperBigEndian(CodedInputStream input)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            int length = input.ReadLength();
 | 
	
		
			
				|  |  | +            if (length == 0)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                return 0D;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            // tag:1 + value:8 = 9 bytes
 | 
	
		
			
				|  |  | +            if (length != 9)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                throw InvalidProtocolBufferException.InvalidWrapperMessageLength();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            // field=1, type=64-bit = tag of 9
 | 
	
		
			
				|  |  | +            if (input.ReadTag() != 9)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                throw InvalidProtocolBufferException.InvalidWrapperMessageTag();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            return input.ReadDouble();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        internal static long? ReadInt64Wrapper(CodedInputStream input)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            // field=1, type=varint = tag of 8
 | 
	
		
			
				|  |  | +            const int expectedTag = 8;
 | 
	
		
			
				|  |  | +            // length:1 + tag:1 + value:10(varint64-max) = 12 bytes
 | 
	
		
			
				|  |  | +            if (input.bufferPos + 12 <= input.bufferSize)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                int length = input.buffer[input.bufferPos++];
 | 
	
		
			
				|  |  | +                if (length == 0)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    return 0L;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                // Length will always fit in a single byte.
 | 
	
		
			
				|  |  | +                if (length >= 128)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    throw InvalidProtocolBufferException.InvalidWrapperMessageLength();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                int finalBufferPos = input.bufferPos + length;
 | 
	
		
			
				|  |  | +                if (input.buffer[input.bufferPos++] != expectedTag)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    throw InvalidProtocolBufferException.InvalidWrapperMessageTag();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                var result = input.ReadInt64();
 | 
	
		
			
				|  |  | +                // Verify this message only contained a single field.
 | 
	
		
			
				|  |  | +                if (input.bufferPos != finalBufferPos)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    throw InvalidProtocolBufferException.InvalidWrapperMessageExtraFields();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                return result;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                int length = input.ReadLength();
 | 
	
		
			
				|  |  | +                if (length == 0)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    return 0L;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                int finalBufferPos = input.totalBytesRetired + input.bufferPos + length;
 | 
	
		
			
				|  |  | +                if (input.ReadTag() != expectedTag)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    throw InvalidProtocolBufferException.InvalidWrapperMessageTag();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                var result = input.ReadInt64();
 | 
	
		
			
				|  |  | +                // Verify this message only contained a single field.
 | 
	
		
			
				|  |  | +                if (input.totalBytesRetired + input.bufferPos != finalBufferPos)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    throw InvalidProtocolBufferException.InvalidWrapperMessageExtraFields();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                return result;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +#endregion
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          #region Underlying reading primitives
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -876,17 +1021,42 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  |          internal ulong ReadRawVarint64()
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            int shift = 0;
 | 
	
		
			
				|  |  | -            ulong result = 0;
 | 
	
		
			
				|  |  | -            while (shift < 64)
 | 
	
		
			
				|  |  | +            if (bufferPos + 10 <= bufferSize)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                byte b = ReadRawByte();
 | 
	
		
			
				|  |  | -                result |= (ulong) (b & 0x7F) << shift;
 | 
	
		
			
				|  |  | -                if ((b & 0x80) == 0)
 | 
	
		
			
				|  |  | +                ulong result = buffer[bufferPos++];
 | 
	
		
			
				|  |  | +                if (result < 128)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  |                      return result;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                shift += 7;
 | 
	
		
			
				|  |  | +                result &= 0x7f;
 | 
	
		
			
				|  |  | +                int shift = 7;
 | 
	
		
			
				|  |  | +                do
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    byte b = buffer[bufferPos++];
 | 
	
		
			
				|  |  | +                    result |= (ulong)(b & 0x7F) << shift;
 | 
	
		
			
				|  |  | +                    if (b < 0x80)
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        return result;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    shift += 7;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                while (shift < 64);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                int shift = 0;
 | 
	
		
			
				|  |  | +                ulong result = 0;
 | 
	
		
			
				|  |  | +                do
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    byte b = ReadRawByte();
 | 
	
		
			
				|  |  | +                    result |= (ulong)(b & 0x7F) << shift;
 | 
	
		
			
				|  |  | +                    if (b < 0x80)
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        return result;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    shift += 7;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                while (shift < 64);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              throw InvalidProtocolBufferException.MalformedVarint();
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -896,11 +1066,32 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  |          internal uint ReadRawLittleEndian32()
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            uint b1 = ReadRawByte();
 | 
	
		
			
				|  |  | -            uint b2 = ReadRawByte();
 | 
	
		
			
				|  |  | -            uint b3 = ReadRawByte();
 | 
	
		
			
				|  |  | -            uint b4 = ReadRawByte();
 | 
	
		
			
				|  |  | -            return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
 | 
	
		
			
				|  |  | +            if (bufferPos + 4 <= bufferSize)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                if (BitConverter.IsLittleEndian)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    var result = BitConverter.ToUInt32(buffer, bufferPos);
 | 
	
		
			
				|  |  | +                    bufferPos += 4;
 | 
	
		
			
				|  |  | +                    return result;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    uint b1 = buffer[bufferPos];
 | 
	
		
			
				|  |  | +                    uint b2 = buffer[bufferPos + 1];
 | 
	
		
			
				|  |  | +                    uint b3 = buffer[bufferPos + 2];
 | 
	
		
			
				|  |  | +                    uint b4 = buffer[bufferPos + 3];
 | 
	
		
			
				|  |  | +                    bufferPos += 4;
 | 
	
		
			
				|  |  | +                    return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                uint b1 = ReadRawByte();
 | 
	
		
			
				|  |  | +                uint b2 = ReadRawByte();
 | 
	
		
			
				|  |  | +                uint b3 = ReadRawByte();
 | 
	
		
			
				|  |  | +                uint b4 = ReadRawByte();
 | 
	
		
			
				|  |  | +                return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -908,16 +1099,42 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  |          internal ulong ReadRawLittleEndian64()
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            ulong b1 = ReadRawByte();
 | 
	
		
			
				|  |  | -            ulong b2 = ReadRawByte();
 | 
	
		
			
				|  |  | -            ulong b3 = ReadRawByte();
 | 
	
		
			
				|  |  | -            ulong b4 = ReadRawByte();
 | 
	
		
			
				|  |  | -            ulong b5 = ReadRawByte();
 | 
	
		
			
				|  |  | -            ulong b6 = ReadRawByte();
 | 
	
		
			
				|  |  | -            ulong b7 = ReadRawByte();
 | 
	
		
			
				|  |  | -            ulong b8 = ReadRawByte();
 | 
	
		
			
				|  |  | -            return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)
 | 
	
		
			
				|  |  | -                   | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
 | 
	
		
			
				|  |  | +            if (bufferPos + 8 <= bufferSize)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                if (BitConverter.IsLittleEndian)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    var result = BitConverter.ToUInt64(buffer, bufferPos);
 | 
	
		
			
				|  |  | +                    bufferPos += 8;
 | 
	
		
			
				|  |  | +                    return result;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    ulong b1 = buffer[bufferPos];
 | 
	
		
			
				|  |  | +                    ulong b2 = buffer[bufferPos + 1];
 | 
	
		
			
				|  |  | +                    ulong b3 = buffer[bufferPos + 2];
 | 
	
		
			
				|  |  | +                    ulong b4 = buffer[bufferPos + 3];
 | 
	
		
			
				|  |  | +                    ulong b5 = buffer[bufferPos + 4];
 | 
	
		
			
				|  |  | +                    ulong b6 = buffer[bufferPos + 5];
 | 
	
		
			
				|  |  | +                    ulong b7 = buffer[bufferPos + 6];
 | 
	
		
			
				|  |  | +                    ulong b8 = buffer[bufferPos + 7];
 | 
	
		
			
				|  |  | +                    bufferPos += 8;
 | 
	
		
			
				|  |  | +                    return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)
 | 
	
		
			
				|  |  | +                           | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                ulong b1 = ReadRawByte();
 | 
	
		
			
				|  |  | +                ulong b2 = ReadRawByte();
 | 
	
		
			
				|  |  | +                ulong b3 = ReadRawByte();
 | 
	
		
			
				|  |  | +                ulong b4 = ReadRawByte();
 | 
	
		
			
				|  |  | +                ulong b5 = ReadRawByte();
 | 
	
		
			
				|  |  | +                ulong b6 = ReadRawByte();
 | 
	
		
			
				|  |  | +                ulong b7 = ReadRawByte();
 | 
	
		
			
				|  |  | +                ulong b8 = ReadRawByte();
 | 
	
		
			
				|  |  | +                return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)
 | 
	
		
			
				|  |  | +                       | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -1301,6 +1518,6 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        #endregion
 | 
	
		
			
				|  |  | +#endregion
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |