1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.Generic; 6 using System.Text; 7 using Xunit; 8 9 namespace System.Text.Encodings.Tests 10 { 11 public class EncoderMiscTests 12 { 13 [Fact] ConvertTest()14 public static unsafe void ConvertTest() 15 { 16 string s1 = "This is simple ascii string"; 17 string s2 = "\uD800\uDC00\u0200"; // non ascii letters 18 string s3 = s1 + s2; 19 20 Encoding utf8 = Encoding.UTF8; 21 Encoder encoder = utf8.GetEncoder(); 22 23 byte [] bytes1 = utf8.GetBytes(s1); 24 byte [] bytes2 = utf8.GetBytes(s2); 25 byte [] bytes3 = utf8.GetBytes(s3); 26 27 byte [] bytes = new byte[50]; 28 29 int bytesUsed; 30 int charsUsed; 31 bool completed; 32 33 fixed (char *pChars1 = s1) 34 fixed (char *pChars2 = s2) 35 fixed (char *pChars3 = s3) 36 fixed (byte *pBytes = bytes) 37 { 38 encoder.Convert(pChars1, s1.Length, pBytes, bytes.Length, true, out charsUsed, out bytesUsed, out completed); 39 Assert.Equal(s1.Length, charsUsed); 40 Assert.Equal(bytes1.Length, bytesUsed); 41 Assert.True(completed, "Expected to have the full operation compeleted with bytes1"); 42 for (int i=0; i<bytes1.Length; i++) { Assert.Equal(bytes1[i], pBytes[i]); } 43 44 encoder.Convert(pChars2, s2.Length, pBytes, bytes.Length, true, out charsUsed, out bytesUsed, out completed); 45 Assert.Equal(s2.Length, charsUsed); 46 Assert.Equal(bytes2.Length, bytesUsed); 47 Assert.True(completed, "Expected to have the full operation compeleted with bytes2"); 48 for (int i=0; i<bytes2.Length; i++) { Assert.Equal(bytes2[i], pBytes[i]); } 49 50 encoder.Convert(pChars3, s3.Length, pBytes, bytes.Length, true, out charsUsed, out bytesUsed, out completed); 51 Assert.Equal(s3.Length, charsUsed); 52 Assert.Equal(bytes3.Length, bytesUsed); 53 Assert.True(completed, "Expected to have the full operation compeleted with bytes3"); 54 for (int i=0; i<bytes3.Length; i++) { Assert.Equal(bytes3[i], pBytes[i]); } 55 56 encoder.Convert(pChars3 + s1.Length, s3.Length - s1.Length, pBytes, bytes.Length, true, out charsUsed, out bytesUsed, out completed); 57 Assert.Equal(s2.Length, charsUsed); 58 Assert.Equal(bytes2.Length, bytesUsed); 59 Assert.True(completed, "Expected to have the full operation compeleted with bytes3+bytes1.Length"); 60 for (int i=0; i<bytes2.Length; i++) { Assert.Equal(bytes2[i], pBytes[i]); } 61 62 encoder.Convert(pChars3 + s1.Length, s3.Length - s1.Length, pBytes, 4, true, out charsUsed, out bytesUsed, out completed); 63 Assert.Equal(2, charsUsed); 64 Assert.True(bytes2.Length > bytesUsed, "Expected to use less bytes when there is not enough char buffer"); 65 Assert.False(completed, "Expected to have the operation not fully completed"); 66 for (int i=0; i<bytesUsed; i++) { Assert.Equal(bytes2[i], pBytes[i]); } 67 68 encoder.Convert(pChars3 + s3.Length - 1, 1, pBytes, 2, true, out charsUsed, out bytesUsed, out completed); 69 Assert.Equal(1, charsUsed); 70 Assert.Equal(2, bytesUsed); 71 Assert.True(completed, "expected to flush the remaining character"); 72 Assert.Equal(bytes2[bytes2.Length - 2], pBytes[0]); 73 Assert.Equal(bytes2[bytes2.Length - 1], pBytes[1]); 74 } 75 } 76 77 [Fact] ConvertNegativeTest()78 public static unsafe void ConvertNegativeTest() 79 { 80 Encoder encoder = Encoding.UTF8.GetEncoder(); 81 int bytesUsed; 82 int charsUsed; 83 bool completed; 84 85 string chars = "\u0D800\uDC00"; 86 byte [] bytes = new byte[4]; 87 88 fixed (byte *bytesPtr = bytes) 89 fixed (char *charsPtr = chars) 90 { 91 byte *pBytes = bytesPtr; 92 char *pChars = charsPtr; 93 94 AssertExtensions.Throws<ArgumentNullException>("chars", () => encoder.Convert(null, chars.Length, pBytes, bytes.Length, true, out charsUsed, out bytesUsed, out completed)); 95 AssertExtensions.Throws<ArgumentNullException>("bytes", () => encoder.Convert(pChars, chars.Length, null, bytes.Length, true, out charsUsed, out bytesUsed, out completed)); 96 97 AssertExtensions.Throws<ArgumentOutOfRangeException>("byteCount", () => encoder.Convert(pChars, chars.Length, pBytes, -1, true, out charsUsed, out bytesUsed, out completed)); 98 AssertExtensions.Throws<ArgumentOutOfRangeException>("charCount", () => encoder.Convert(pChars, -1, pBytes, bytes.Length, true, out charsUsed, out bytesUsed, out completed)); 99 100 AssertExtensions.Throws<ArgumentException>("bytes", () => encoder.Convert(pChars, chars.Length, pBytes, 0, true, out charsUsed, out bytesUsed, out completed)); 101 } 102 103 encoder = Encoding.GetEncoding("us-ascii", new EncoderExceptionFallback(), new DecoderExceptionFallback()).GetEncoder(); 104 105 fixed (char *charsPtr = "\uFFFF") 106 fixed (byte *bytesPtr = new byte [2]) 107 { 108 byte *pBytes = bytesPtr; 109 char *pChars = charsPtr; 110 111 Assert.Throws<EncoderFallbackException>(() => encoder.Convert(pChars, 1, pBytes, 2, true, out charsUsed, out bytesUsed, out completed)); 112 } 113 } 114 115 [Fact] GetBytesTest()116 public static unsafe void GetBytesTest() 117 { 118 string s1 = "This is simple ascii string"; 119 string s2 = "\uD800\uDC00\u0200"; // non ascii letters 120 string s3 = s1 + s2; 121 122 Encoding utf8 = Encoding.UTF8; 123 Encoder encoder = utf8.GetEncoder(); 124 byte [] bytes = new byte[200]; 125 126 byte [] bytes1 = utf8.GetBytes(s1); 127 byte [] bytes2 = utf8.GetBytes(s2); 128 byte [] bytes3 = utf8.GetBytes(s3); 129 130 fixed (char *pChars1 = s1) 131 fixed (char *pChars2 = s2) 132 fixed (char *pChars3 = s3) 133 fixed (byte *pBytes = bytes) 134 { 135 int bytesUsed = encoder.GetBytes(pChars1, s1.Length, pBytes, bytes.Length, true); 136 Assert.Equal(bytes1.Length, bytesUsed); 137 Assert.Equal(bytes1.Length, encoder.GetByteCount(pChars1, s1.Length, true)); 138 for (int i=0; i<bytesUsed; i++) { Assert.Equal(bytes1[i], pBytes[i]); } 139 140 bytesUsed = encoder.GetBytes(pChars2, s2.Length, pBytes, bytes.Length, true); 141 Assert.Equal(bytes2.Length, bytesUsed); 142 Assert.Equal(bytes2.Length, encoder.GetByteCount(pChars2, s2.Length, true)); 143 for (int i=0; i<bytesUsed; i++) { Assert.Equal(bytes2[i], pBytes[i]); } 144 145 bytesUsed = encoder.GetBytes(pChars3, s3.Length, pBytes, bytes.Length, true); 146 Assert.Equal(bytes3.Length, bytesUsed); 147 Assert.Equal(bytes3.Length, encoder.GetByteCount(pChars3, s3.Length, true)); 148 for (int i=0; i<bytesUsed; i++) { Assert.Equal(bytes3[i], pBytes[i]); } 149 150 bytesUsed = encoder.GetBytes(pChars3 + s1.Length, s3.Length - s1.Length, pBytes, bytes.Length, true); 151 Assert.Equal(bytes2.Length, bytesUsed); 152 Assert.Equal(bytes2.Length, encoder.GetByteCount(pChars3 + s1.Length, s3.Length - s1.Length, true)); 153 for (int i=0; i<bytesUsed; i++) { Assert.Equal(bytes2[i], pBytes[i]); } 154 } 155 } 156 157 [Fact] GetBytesNegativeTest()158 public static unsafe void GetBytesNegativeTest() 159 { 160 Encoder encoder = Encoding.UTF8.GetEncoder(); 161 string s = "\u0D800\uDC00"; 162 163 fixed (char *charsPtr = s) 164 fixed (byte *bytesPtr = new byte [4]) 165 { 166 byte *pBytes = bytesPtr; 167 char *pChars = charsPtr; 168 169 AssertExtensions.Throws<ArgumentNullException>("bytes", () => encoder.GetBytes(pChars, s.Length, null, 1, true)); 170 AssertExtensions.Throws<ArgumentNullException>("chars", () => encoder.GetBytes(null, s.Length, pBytes, 4, true)); 171 AssertExtensions.Throws<ArgumentNullException>("chars", () => encoder.GetByteCount(null, s.Length, true)); 172 173 AssertExtensions.Throws<ArgumentOutOfRangeException>("charCount", () => encoder.GetBytes(pChars, -1, pBytes, 4, true)); 174 AssertExtensions.Throws<ArgumentOutOfRangeException>("byteCount", () => encoder.GetBytes(pChars, s.Length, pBytes, -1, true)); 175 AssertExtensions.Throws<ArgumentOutOfRangeException>("count", () => encoder.GetByteCount(pChars, -1, true)); 176 177 AssertExtensions.Throws<ArgumentException>("bytes", () => encoder.GetBytes(pChars, s.Length, pBytes, 1, true)); 178 } 179 180 encoder = Encoding.GetEncoding("us-ascii", new EncoderExceptionFallback(), new DecoderExceptionFallback()).GetEncoder(); 181 182 fixed (char *charsPtr = "\uFFFF") 183 fixed (byte *bytesPtr = new byte [2]) 184 { 185 byte *pBytes = bytesPtr; 186 char *pChars = charsPtr; 187 188 Assert.Throws<EncoderFallbackException>(() => encoder.GetBytes(pChars, 1, pBytes, 2, true)); 189 Assert.Throws<EncoderFallbackException>(() => encoder.GetByteCount(pChars, 1, true)); 190 } 191 } 192 193 [Fact] EncoderExceptionFallbackBufferTest()194 public static void EncoderExceptionFallbackBufferTest() 195 { 196 Encoder encoder = Encoding.GetEncoding("us-ascii", new EncoderExceptionFallback(), new DecoderExceptionFallback()).GetEncoder(); 197 198 char [] chars = new char[] { '\uFFFF' }; 199 byte [] bytes = new byte[2]; 200 201 Assert.Throws<EncoderFallbackException>(() => encoder.GetBytes(chars, 0, 1, bytes, 0, true)); 202 203 EncoderFallbackBuffer fallbackBuffer = encoder.FallbackBuffer; 204 Assert.True(fallbackBuffer is EncoderExceptionFallbackBuffer, "Expected to get EncoderExceptionFallbackBuffer type"); 205 Assert.Throws<EncoderFallbackException>(() => fallbackBuffer.Fallback(chars[0], 0)); 206 Assert.Throws<EncoderFallbackException>(() => fallbackBuffer.Fallback('\u0040', 0)); 207 Assert.Throws<EncoderFallbackException>(() => fallbackBuffer.Fallback('\uD800', '\uDC00', 0)); 208 209 Assert.Equal(0, fallbackBuffer.Remaining); 210 Assert.Equal('\u0000', fallbackBuffer.GetNextChar()); 211 212 Assert.False(fallbackBuffer.MovePrevious(), "MovePrevious expected to always return false"); 213 214 fallbackBuffer.Reset(); 215 216 Assert.Equal(0, fallbackBuffer.Remaining); 217 Assert.Equal('\u0000', fallbackBuffer.GetNextChar()); 218 219 } 220 221 [Fact] EncoderReplacementFallbackBufferTest()222 public static void EncoderReplacementFallbackBufferTest() 223 { 224 Encoder encoder = Encoding.GetEncoding("us-ascii", new EncoderReplacementFallback(), new DecoderReplacementFallback()).GetEncoder(); 225 226 char [] chars = new char [] { '\uFFFF' }; 227 byte [] bytes = new byte [2]; 228 229 EncoderFallbackBuffer fallbackBuffer = encoder.FallbackBuffer; 230 Assert.True(fallbackBuffer is EncoderReplacementFallbackBuffer, "Expected to get EncoderReplacementFallbackBuffer type"); 231 Assert.True(fallbackBuffer.Fallback(chars[0], 0), "Expected we fallback on the given buffer"); 232 Assert.Equal(1, fallbackBuffer.Remaining); 233 Assert.False(fallbackBuffer.MovePrevious(), "Expected we cannot move back on the replacement buffer as we are at the Beginning of the buffer"); 234 Assert.Equal('?', fallbackBuffer.GetNextChar()); 235 Assert.True(fallbackBuffer.MovePrevious(), "Expected we can move back on the replacement buffer"); 236 Assert.Equal('?', fallbackBuffer.GetNextChar()); 237 238 fallbackBuffer.Reset(); 239 Assert.Equal(0, fallbackBuffer.Remaining); 240 Assert.Equal('\u0000', fallbackBuffer.GetNextChar()); 241 Assert.False(fallbackBuffer.MovePrevious(), "Expected we cannot move back on the replacement buffer as we are rest the buffer"); 242 } 243 } 244 } 245