utf7encoding.cs

来自「没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没」· CS 代码 · 共 799 行 · 第 1/2 页

CS
799
字号
/* * UTF7Encoding.cs - Implementation of the *		"System.Text.UTF7Encoding" class. * * Copyright (C) 2001  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{using System;[Serializable]#if ECMA_COMPATinternal#elsepublic#endifclass UTF7Encoding : Encoding{	// Magic number used by Windows for UTF-7.	internal const int UTF7_CODE_PAGE = 65000;	// Internal state.	private bool allowOptionals;	// Encoding rule table for 0x00-0x7F.	// 0 - full encode, 1 - direct, 2 - optional, 3 - encode plus.	private static readonly byte[] encodingRules = {		0, 0, 0, 0, 0, 0, 0, 0,   0, 1, 1, 0, 0, 1, 0, 0,	// 00		0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,	// 10		1, 2, 2, 2, 2, 2, 2, 1,   1, 1, 2, 3, 1, 1, 1, 1,	// 20		1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 2, 2, 2, 2, 1,	// 30		2, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,	// 40		1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 2, 0, 2, 2, 2,	// 50		2, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,	// 60		1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 2, 2, 2, 0, 0,	// 70	};	// Characters to use to encode 6-bit values in base64.	private const String base64Chars =		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";	// Map bytes in base64 to 6-bit values.	private static readonly sbyte[] base64Values = {		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // 00		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // 10		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, 62, -1, -1, 63, // 20		52, 53, 54, 55, 56, 57, 58, 59,   60, 61, -1, -1, -1, -1, -1, -1, // 30		 0,  1,  2,  3,  4,  5,  6,  7,    8,  9, 10, 11, 12, 13, 14, 15, // 40		16, 17, 18, 19, 20, 21, 22, 23,   24, 25, -1, -1, -1, -1, -1, -1, // 50		26, 27, 28, 29, 30, 31, 32, 33,   34, 35, 36, 37, 38, 39, 40, 41, // 60		42, 43, 44, 45, 46, 47, 48, 49,   50, 51, -1, -1, -1, -1, -1, -1, // 70		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // 80		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // 90		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // A0		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // B0		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // C0		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // D0		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // E0		-1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // F0	};	// Constructors.	public UTF7Encoding()			: base(UTF7_CODE_PAGE)			{				allowOptionals = false;			}	public UTF7Encoding(bool allowOptionals)			: base(UTF7_CODE_PAGE)			{				this.allowOptionals = allowOptionals;			}	// Internal version of "GetByteCount" that can handle	// a rolling state between calls.	private static int InternalGetByteCount				(char[] chars, int index, int count, bool flush,				 int leftOver, bool allowOptionals)			{				// Validate the parameters.				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"));				}				// Determine the length of the output.				int length = 0;				int leftOverSize = (leftOver >> 8);				byte[] rules = encodingRules;				int ch, rule;				while(count > 0)				{					ch = (int)(chars[index++]);					--count;					if(ch < 0x0080)					{						rule = rules[ch];					}					else					{						rule = 0;					}					switch(rule)					{						case 0:						{							// Handle characters that must be fully encoded.							if(leftOverSize == 0)							{								++length;							}							leftOverSize += 16;							while(leftOverSize >= 6)							{								++length;								leftOverSize -= 6;							}						}						break;						case 1:						{							// The character is encoded as itself.							if(leftOverSize != 0)							{								// Flush the previous encoded sequence.								length += 2;								leftOverSize = 0;							}							++length;						}						break;						case 2:						{							// The character may need to be encoded.							if(allowOptionals)							{								goto case 1;							}							else							{								goto case 0;							}						}						// Not reached.						case 3:						{							// Encode the plus sign as "+-".							if(leftOverSize != 0)							{								// Flush the previous encoded sequence.								length += 2;								leftOverSize = 0;							}							length += 2;						}						break;					}				}				if(leftOverSize != 0 && flush)				{					length += 2;				}				// Return the length to the caller.				return length;			}	// Get the number of bytes needed to encode a character buffer.	public override int GetByteCount(char[] chars, int index, int count)			{				return InternalGetByteCount(chars, index, count,											true, 0, allowOptionals);			}	// Internal version of "GetBytes" that can handle a	// rolling state between calls.	private static int InternalGetBytes				(char[] chars, int charIndex, int charCount,				 byte[] bytes, int byteIndex, bool flush,				 ref int leftOver, bool allowOptionals)			{				// Validate the parameters.				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"));				}				// Convert the characters.				int posn = byteIndex;				int byteLength = bytes.Length;				int leftOverSize = (leftOver >> 8);				int leftOverBits = (leftOver & 0xFF);				byte[] rules = encodingRules;				String base64 = base64Chars;				int ch, rule;				while(charCount > 0)				{					ch = (int)(chars[charIndex++]);					--charCount;					if(ch < 0x0080)					{						rule = rules[ch];					}					else					{						rule = 0;					}					switch(rule)					{						case 0:						{							// Handle characters that must be fully encoded.							if(leftOverSize == 0)							{								if(posn >= byteLength)								{									throw new ArgumentException										(_("Arg_InsufficientSpace"), "bytes");								}								bytes[posn++] = (byte)'+';							}							leftOverBits = ((leftOverBits << 16) | ch);							leftOverSize += 16;							while(leftOverSize >= 6)							{								if(posn >= byteLength)								{									throw new ArgumentException										(_("Arg_InsufficientSpace"), "bytes");								}								leftOverSize -= 6;								bytes[posn++] = (byte)(base64									[leftOverBits >> leftOverSize]);								leftOverBits &= ((1 << leftOverSize) - 1);							}						}						break;						case 1:						{							// The character is encoded as itself.							if(leftOverSize != 0)							{								// Flush the previous encoded sequence.								if((posn + 2) > byteLength)								{									throw new ArgumentException										(_("Arg_InsufficientSpace"), "bytes");								}								bytes[posn++] = (byte)(base64									[leftOverBits << (6 - leftOverSize)]);								bytes[posn++] = (byte)'-';								leftOverSize = 0;								leftOverBits = 0;							}							if(posn >= byteLength)							{								throw new ArgumentException									(_("Arg_InsufficientSpace"), "bytes");							}							bytes[posn++] = (byte)ch;						}						break;						case 2:						{							// The character may need to be encoded.							if(allowOptionals)							{								goto case 1;							}							else							{								goto case 0;							}						}						// Not reached.						case 3:						{							// Encode the plus sign as "+-".							if(leftOverSize != 0)							{								// Flush the previous encoded sequence.								if((posn + 2) > byteLength)								{									throw new ArgumentException										(_("Arg_InsufficientSpace"), "bytes");								}								bytes[posn++] = (byte)(base64									[leftOverBits << (6 - leftOverSize)]);								bytes[posn++] = (byte)'-';								leftOverSize = 0;								leftOverBits = 0;							}							if((posn + 2) > byteLength)							{								throw new ArgumentException									(_("Arg_InsufficientSpace"), "bytes");							}							bytes[posn++] = (byte)'+';							bytes[posn++] = (byte)'-';						}						break;					}				}				if(leftOverSize != 0 && flush)				{					if((posn + 2) > byteLength)					{						throw new ArgumentException							(_("Arg_InsufficientSpace"), "bytes");					}					bytes[posn++] = (byte)(base64						[leftOverBits << (6 - leftOverSize)]);					bytes[posn++] = (byte)'-';					leftOverSize = 0;					leftOverBits = 0;				}				leftOver = ((leftOverSize << 8) | leftOverBits);				// Return the length to the caller.				return posn - byteIndex;			}	// Get the bytes that result from encoding a character buffer.	public override int GetBytes(char[] chars, int charIndex, int charCount,								 byte[] bytes, int byteIndex)			{				int leftOver = 0;				return InternalGetBytes(chars, charIndex, charCount,									    bytes, byteIndex, true,										ref leftOver, allowOptionals);			}	// Internal version of "GetCharCount" that can handle	// a rolling state between call.s	private static int InternalGetCharCount					(byte[] bytes, int index, int count, int leftOver)			{				// Validate the parameters.				if(bytes == null)				{					throw new ArgumentNullException("bytes");				}				if(index < 0 || index > bytes.Length)				{					throw new ArgumentOutOfRangeException

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?