utf32encoding.cs
来自「没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没」· CS 代码 · 共 813 行 · 第 1/2 页
CS
813 行
/* * UTF32Encoding.cs - Implementation of the "System.Text.UTF32Encoding" class. * * Copyright (C) 2003 Southern Storm Software, Pty Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */namespace System.Text{#if !ECMA_COMPAT && CONFIG_FRAMEWORK_1_2public class UTF32Encoding : Encoding#elseinternal class UTF32Encoding : Encoding#endif{ // Code page numbers for UTF32. internal const int UTF32_CODE_PAGE = 12000; internal const int UTF32_BIG_ENDIAN_CODE_PAGE = 12001; // Byte ordering for UCS-4 streams. private enum ByteOrder { Order_1234, Order_4321, Order_3412, Order_2143 }; // enum ByteOrder // Internal state. private ByteOrder byteOrder; private bool byteOrderMark; private bool throwOnInvalidChars; // Constructors. public UTF32Encoding() : this(false, true, false) {} public UTF32Encoding(bool bigEndian, bool byteOrderMark) : this(bigEndian, byteOrderMark, false) {} public UTF32Encoding(bool bigEndian, bool byteOrderMark, bool throwOnInvalidChars) : base(bigEndian ? UTF32_BIG_ENDIAN_CODE_PAGE : UTF32_CODE_PAGE) { if(bigEndian) { byteOrder = ByteOrder.Order_1234; } else { byteOrder = ByteOrder.Order_4321; } this.byteOrderMark = byteOrderMark; this.throwOnInvalidChars = throwOnInvalidChars; } // Get the number of bytes needed to encode a character buffer. public override int GetByteCount(char[] chars, int index, int count) { if(chars == null) { throw new ArgumentNullException("chars"); } if(index < 0 || index > chars.Length) { throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array")); } if(count < 0 || count > (chars.Length - index)) { throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array")); } int bytes = 0; char ch; while(count > 0) { ch = chars[index++]; --count; if(ch >= '\uD800' && ch <= '\uDBFF') { // Possibly the start of a surrogate pair. if(count > 0) { ch = chars[index]; if(ch >= '\uDC00' && ch <= '\uDFFF') { ++index; --count; } } } bytes += 4; } return bytes; } // Get the bytes that result from encoding a character buffer. public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { if(chars == null) { throw new ArgumentNullException("chars"); } if(bytes == null) { throw new ArgumentNullException("bytes"); } if(charIndex < 0 || charIndex > chars.Length) { throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array")); } if(charCount < 0 || charCount > (chars.Length - charIndex)) { throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array")); } if(byteIndex < 0 || byteIndex > bytes.Length) { throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array")); } int posn = byteIndex; int left = bytes.Length - byteIndex; uint pair; char ch; switch(byteOrder) { case ByteOrder.Order_1234: { while(charCount-- > 0) { if(left < 4) { throw new ArgumentException (_("Arg_InsufficientSpace")); } ch = chars[charIndex++]; if(ch >= '\uD800' && ch <= '\uDBFF' && charCount > 0 && chars[charIndex] >= '\uDC00' && chars[charIndex] <= '\uDFFF') { pair = ((uint)(ch - '\uD800')) << 10; ch = chars[charIndex++]; --charCount; pair += ((uint)(ch - '\uDC00')) + (uint)0x10000; bytes[posn++] = (byte)(pair >> 24); bytes[posn++] = (byte)(pair >> 16); bytes[posn++] = (byte)(pair >> 8); bytes[posn++] = (byte)pair; } else { bytes[posn++] = (byte)0; bytes[posn++] = (byte)0; bytes[posn++] = (byte)(ch >> 8); bytes[posn++] = (byte)ch; } left -= 4; } } break; case ByteOrder.Order_4321: { while(charCount-- > 0) { if(left < 4) { throw new ArgumentException (_("Arg_InsufficientSpace")); } ch = chars[charIndex++]; if(ch >= '\uD800' && ch <= '\uDBFF' && charCount > 0 && chars[charIndex] >= '\uDC00' && chars[charIndex] <= '\uDFFF') { pair = ((uint)(ch - '\uD800')) << 10; ch = chars[charIndex++]; --charCount; pair += ((uint)(ch - '\uDC00')) + (uint)0x10000; bytes[posn++] = (byte)pair; bytes[posn++] = (byte)(pair >> 8); bytes[posn++] = (byte)(pair >> 16); bytes[posn++] = (byte)(pair >> 24); } else { bytes[posn++] = (byte)ch; bytes[posn++] = (byte)(ch >> 8); bytes[posn++] = (byte)0; bytes[posn++] = (byte)0; } left -= 4; } } break; case ByteOrder.Order_3412: { while(charCount-- > 0) { if(left < 4) { throw new ArgumentException (_("Arg_InsufficientSpace")); } ch = chars[charIndex++]; if(ch >= '\uD800' && ch <= '\uDBFF' && charCount > 0 && chars[charIndex] >= '\uDC00' && chars[charIndex] <= '\uDFFF') { pair = ((uint)(ch - '\uD800')) << 10; ch = chars[charIndex++]; --charCount; pair += ((uint)(ch - '\uDC00')) + (uint)0x10000; bytes[posn++] = (byte)(pair >> 8); bytes[posn++] = (byte)pair; bytes[posn++] = (byte)(pair >> 24); bytes[posn++] = (byte)(pair >> 16); } else { bytes[posn++] = (byte)(ch >> 8); bytes[posn++] = (byte)ch; bytes[posn++] = (byte)0; bytes[posn++] = (byte)0; } left -= 4; } } break; case ByteOrder.Order_2143: { while(charCount-- > 0) { if(left < 4) { throw new ArgumentException (_("Arg_InsufficientSpace")); } ch = chars[charIndex++]; if(ch >= '\uD800' && ch <= '\uDBFF' && charCount > 0 && chars[charIndex] >= '\uDC00' && chars[charIndex] <= '\uDFFF') { pair = ((uint)(ch - '\uD800')) << 10; ch = chars[charIndex++]; --charCount; pair += ((uint)(ch - '\uDC00')) + (uint)0x10000; bytes[posn++] = (byte)(pair >> 16); bytes[posn++] = (byte)(pair >> 24); bytes[posn++] = (byte)pair; bytes[posn++] = (byte)(pair >> 8); } else { bytes[posn++] = (byte)0; bytes[posn++] = (byte)0; bytes[posn++] = (byte)ch; bytes[posn++] = (byte)(ch >> 8); } left -= 4; } } break; } return posn - byteIndex; } // Read a 4-byte character from an array. private static uint ReadChar(ByteOrder byteOrder, byte[] array, int index) { switch(byteOrder) { case ByteOrder.Order_1234: { return (((uint)(array[index])) << 24) | (((uint)(array[index + 1])) << 16) | (((uint)(array[index + 2])) << 8) | ((uint)(array[index + 3])); } // Not reached. case ByteOrder.Order_4321: { return (((uint)(array[index + 3])) << 24) | (((uint)(array[index + 2])) << 16) | (((uint)(array[index + 1])) << 8) | ((uint)(array[index])); } // Not reached. case ByteOrder.Order_3412: { return (((uint)(array[index + 2])) << 24) | (((uint)(array[index + 3])) << 16) | (((uint)(array[index])) << 8) | ((uint)(array[index + 1])); } // Not reached. case ByteOrder.Order_2143: { return (((uint)(array[index + 1])) << 24) | (((uint)(array[index])) << 16) | (((uint)(array[index + 3])) << 8) | ((uint)(array[index + 2])); } // Not reached. } return 0; } // Internal version of "GetCharCount". private static int InternalGetCharCount (ByteOrder byteOrder, byte[] leftOver, int leftOverLen, byte[] bytes, int index, int count) { // Validate the parameters. if(bytes == null) { throw new ArgumentNullException("bytes"); } if(index < 0 || index > bytes.Length) { throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array")); } if(count < 0 || count > (bytes.Length - index)) { throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array")); } // Handle the left-over buffer. int chars = 0; uint value; if(leftOverLen > 0) { if((leftOverLen + count) < 4) { return 0; } Array.Copy(bytes, index, leftOver, leftOverLen, 4 - leftOverLen); value = ReadChar(byteOrder, leftOver, 0); if(value != (uint)0x0000FEFF) { if(value > (uint)0x0000FFFF) { chars += 2; } else { ++chars; } } index += 4 - leftOverLen; count -= 4 - leftOverLen; } // Handle the main buffer contents. while(count >= 4) { value = ReadChar(byteOrder, bytes, index); if(value != (uint)0x0000FEFF) { if(value > (uint)0x0000FFFF) { chars += 2; } else { ++chars; } } index += 4; count -= 4; } return chars; } // Get the number of characters needed to decode a byte buffer. public override int GetCharCount(byte[] bytes, int index, int count) { return InternalGetCharCount(byteOrder, null, 0, bytes, index, count);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?