﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System.IO;
using Apache.NMS.Util;
using NUnit.Framework;

namespace Apache.NMS.Test
{
	[TestFixture]
	public class EndianBinaryReaderTest
	{
		public void readString16Helper(byte[] input, char[] expect)
		{
			MemoryStream stream = new MemoryStream(input);
			EndianBinaryReader reader = new EndianBinaryReader(stream);

			char[] result = reader.ReadString16().ToCharArray();

			for(int i = 0; i < expect.Length; ++i)
			{
				Assert.AreEqual(expect[i], result[i]);
			}
		}

		[Test]
		public void testReadString16_1byteUTF8encoding()
		{
			// Test data with 1-byte UTF8 encoding.
			char[] expect = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
			byte[] input = { 0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };

			readString16Helper(input, expect);
		}

		[Test]
		public void testReadString16_2byteUTF8encoding()
		{
			// Test data with 2-byte UT8 encoding.
			char[] expect = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
			byte[] input = { 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
			readString16Helper(input, expect);
		}

		[Test]
		public void testReadString16_1byteAnd2byteEmbeddedNULLs()
		{
			// Test data with 1-byte and 2-byte encoding with embedded NULL's.
			char[] expect = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
			byte[] input = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

			readString16Helper(input, expect);
		}

		[Test]
		[ExpectedException(typeof(IOException))]
		public void testReadString16_UTF8Missing2ndByte()
		{
			// Test with bad UTF-8 encoding, missing 2nd byte of two byte value
			byte[] input = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

			MemoryStream stream = new MemoryStream(input);
			EndianBinaryReader reader = new EndianBinaryReader(stream);

			reader.ReadString16();
		}

		[Test]
		[ExpectedException(typeof(IOException))]
		public void testReadString16_3byteEncodingMissingLastByte()
		{
			// Test with three byte encode that's missing a last byte.
			byte[] input = { 0x00, 0x02, 0xE8, 0xA8 };

			MemoryStream stream = new MemoryStream(input);
			EndianBinaryReader reader = new EndianBinaryReader(stream);

			reader.ReadString16();
		}

		public void readString32Helper(byte[] input, char[] expect)
		{
			MemoryStream stream = new MemoryStream(input);
			EndianBinaryReader reader = new EndianBinaryReader(stream);

			char[] result = reader.ReadString32().ToCharArray();

			for(int i = 0; i < expect.Length; ++i)
			{
				Assert.AreEqual(expect[i], result[i]);
			}
		}

		[Test]
		public void testReadString32_1byteUTF8encoding()
		{
			// Test data with 1-byte UTF8 encoding.
			char[] expect = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
			byte[] input = { 0x00, 0x00, 0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };

			readString32Helper(input, expect);
		}

		[Test]
		public void testReadString32_2byteUTF8encoding()
		{
			// Test data with 2-byte UT8 encoding.
			char[] expect = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
			byte[] input = { 0x00, 0x00, 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };
			readString32Helper(input, expect);
		}

		[Test]
		public void testReadString32_1byteAnd2byteEmbeddedNULLs()
		{
			// Test data with 1-byte and 2-byte encoding with embedded NULL's.
			char[] expect = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
			byte[] input = { 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

			readString32Helper(input, expect);
		}

		[Test]
		[ExpectedException(typeof(IOException))]
		public void testReadString32_UTF8Missing2ndByte()
		{
			// Test with bad UTF-8 encoding, missing 2nd byte of two byte value
			byte[] input = { 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

			MemoryStream stream = new MemoryStream(input);
			EndianBinaryReader reader = new EndianBinaryReader(stream);

			reader.ReadString32();
		}

		[Test]
		[ExpectedException(typeof(IOException))]
		public void testReadString32_3byteEncodingMissingLastByte()
		{
			// Test with three byte encode that's missing a last byte.
			byte[] input = { 0x00, 0x00, 0x00, 0x02, 0xE8, 0xA8 };

			MemoryStream stream = new MemoryStream(input);
			EndianBinaryReader reader = new EndianBinaryReader(stream);

			reader.ReadString32();
		}
	}
}
