/* * CP57002.cs - ISCII code pages 57002-57011. * * Atsushi Enomoto (C) 2005 Novell, Inc. * * original copyright: * * Copyright (c) 2002 Southern Storm Software, Pty Ltd * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ namespace I18N.Other { using System; using System.Text; using I18N.Common; // This class provides an abstract base for the ISCII encodings, // which all have a similar pattern. Code points 0x00-0x7F are // the standard ASCII character set, and code points 0x80-0xFF // are a shifted version of the Unicode character set, starting // at a fixed offset. [Serializable] public abstract class ISCIIEncoding : MonoEncoding { // Internal state. int shift; string encodingName; string webName; // Constructor. protected ISCIIEncoding(int codePage, int shift, String encodingName, String webName) : base(codePage) { this.shift = shift; this.encodingName = encodingName; this.webName = webName; } // 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", Strings.GetString("ArgRange_Array")); } if(count < 0 || count > (chars.Length - index)) { throw new ArgumentOutOfRangeException ("count", Strings.GetString("ArgRange_Array")); } return count; } // Convenience wrappers for "GetByteCount". public override int GetByteCount(String s) { if(s == null) { throw new ArgumentNullException("s"); } return s.Length; } public unsafe override int GetByteCountImpl (char* chars, int count) { int index = 0; int length = 0; char ch; char first = (char)shift; char last = (char)(shift + 0x7F); while(count-- > 0) { ch = chars[index++]; if(ch < (char)0x0080) { // Regular ASCII subset. length++; } else if(ch >= first && ch <= last) { // ISCII range that we need to shift. length++; } else if(ch >= '\uFF01' && ch <= '\uFF5E') { // ASCII full-width characters. length++; } else { // FIXME: implement fallback support for GetByteCountImpl(). length++; } count--; } // Return the final length of the output. return length; } public unsafe override int GetBytesImpl (char* chars, int charCount, byte* bytes, int byteCount) { EncoderFallbackBuffer buffer = null; //int charIndex = 0; int byteIndex = 0; int end = charCount; if(chars == null) { throw new ArgumentNullException("chars"); } if(bytes == null) { throw new ArgumentNullException("bytes"); } // Convert the characters into bytes. char ch; int posn = byteIndex; char first = (char)shift; char last = (char)(shift + 0x7F); for (int i = 0; i < end; i++, charCount--) { ch = chars[i]; if(ch < (char)0x0080) { // Regular ASCII subset. bytes[posn++] = (byte)ch; } else if(ch >= first && ch <= last) { // ISCII range that we need to shift. bytes[posn++] = (byte)(ch - first + 0x80); } else if(ch >= '\uFF01' && ch <= '\uFF5E') { // ASCII full-width characters. bytes[posn++] = (byte)(ch - 0xFEE0); } else { HandleFallback (ref buffer, chars, ref i, ref charCount, bytes, ref posn, ref byteCount); continue; } byteCount--; } // Return the final length of the output. return posn - byteIndex; } /* // Convenience wrappers for "GetBytes". public override int GetBytes(String s, int charIndex, int charCount, byte[] bytes, int byteIndex) { // Validate the parameters. if(s == null) { throw new ArgumentNullException("s"); } if(bytes == null) { throw new ArgumentNullException("bytes"); } if(charIndex < 0 || charIndex > s.Length) { throw new ArgumentOutOfRangeException ("charIndex", Strings.GetString("ArgRange_StringIndex")); } if(charCount < 0 || charCount > (s.Length - charIndex)) { throw new ArgumentOutOfRangeException ("charCount", Strings.GetString("ArgRange_StringRange")); } if(byteIndex < 0 || byteIndex > bytes.Length) { throw new ArgumentOutOfRangeException ("byteIndex", Strings.GetString("ArgRange_Array")); } if((bytes.Length - byteIndex) < charCount) { throw new ArgumentException (Strings.GetString("Arg_InsufficientSpace"), "bytes"); } // Convert the characters into bytes. char ch; int posn = byteIndex; char first = (char)shift; char last = (char)(shift + 0x7F); while(charCount-- > 0) { ch = s[charIndex++]; if(ch < (char)0x0080) { // Regular ASCII subset. bytes[posn++] = (byte)ch; } else if(ch >= first && ch <= last) { // ISCII range that we need to shift. bytes[posn++] = (byte)(ch - first + 0x80); } else if(ch >= '\uFF01' && ch <= '\uFF5E') { // ASCII full-width characters. bytes[posn++] = (byte)(ch - 0xFEE0); } else { bytes[posn++] = (byte)'?'; } } // Return the final length of the output. return posn - byteIndex; } */ // Get the number of characters needed to decode a byte buffer. public override int GetCharCount(byte[] bytes, int index, int count) { if(bytes == null) { throw new ArgumentNullException("bytes"); } if(index < 0 || index > bytes.Length) { throw new ArgumentOutOfRangeException ("index", Strings.GetString("ArgRange_Array")); } if(count < 0 || count > (bytes.Length - index)) { throw new ArgumentOutOfRangeException ("count", Strings.GetString("ArgRange_Array")); } return count; } // Get the characters that result from decoding a byte buffer. public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { // Validate the parameters. if(bytes == null) { throw new ArgumentNullException("bytes"); } if(chars == null) { throw new ArgumentNullException("chars"); } if(byteIndex < 0 || byteIndex > bytes.Length) { throw new ArgumentOutOfRangeException ("byteIndex", Strings.GetString("ArgRange_Array")); } if(byteCount < 0 || byteCount > (bytes.Length - byteIndex)) { throw new ArgumentOutOfRangeException ("byteCount", Strings.GetString("ArgRange_Array")); } if(charIndex < 0 || charIndex > chars.Length) { throw new ArgumentOutOfRangeException ("charIndex", Strings.GetString("ArgRange_Array")); } if((chars.Length - charIndex) < byteCount) { throw new ArgumentException (Strings.GetString("Arg_InsufficientSpace"), "chars"); } // Convert the bytes into characters. int count = byteCount; int byteval; int shift = this.shift - 0x80; while(count-- > 0) { byteval = (int)(bytes[byteIndex++]); if(byteval < 0x80) { // Ordinary ASCII character. chars[charIndex++] = (char)byteval; } else { // Shift the ISCII character into the Unicode page. chars[charIndex++] = (char)(byteval + shift); } } return byteCount; } // Get the maximum number of bytes needed to encode a // specified number of characters. public override int GetMaxByteCount(int charCount) { if(charCount < 0) { throw new ArgumentOutOfRangeException ("charCount", Strings.GetString("ArgRange_NonNegative")); } return charCount; } // Get the maximum number of characters needed to decode a // specified number of bytes. public override int GetMaxCharCount(int byteCount) { if(byteCount < 0) { throw new ArgumentOutOfRangeException ("byteCount", Strings.GetString("ArgRange_NonNegative")); } return byteCount; } #if !ECMA_COMPAT // Get the mail body name for this encoding. public override String BodyName { get { return webName; } } // Get the human-readable name for this encoding. public override String EncodingName { get { return encodingName; } } // Get the mail agent header name for this encoding. public override String HeaderName { get { return webName; } } // Get the IANA-preferred Web name for this encoding. public override String WebName { get { return webName; } } #endif // !ECMA_COMPAT }; // class ISCIIEncoding // Define the ISCII code pages as subclasses of "ISCIIEncoding". [Serializable] public class CP57002 : ISCIIEncoding { public CP57002() : base(57002, 0x0900, "ISCII Devanagari", "x-iscii-de") {} }; // class CP57002 [Serializable] public class CP57003 : ISCIIEncoding { public CP57003() : base(57003, 0x0980, "ISCII Bengali", "x-iscii-be") {} }; // class CP57003 [Serializable] public class CP57004 : ISCIIEncoding { public CP57004() : base(57004, 0x0B80, "ISCII Tamil", "x-iscii-ta") {} }; // class CP57004 [Serializable] public class CP57005 : ISCIIEncoding { public CP57005() : base(57005, 0x0B80, "ISCII Telugu", "x-iscii-te") {} }; // class CP57005 [Serializable] public class CP57006 : ISCIIEncoding { // Note: Unicode has a "Sinhala" page, but no "Assamese" page. // Until I hear otherwise, I will assume that they are the same // thing with different names - Rhys Weatherley, 16 April 2002. public CP57006() : base(57006, 0x0D80, "ISCII Assamese", "x-iscii-as") {} }; // class CP57006 [Serializable] public class CP57007 : ISCIIEncoding { public CP57007() : base(57007, 0x0B00, "ISCII Oriya", "x-iscii-or") {} }; // class CP57007 [Serializable] public class CP57008 : ISCIIEncoding { public CP57008() : base(57008, 0x0C80, "ISCII Kannada", "x-iscii-ka") {} }; // class CP57008 [Serializable] public class CP57009 : ISCIIEncoding { public CP57009() : base(57009, 0x0D00, "ISCII Malayalam", "x-iscii-ma") {} }; // class CP57009 [Serializable] public class CP57010 : ISCIIEncoding { public CP57010() : base(57010, 0x0A80, "ISCII Gujarati", "x-iscii-gu") {} }; // class CP57010 [Serializable] public class CP57011 : ISCIIEncoding { // Note: Unicode has a "Gurmukhi" page, but no "Punjabi" page. // Other ISCII-related information on the Internet seems to // indicate that they are the same. Until I hear otherwise, // I will assume that they are the same thing with different // names - Rhys Weatherley, 16 April 2002. public CP57011() : base(57011, 0x0A00, "ISCII Punjabi", "x-iscii-pa") {} }; // class CP57011 // Define the web encoding name aliases for the above code pages. [Serializable] public class ENCx_iscii_de : CP57002 { public ENCx_iscii_de() : base() {} }; // class ENCx_iscii_de [Serializable] public class ENCx_iscii_be : CP57003 { public ENCx_iscii_be() : base() {} }; // class ENCx_iscii_be [Serializable] public class ENCx_iscii_ta : CP57004 { public ENCx_iscii_ta() : base() {} }; // class ENCx_iscii_ta [Serializable] public class ENCx_iscii_te : CP57005 { public ENCx_iscii_te() : base() {} }; // class ENCx_iscii_te [Serializable] public class ENCx_iscii_as : CP57006 { public ENCx_iscii_as() : base() {} }; // class ENCx_iscii_as [Serializable] public class ENCx_iscii_or : CP57007 { public ENCx_iscii_or() : base() {} }; // class ENCx_iscii_or [Serializable] public class ENCx_iscii_ka : CP57008 { public ENCx_iscii_ka() : base() {} }; // class ENCx_iscii_ka [Serializable] public class ENCx_iscii_ma : CP57009 { public ENCx_iscii_ma() : base() {} }; // class ENCx_iscii_ma [Serializable] public class ENCx_iscii_gu : CP57010 { public ENCx_iscii_gu() : base() {} }; // class ENCx_iscii_gu [Serializable] public class ENCx_iscii_pa : CP57011 { public ENCx_iscii_pa() : base() {} }; // class ENCx_iscii_pa }; // namespace I18N.Other