Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,499 @@
/*
* ByteEncoding.cs - Implementation of the "I18N.Common.ByteEncoding" class.
*
* 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.Common
{
using System;
using System.Runtime.InteropServices;
using System.Text;
// This class provides an abstract base for encodings that use a single
// byte per character. The bulk of the work is done in this class, with
// subclasses providing implementations of the "ToBytes" methods to perform
// the char->byte conversion.
[Serializable]
public abstract class ByteEncoding : MonoEncoding
{
// Internal state.
protected char[] toChars;
protected String encodingName;
protected String bodyName;
protected String headerName;
protected String webName;
protected bool isBrowserDisplay;
protected bool isBrowserSave;
protected bool isMailNewsDisplay;
protected bool isMailNewsSave;
protected int windowsCodePage;
#if NET_2_0
static byte [] isNormalized;
static byte [] isNormalizedComputed;
static byte [] normalization_bytes;
#endif
// Constructor.
protected ByteEncoding(int codePage, char[] toChars,
String encodingName, String bodyName,
String headerName, String webName,
bool isBrowserDisplay, bool isBrowserSave,
bool isMailNewsDisplay, bool isMailNewsSave,
int windowsCodePage)
: base(codePage)
{
if (toChars.Length != byte.MaxValue + 1)
throw new ArgumentException("toChars");
this.toChars = toChars;
this.encodingName = encodingName;
this.bodyName = bodyName;
this.headerName = headerName;
this.webName = webName;
this.isBrowserDisplay = isBrowserDisplay;
this.isBrowserSave = isBrowserSave;
this.isMailNewsDisplay = isMailNewsDisplay;
this.isMailNewsSave = isMailNewsSave;
this.windowsCodePage = windowsCodePage;
}
#if NET_2_0
public override bool IsAlwaysNormalized (NormalizationForm form)
{
if (form != NormalizationForm.FormC)
return false;
if (isNormalized == null)
isNormalized = new byte [0x10000 / 8];
if (isNormalizedComputed == null)
isNormalizedComputed = new byte [0x10000 / 8];
if (normalization_bytes == null) {
normalization_bytes = new byte [0x100];
lock (normalization_bytes) {
for (int i = 0; i < 0x100; i++)
normalization_bytes [i] = (byte) i;
}
}
byte offset = (byte) (1 << (CodePage % 8));
if ((isNormalizedComputed [CodePage / 8] & offset) == 0) {
Encoding e = Clone () as Encoding;
e.DecoderFallback = new DecoderReplacementFallback ("");
string s = e.GetString (normalization_bytes);
// note that the flag only stores FormC information.
if (s != s.Normalize (form))
isNormalized [CodePage / 8] |= offset;
isNormalizedComputed [CodePage / 8] |= offset;
}
return (isNormalized [CodePage / 8] & offset) == 0;
}
public override bool IsSingleByte {
get { return true; }
}
#endif
public override int GetByteCount(String s)
{
if(s == null)
{
throw new ArgumentNullException("s");
}
return s.Length;
}
// Get the number of bytes needed to encode a character buffer.
public unsafe override int GetByteCountImpl (char* chars, int count)
{
return count;
}
// Convert an array of characters into a byte buffer,
// once the parameters have been validated.
protected unsafe abstract void ToBytes (
char* chars, int charCount, byte* bytes, int byteCount);
/*
protected unsafe virtual void ToBytes (
char* chars, int charCount, byte* bytes, int byteCount)
{
// When it is not overriden, use ToBytes() with arrays.
char [] carr = new char [charCount];
Marshal.Copy ((IntPtr) chars, carr, 0, charCount);
byte [] barr = new byte [byteCount];
Marshal.Copy ((IntPtr) bytes, barr, 0, byteCount);
ToBytes (carr, 0, charCount, barr, 0);
}
*/
// Convert an array of characters into a byte buffer,
// once the parameters have been validated.
protected unsafe virtual void ToBytes(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
// When it is not overriden, use ToBytes() with pointers
// (this is the ideal solution)
if (charCount == 0 || bytes.Length == byteIndex)
return;
if (charIndex < 0 || charIndex > chars.Length) {
throw new ArgumentOutOfRangeException
("charIndex", Strings.GetString("ArgRange_Array"));
}
if (byteIndex < 0 || byteIndex > bytes.Length) {
throw new ArgumentOutOfRangeException
("byteIndex", Strings.GetString("ArgRange_Array"));
}
if (charCount < 0 || charIndex + charCount > chars.Length || byteIndex + charCount > bytes.Length) {
throw new ArgumentOutOfRangeException
("charCount", Strings.GetString("ArgRange_Array"));
}
fixed (char* cptr = chars) {
fixed (byte* bptr = bytes) {
ToBytes (cptr + charIndex, charCount,
bptr + byteIndex, bytes.Length - byteIndex);
}
}
}
/*
// Convert a string into a byte buffer, once the parameters
// have been validated.
protected unsafe virtual void ToBytes(String s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
// When it is not overriden, use ToBytes() with pointers
// (Ideal solution)
if (s.Length == 0 || bytes.Length == byteIndex)
return;
fixed (char* cptr = s) {
fixed (byte* bptr = bytes) {
ToBytes (cptr + charIndex, charCount,
bptr + byteIndex, bytes.Length - byteIndex);
}
}
}
*/
//[CLSCompliant (false)]
public unsafe override int GetBytesImpl (char* chars, int charCount, byte* bytes, int byteCount)
{
ToBytes (chars, charCount, bytes, byteCount);
return charCount;
}
/*
// 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", Strings.GetString("ArgRange_Array"));
}
if(charCount < 0 || charCount > (chars.Length - charIndex))
{
throw new ArgumentOutOfRangeException
("charCount", Strings.GetString("ArgRange_Array"));
}
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"));
}
ToBytes(chars, charIndex, charCount, bytes, byteIndex);
return charCount;
}
// Convenience wrappers for "GetBytes".
public override int GetBytes(String s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
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"));
}
ToBytes(s, charIndex, charCount, bytes, byteIndex);
return charCount;
}
*/
// 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)
{
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"));
}
int count = byteCount;
char[] cvt = toChars;
while(count-- > 0)
{
chars[charIndex++] = cvt[(int)(bytes[byteIndex++])];
}
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;
}
// Decode a buffer of bytes into a string.
public unsafe override String GetString(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"));
}
if (count == 0)
return string.Empty;
string s = new string ((char) 0, count);
fixed (byte* bytePtr = bytes)
fixed (char* charPtr = s)
fixed (char* cvt = toChars) {
byte* b = bytePtr + index;
char* c = charPtr;
while(count-- != 0)
*(c++) = cvt[*(b++)];
}
return s;
}
public override String GetString(byte[] bytes)
{
if(bytes == null)
{
throw new ArgumentNullException("bytes");
}
return GetString (bytes, 0, bytes.Length);
}
#if !ECMA_COMPAT
// Get the mail body name for this encoding.
public override String BodyName
{
get
{
return bodyName;
}
}
// 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 headerName;
}
}
// Determine if this encoding can be displayed in a Web browser.
public override bool IsBrowserDisplay
{
get
{
return isBrowserDisplay;
}
}
// Determine if this encoding can be saved from a Web browser.
public override bool IsBrowserSave
{
get
{
return isBrowserSave;
}
}
// Determine if this encoding can be displayed in a mail/news agent.
public override bool IsMailNewsDisplay
{
get
{
return isMailNewsDisplay;
}
}
// Determine if this encoding can be saved from a mail/news agent.
public override bool IsMailNewsSave
{
get
{
return isMailNewsSave;
}
}
// Get the IANA-preferred Web name for this encoding.
public override String WebName
{
get
{
return webName;
}
}
// Get the Windows code page represented by this object.
public override int WindowsCodePage
{
get
{
return windowsCodePage;
}
}
#endif // !ECMA_COMPAT
}; // class ByteEncoding
}; // namespace I18N.Encoding

View File

@@ -0,0 +1,460 @@
/*
* ByteSafeEncoding.cs - Implementation of the "I18N.Common.ByteSafeEncoding" class.
*
* Copyright (c) 2002 Southern Storm Software, Pty Ltd
* Copytight (c) 2011 Pablo Ruiz Garc<72>a
*
* 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.Common
{
using System;
using System.Runtime.InteropServices;
using System.Text;
// This class provides an abstract base for encodings that use a single
// byte per character. The bulk of the work is done in this class, with
// subclasses providing implementations of the "ToBytes" methods to perform
// the char->byte conversion.
#if DISABLE_UNSAFE
[Serializable]
public abstract class ByteSafeEncoding : MonoSafeEncoding
{
// Internal state.
protected char[] toChars;
protected String encodingName;
protected String bodyName;
protected String headerName;
protected String webName;
protected bool isBrowserDisplay;
protected bool isBrowserSave;
protected bool isMailNewsDisplay;
protected bool isMailNewsSave;
protected int windowsCodePage;
#if NET_2_0
static byte [] isNormalized;
static byte [] isNormalizedComputed;
static byte [] normalization_bytes;
#endif
// Constructor.
protected ByteSafeEncoding(int codePage, char[] toChars,
String encodingName, String bodyName,
String headerName, String webName,
bool isBrowserDisplay, bool isBrowserSave,
bool isMailNewsDisplay, bool isMailNewsSave,
int windowsCodePage)
: base(codePage)
{
if (toChars.Length != byte.MaxValue + 1)
throw new ArgumentException("toChars");
this.toChars = toChars;
this.encodingName = encodingName;
this.bodyName = bodyName;
this.headerName = headerName;
this.webName = webName;
this.isBrowserDisplay = isBrowserDisplay;
this.isBrowserSave = isBrowserSave;
this.isMailNewsDisplay = isMailNewsDisplay;
this.isMailNewsSave = isMailNewsSave;
this.windowsCodePage = windowsCodePage;
}
#if NET_2_0
public override bool IsAlwaysNormalized (NormalizationForm form)
{
if (form != NormalizationForm.FormC)
return false;
if (isNormalized == null)
isNormalized = new byte [0x10000 / 8];
if (isNormalizedComputed == null)
isNormalizedComputed = new byte [0x10000 / 8];
if (normalization_bytes == null) {
normalization_bytes = new byte [0x100];
lock (normalization_bytes) {
for (int i = 0; i < 0x100; i++)
normalization_bytes [i] = (byte) i;
}
}
byte offset = (byte) (1 << (CodePage % 8));
if ((isNormalizedComputed [CodePage / 8] & offset) == 0) {
Encoding e = Clone () as Encoding;
e.DecoderFallback = new DecoderReplacementFallback ("");
string s = e.GetString (normalization_bytes);
// note that the flag only stores FormC information.
if (s != s.Normalize (form))
isNormalized [CodePage / 8] |= offset;
isNormalizedComputed [CodePage / 8] |= offset;
}
return (isNormalized [CodePage / 8] & offset) == 0;
}
public override bool IsSingleByte {
get { return true; }
}
#endif
public override int GetByteCount(String s)
{
if(s == null)
throw new ArgumentNullException("s");
return s.Length;
}
// Get the number of bytes needed to encode a character buffer.
public override int GetByteCount(char[] chars, int index, int count)
{
return count - index;
}
public override unsafe int GetByteCount(char* chars, int count)
{
return count;
}
// Convert an array of characters into a byte buffer,
// once the parameters have been validated.
protected abstract void ToBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex);
// Convert a string into a byte buffer, once the parameters
// have been validated.
protected virtual void ToBytes(String s, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
// When it is not overriden, use ToBytes() with pointers
// (Ideal solution)
if (s.Length == 0 || bytes.Length == byteIndex)
return;
ToBytes(s.ToCharArray(), charIndex, charCount, bytes, 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)
{
if(chars == null)
{
throw new ArgumentNullException("chars");
}
if(bytes == null)
{
throw new ArgumentNullException("bytes");
}
if(charIndex < 0 || charIndex > chars.Length)
{
throw new ArgumentOutOfRangeException
("charIndex", Strings.GetString("ArgRange_Array"));
}
if(charCount < 0 || charCount > (chars.Length - charIndex))
{
throw new ArgumentOutOfRangeException
("charCount", Strings.GetString("ArgRange_Array"));
}
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"));
}
ToBytes(chars, charIndex, charCount, bytes, byteIndex);
return charCount;
}
// Convenience wrappers for "GetBytes".
public override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
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"));
}
ToBytes(s, charIndex, charCount, bytes, byteIndex);
return charCount;
}
public override byte[] GetBytes(string s)
{
if (s == null)
throw new ArgumentNullException("s");
char[] data = s.ToCharArray();
return GetBytes(data, 0, data.Length);
}
// 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)
{
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"));
}
int count = byteCount;
char[] cvt = toChars;
while(count-- > 0)
{
chars[charIndex++] = cvt[(int)(bytes[byteIndex++])];
}
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;
}
// Decode a buffer of bytes into a string.
public unsafe override String GetString(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"));
}
if (count == 0)
return string.Empty;
string s = new string ((char) 0, count);
fixed (byte* bytePtr = bytes)
fixed (char* charPtr = s)
fixed (char* cvt = toChars) {
byte* b = bytePtr + index;
char* c = charPtr;
while(count-- != 0)
*(c++) = cvt[*(b++)];
}
return s;
}
public override String GetString(byte[] bytes)
{
if(bytes == null)
{
throw new ArgumentNullException("bytes");
}
return GetString (bytes, 0, bytes.Length);
}
#if !ECMA_COMPAT
// Get the mail body name for this encoding.
public override String BodyName
{
get
{
return bodyName;
}
}
// 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 headerName;
}
}
// Determine if this encoding can be displayed in a Web browser.
public override bool IsBrowserDisplay
{
get
{
return isBrowserDisplay;
}
}
// Determine if this encoding can be saved from a Web browser.
public override bool IsBrowserSave
{
get
{
return isBrowserSave;
}
}
// Determine if this encoding can be displayed in a mail/news agent.
public override bool IsMailNewsDisplay
{
get
{
return isMailNewsDisplay;
}
}
// Determine if this encoding can be saved from a mail/news agent.
public override bool IsMailNewsSave
{
get
{
return isMailNewsSave;
}
}
// Get the IANA-preferred Web name for this encoding.
public override String WebName
{
get
{
return webName;
}
}
// Get the Windows code page represented by this object.
public override int WindowsCodePage
{
get
{
return windowsCodePage;
}
}
#endif // !ECMA_COMPAT
}; // class ByteEncoding
#endif
}; // namespace I18N.Encoding

View File

@@ -0,0 +1,75 @@
2006-08-24 Atsushi Enomoto <atsushi@ximian.com>
* ByteEncoding.cs : Implemented IsAlwaysNormalized().
(only SingleByte and FormC may return true for IsAlwaysNormalized
on .NET.)
Ask String.Normalize() for every possible single byte character
which is valid for the encoding and see if it has changed the
string (i.e. it returns the value based on the actual
normalization.)
2006-06-13 Kornél Pál <kornelpal@gmail.com>
* ByteEncoding.cs: Use unsafe code in GetString() that results in
significant performance improvement.
2006-01-30 Atsushi Enomoto <atsushi@ximian.com>
* MonoEncoding.cs :
Added another overload that takes windows code page.
2006-01-23 Atsushi Enomoto <atsushi@ximian.com>
* MonoEncoding.cs :
Added abstract GetByteCountImpl() in MonoEncoding and MonoEncoder.
GetByteCount() is now based on the method above.
* ByteEncoding.cs : so GetByteCount() became GetByteCountImpl() and
is based on char*.
2006-01-17 Atsushi Enomoto <atsushi@ximian.com>
* MonoEncoding.cs, ByteEncoding.cs :
Marked as [Serializable].
2005-12-01 Atsushi Enomoto <atsushi@ximian.com>
* MonoEncoding.cs : new file, which is going to be used as the
abstract class for all Encoding classes in I18N.*.dll. Only
GetBytesImpl() is required in derived classes.
* I18N.dll.sources : added above.
* ByteEncoding : HandleFallback() is moved to MonoEncoding.
Now that only ToBytes() with pointers is required, commented out
other ToBytes() overloads.
GetBytesImpl() is implemented to call ToBytes() and thus all of
the derived classes work as they used to be.
2005-11-30 Atsushi Enomoto <atsushi@ximian.com>
* Makefile : now it uses unsafe pointers.
* ByteEncoding.cs : Now there is three versions of ToBytes(): the only
one with pointers will be in use in the future. ToBytes(string) and
ToBytes() with arrays will be implemented to dispatch pointer-based
one and will be only one conversion implementation while they keep
avoiding extra array creation.
2005-11-28 Atsushi Enomoto <atsushi@ximian.com>
* ByteEncoding.cs : added IsSingleByte.
2005-11-01 Atsushi Enomoto <atsushi@ximian.com>
* Handler.cs : added 51949 (true euc-kr).
2005-09-25 Atsushi Enomoto <atsushi@ximian.com>
* Handler.cs : added 50220 and 50222.
2005-09-18 Atsushi Enomoto <atsushi@ximian.com>
* Handler.cs : Required changes wrt some class renames.
2005-08-19 Atsushi Enomoto <atsushi@ximian.com>
why didn't we have it? ;-)
* Handlers.cs : added GB18030 support.

View File

@@ -0,0 +1,330 @@
/*
* Handlers.cs - Implementation of the "I18N.Common.Handlers" class.
*
* 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.Common
{
using System;
using System.Collections.Generic;
// This class provides an internal list of handlers, for runtime
// engines that do not implement the altered "GetFile" semantics.
// The list must be kept up to date manually.
public sealed class Handlers
{
public static readonly String[] List = {
"I18N.CJK.CP932",
"I18N.CJK.CP936",
"I18N.CJK.CP949",
"I18N.CJK.CP950",
"I18N.CJK.CP50220",
"I18N.CJK.CP50221",
"I18N.CJK.CP50222",
"I18N.CJK.CP51932",
"I18N.CJK.CP51949",
"I18N.CJK.CP54936",
"I18N.CJK.ENCbig5",
"I18N.CJK.ENCgb2312",
"I18N.CJK.ENCshift_jis",
"I18N.CJK.ENCiso_2022_jp",
"I18N.CJK.ENCeuc_jp",
"I18N.CJK.ENCeuc_kr",
"I18N.CJK.ENCuhc",
"I18N.CJK.ENCgb18030",
"I18N.MidEast.CP1254",
"I18N.MidEast.ENCwindows_1254",
"I18N.MidEast.CP1255",
"I18N.MidEast.ENCwindows_1255",
"I18N.MidEast.CP1256",
"I18N.MidEast.ENCwindows_1256",
"I18N.MidEast.CP28596",
"I18N.MidEast.ENCiso_8859_6",
"I18N.MidEast.CP28598",
"I18N.MidEast.ENCiso_8859_8",
"I18N.MidEast.CP28599",
"I18N.MidEast.ENCiso_8859_9",
"I18N.MidEast.CP38598",
"I18N.MidEast.ENCwindows_38598",
"I18N.Other.CP1251",
"I18N.Other.ENCwindows_1251",
"I18N.Other.CP1257",
"I18N.Other.ENCwindows_1257",
"I18N.Other.CP1258",
"I18N.Other.ENCwindows_1258",
"I18N.Other.CP20866",
"I18N.Other.ENCkoi8_r",
"I18N.Other.CP21866",
"I18N.Other.ENCkoi8_u",
"I18N.Other.CP28594",
"I18N.Other.ENCiso_8859_4",
"I18N.Other.CP28595",
"I18N.Other.ENCiso_8859_5",
"I18N.Other.ISCIIEncoding",
"I18N.Other.CP57002",
"I18N.Other.CP57003",
"I18N.Other.CP57004",
"I18N.Other.CP57005",
"I18N.Other.CP57006",
"I18N.Other.CP57007",
"I18N.Other.CP57008",
"I18N.Other.CP57009",
"I18N.Other.CP57010",
"I18N.Other.CP57011",
"I18N.Other.ENCx_iscii_de",
"I18N.Other.ENCx_iscii_be",
"I18N.Other.ENCx_iscii_ta",
"I18N.Other.ENCx_iscii_te",
"I18N.Other.ENCx_iscii_as",
"I18N.Other.ENCx_iscii_or",
"I18N.Other.ENCx_iscii_ka",
"I18N.Other.ENCx_iscii_ma",
"I18N.Other.ENCx_iscii_gu",
"I18N.Other.ENCx_iscii_pa",
"I18N.Other.CP874",
"I18N.Other.ENCwindows_874",
"I18N.Rare.CP1026",
"I18N.Rare.ENCibm1026",
"I18N.Rare.CP1047",
"I18N.Rare.ENCibm1047",
"I18N.Rare.CP1140",
"I18N.Rare.ENCibm01140",
"I18N.Rare.CP1141",
"I18N.Rare.ENCibm01141",
"I18N.Rare.CP1142",
"I18N.Rare.ENCibm01142",
"I18N.Rare.CP1143",
"I18N.Rare.ENCibm01143",
"I18N.Rare.CP1144",
"I18N.Rare.ENCibm1144",
"I18N.Rare.CP1145",
"I18N.Rare.ENCibm1145",
"I18N.Rare.CP1146",
"I18N.Rare.ENCibm1146",
"I18N.Rare.CP1147",
"I18N.Rare.ENCibm1147",
"I18N.Rare.CP1148",
"I18N.Rare.ENCibm1148",
"I18N.Rare.CP1149",
"I18N.Rare.ENCibm1149",
"I18N.Rare.CP20273",
"I18N.Rare.ENCibm273",
"I18N.Rare.CP20277",
"I18N.Rare.ENCibm277",
"I18N.Rare.CP20278",
"I18N.Rare.ENCibm278",
"I18N.Rare.CP20280",
"I18N.Rare.ENCibm280",
"I18N.Rare.CP20284",
"I18N.Rare.ENCibm284",
"I18N.Rare.CP20285",
"I18N.Rare.ENCibm285",
"I18N.Rare.CP20290",
"I18N.Rare.ENCibm290",
"I18N.Rare.CP20297",
"I18N.Rare.ENCibm297",
"I18N.Rare.CP20420",
"I18N.Rare.ENCibm420",
"I18N.Rare.CP20424",
"I18N.Rare.ENCibm424",
"I18N.Rare.CP20871",
"I18N.Rare.ENCibm871",
"I18N.Rare.CP21025",
"I18N.Rare.ENCibm1025",
"I18N.Rare.CP37",
"I18N.Rare.ENCibm037",
"I18N.Rare.CP500",
"I18N.Rare.ENCibm500",
"I18N.Rare.CP708",
"I18N.Rare.ENCasmo_708",
"I18N.Rare.CP852",
"I18N.Rare.ENCibm852",
"I18N.Rare.CP855",
"I18N.Rare.ENCibm855",
"I18N.Rare.CP857",
"I18N.Rare.ENCibm857",
"I18N.Rare.CP858",
"I18N.Rare.ENCibm00858",
"I18N.Rare.CP862",
"I18N.Rare.ENCibm862",
"I18N.Rare.CP864",
"I18N.Rare.ENCibm864",
"I18N.Rare.CP866",
"I18N.Rare.ENCibm866",
"I18N.Rare.CP869",
"I18N.Rare.ENCibm869",
"I18N.Rare.CP870",
"I18N.Rare.ENCibm870",
"I18N.Rare.CP875",
"I18N.Rare.ENCibm875",
"I18N.West.CP10000",
"I18N.West.ENCmacintosh",
"I18N.West.CP10079",
"I18N.West.ENCx_mac_icelandic",
"I18N.West.CP1250",
"I18N.West.ENCwindows_1250",
"I18N.West.CP1252",
"I18N.West.ENCwindows_1252",
"I18N.West.CP1253",
"I18N.West.ENCwindows_1253",
"I18N.West.CP28592",
"I18N.West.ENCiso_8859_2",
"I18N.West.CP28593",
"I18N.West.ENCiso_8859_3",
"I18N.West.CP28597",
"I18N.West.ENCiso_8859_7",
"I18N.West.CP28605",
"I18N.West.ENCiso_8859_15",
"I18N.West.CP437",
"I18N.West.ENCibm437",
"I18N.West.CP850",
"I18N.West.ENCibm850",
"I18N.West.CP860",
"I18N.West.ENCibm860",
"I18N.West.CP861",
"I18N.West.ENCibm861",
"I18N.West.CP863",
"I18N.West.ENCibm863",
"I18N.West.CP865",
"I18N.West.ENCibm865"
};
static Dictionary<string, string> aliases;
public static string GetAlias (string name)
{
if (aliases == null)
BuildHash ();
string v;
aliases.TryGetValue (name, out v);
return v;
}
static void BuildHash ()
{
aliases = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
aliases.Add ("arabic", "iso_8859_6");
aliases.Add ("csISOLatinArabic", "iso_8859_6");
aliases.Add ("ECMA_114", "iso_8859_6");
aliases.Add ("ISO_8859_6:1987", "iso_8859_6");
aliases.Add ("iso_ir_127", "iso_8859_6");
aliases.Add ("cp1256" ,"windows_1256");
aliases.Add ("csISOLatin4", "iso_8859_4");
aliases.Add ("ISO_8859_4:1988", "iso_8859_4");
aliases.Add ("iso_ir_110", "iso_8859_4");
aliases.Add ("l4", "iso_8859_4");
aliases.Add ("latin4", "iso_8859_4");
aliases.Add ("cp852" ,"ibm852");
aliases.Add ("csISOLatin2", "iso_8859_2");
aliases.Add ("iso_8859_2:1987", "iso_8859_2");
aliases.Add ("iso8859_2", "iso_8859_2");
aliases.Add ("iso_ir_101", "iso_8859_2");
aliases.Add ("l2", "iso_8859_2");
aliases.Add ("latin2", "iso_8859_2");
aliases.Add ("x-cp1250", "windows_1250");
aliases.Add ("chinese", "gb2312");
aliases.Add ("CN-GB", "gb2312");
aliases.Add ("csGB2312", "gb2312");
aliases.Add ("csGB231280", "gb2312");
aliases.Add ("csISO58GB231280", "gb2312");
aliases.Add ("GB_2312_80", "gb2312");
aliases.Add ("GB231280", "gb2312");
aliases.Add ("GB2312_80", "gb2312");
aliases.Add ("GBK", "gb2312");
aliases.Add ("iso_ir_58", "gb2312");
aliases.Add ("cn-big5", "big5");
aliases.Add ("csbig5", "big5");
aliases.Add ("x-x-big5", "big5");
aliases.Add ("cp866", "ibm866");
aliases.Add ("csISOLatin5", "iso_8859_5");
aliases.Add ("csISOLatinCyrillic", "iso_8859_5");
aliases.Add ("cyrillic", "iso_8859_5");
aliases.Add ("ISO_8859_5:1988", "iso_8859_5");
aliases.Add ("iso_ir_144", "iso_8859_5");
aliases.Add ("l5", "iso_8859_5");
aliases.Add ("csKOI8R", "koi8_r");
aliases.Add ("koi", "koi8_r");
aliases.Add ("koi8", "koi8_r");
aliases.Add ("koi8r", "koi8_r");
aliases.Add ("koi8ru", "koi8_u");
aliases.Add ("x-cp1251", "windows_1251");
aliases.Add ("csISOLatinGreek", "iso_8859_7");
aliases.Add ("ECMA_118", "iso_8859_7");
aliases.Add ("ELOT_928", "iso_8859_7");
aliases.Add ("greek", "iso_8859_7");
aliases.Add ("greek8", "iso_8859_7");
aliases.Add ("ISO_8859_7:1987", "iso_8859_7");
aliases.Add ("iso_ir_126", "iso_8859_7");
aliases.Add ("csISOLatinHebrew", "iso_8859_8");
aliases.Add ("hebrew", "iso_8859_8");
aliases.Add ("ISO_8859_8:1988", "iso_8859_8");
aliases.Add ("iso_ir_138", "iso_8859_8");
aliases.Add ("csShiftJIS", "shift_jis");
aliases.Add ("csWindows31J", "shift_jis");
aliases.Add ("ms_Kanji", "shift_jis");
aliases.Add ("shift-jis", "shift_jis");
aliases.Add ("x-ms-cp932", "shift_jis");
aliases.Add ("x-sjis", "shift_jis");
aliases.Add ("iso_2022_kr", "euc_kr");
aliases.Add ("csISOLatin3", "iso_8859_3");
aliases.Add ("ISO_8859_3:1988", "iso_8859_3");
aliases.Add ("iso_ir_109", "iso_8859_3");
aliases.Add ("l3", "iso_8859_3");
aliases.Add ("latin3", "iso_8859_3");
aliases.Add ("csISOLatin9", "iso_8859_15");
aliases.Add ("l9", "iso_8859_15");
aliases.Add ("latin9", "iso_8859_15");
aliases.Add ("cp437", "ibm437");
aliases.Add ("csPC8", "ibm437");
aliases.Add ("CodePage437", "ibm437");
aliases.Add ("DOS_874", "windows_874");
aliases.Add ("iso_8859_11", "windows_874");
aliases.Add ("TIS_620", "windows_874");
}
}; // class Handlers
}; // namespace I18N.Common

View File

@@ -0,0 +1,9 @@
../Assembly/AssemblyInfo.cs
../../../build/common/Consts.cs
ByteEncoding.cs
ByteSafeEncoding.cs
Handlers.cs
Manager.cs
MonoEncoding.cs
MonoSafeEncoding.cs
Strings.cs

View File

@@ -0,0 +1,9 @@
thisdir = class/I18N/Common
SUBDIRS =
include ../../../build/rules.make
LIBRARY = I18N.dll
LOCAL_MCS_FLAGS = /r:$(corlib) /unsafe /define:DISABLE_UNSAFE
NO_TEST = yes
include ../../../build/library.make

View File

@@ -0,0 +1,360 @@
/*
* Manager.cs - Implementation of the "I18N.Common.Manager" class.
*
* 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.Common
{
using System;
using System.IO;
using System.Text;
using System.Globalization;
using System.Collections;
using System.Reflection;
using System.Security;
// This class provides the primary entry point into the I18N
// library. Users of the library start by getting the value
// of the "PrimaryManager" property. They then invoke methods
// on the manager to obtain further I18N information.
public class Manager
{
// The primary I18N manager.
private static Manager manager;
// Internal state.
private Hashtable handlers; // List of all handler classes.
private Hashtable active; // Currently active handlers.
private Hashtable assemblies; // Currently loaded region assemblies.
static readonly object lockobj = new object ();
// Constructor.
private Manager()
{
handlers = new Hashtable (CaseInsensitiveHashCodeProvider.Default,
CaseInsensitiveComparer.Default);
active = new Hashtable(16);
assemblies = new Hashtable(8);
LoadClassList();
}
// Get the primary I18N manager instance.
public static Manager PrimaryManager
{
get
{
lock(lockobj)
{
if(manager == null)
{
manager = new Manager();
}
return manager;
}
}
}
// Normalize a name.
// FIXME: This means, we accept invalid names such as "euc_jp"
private static String Normalize(String name)
{
#if ECMA_COMPAT
return (name.ToLower()).Replace('-', '_');
#else
return (name.ToLower(CultureInfo.InvariantCulture))
.Replace('-', '_');
#endif
}
// Get an encoding object for a specific code page.
// Returns NULL if the code page is not available.
public Encoding GetEncoding(int codePage)
{
return (Instantiate("CP" + codePage.ToString()) as Encoding);
}
// Get an encoding object for a specific Web encoding.
// Returns NULL if the encoding is not available.
public Encoding GetEncoding(String name)
{
// Validate the parameter.
if(name == null)
{
return null;
}
string orgName = name;
// Normalize the encoding name.
name = Normalize(name);
// Try to find a class called "ENCname".
Encoding e = Instantiate ("ENC" + name) as Encoding;
if (e == null)
e = Instantiate (name) as Encoding;
if (e == null) {
// Try windows aliases
string alias = Handlers.GetAlias (name);
if (alias != null) {
e = Instantiate ("ENC" + alias) as Encoding;
if (e == null)
e = Instantiate (alias) as Encoding;
}
}
if (e == null)
return null;
// e.g. Neither euc_jp nor shift-jis not allowed (Normalize() badness)
if (orgName.IndexOf ('_') > 0 && e.WebName.IndexOf ('-') > 0)
return null;
if (orgName.IndexOf ('-') > 0 && e.WebName.IndexOf ('_') > 0)
return null;
return e;
}
// List of hex digits for use by "GetCulture".
private const String hex = "0123456789abcdef";
// Get a specific culture by identifier. Returns NULL
// if the culture information is not available.
public CultureInfo GetCulture(int culture, bool useUserOverride)
{
// Create the hex version of the culture identifier.
StringBuilder builder = new StringBuilder();
builder.Append(hex[(culture >> 12) & 0x0F]);
builder.Append(hex[(culture >> 8) & 0x0F]);
builder.Append(hex[(culture >> 4) & 0x0F]);
builder.Append(hex[culture & 0x0F]);
String name = builder.ToString();
// Try looking for an override culture handler.
if(useUserOverride)
{
Object obj = Instantiate("CIDO" + name);
if(obj != null)
{
return (obj as CultureInfo);
}
}
// Look for the generic non-override culture.
return (Instantiate("CID" + name) as CultureInfo);
}
// Get a specific culture by name. Returns NULL if the
// culture informaion is not available.
public CultureInfo GetCulture(String name, bool useUserOverride)
{
// Validate the parameter.
if(name == null)
{
return null;
}
// Normalize the culture name.
name = Normalize(name);
// Try looking for an override culture handler.
if(useUserOverride)
{
Object obj = Instantiate("CNO" + name.ToString());
if(obj != null)
{
return (obj as CultureInfo);
}
}
// Look for the generic non-override culture.
return (Instantiate("CN" + name.ToString()) as CultureInfo);
}
// Instantiate a handler class. Returns null if it is not
// possible to instantiate the class.
internal Object Instantiate(String name)
{
Object handler;
String region;
Assembly assembly;
Type type;
lock(this)
{
// See if we already have an active handler by this name.
handler = active[name];
if(handler != null)
{
return handler;
}
// Determine which region assembly handles the class.
region = (String)(handlers[name]);
if(region == null)
{
// The class does not exist in any region assembly.
return null;
}
// Find the region-specific assembly and load it.
assembly = (Assembly)(assemblies[region]);
if(assembly == null)
{
try
{
// we use the same strong name as I18N.dll except the assembly name
AssemblyName myName = typeof(Manager).Assembly.GetName();
myName.Name = region;
assembly = Assembly.Load(myName);
}
catch(SystemException)
{
assembly = null;
}
if(assembly == null)
{
return null;
}
assemblies[region] = assembly;
}
// Look for the class within the region-specific assembly.
type = assembly.GetType(region + "." + name, false, true);
if(type == null)
{
return null;
}
// Invoke the constructor, which we assume is public
// and has zero arguments.
try
{
handler = Activator.CreateInstance (type);
}
catch(MissingMethodException)
{
// The constructor was not present.
return null;
}
catch(SecurityException)
{
// The constructor was inaccessible.
return null;
}
// Add the handler to the active handlers cache.
active.Add(name, handler);
// Return the handler to the caller.
return handler;
}
}
// Load the list of classes that are present in all region assemblies.
private void LoadClassList()
{
FileStream stream;
// Look for "I18N-handlers.def" in the same directory
// as this assembly. Note: this assumes that the
// "Assembly.GetFile" method can access files that
// aren't explicitly part of the assembly manifest.
//
// This is necessary because the "I18N-handlers.def"
// file is generated after the "i18n" assembly is
// compiled and linked. So it cannot be embedded
// directly into the assembly manifest.
try
{
stream = Assembly.GetExecutingAssembly()
.GetFile("I18N-handlers.def");
if(stream == null)
{
LoadInternalClasses();
return;
}
}
catch(FileLoadException)
{
// The file does not exist, or the runtime engine
// refuses to implement the necessary semantics.
// Fall back to an internal list, which must be
// kept up to date manually.
LoadInternalClasses();
return;
}
// Load the class list from the stream.
StreamReader reader = new StreamReader(stream);
String line;
int posn;
while((line = reader.ReadLine()) != null)
{
// Skip comment lines in the input.
if(line.Length == 0 || line[0] == '#')
{
continue;
}
// Split the line into namespace and name. We assume
// that the line has the form "I18N.<Region>.<Name>".
posn = line.LastIndexOf('.');
if(posn != -1)
{
// Add the namespace to the "handlers" hash,
// attached to the name of the handler class.
String name = line.Substring(posn + 1);
if(!handlers.Contains(name))
{
handlers.Add(name, line.Substring(0, posn));
}
}
}
reader.Close();
}
// Load the list of classes from the internal list.
private void LoadInternalClasses()
{
int posn;
foreach(String line in Handlers.List)
{
// Split the line into namespace and name. We assume
// that the line has the form "I18N.<Region>.<Name>".
posn = line.LastIndexOf('.');
if(posn != -1)
{
// Add the namespace to the "handlers" hash,
// attached to the name of the handler class.
String name = line.Substring(posn + 1);
if(!handlers.Contains(name))
{
handlers.Add(name, line.Substring(0, posn));
}
}
}
}
}; // class Manager
}; // namespace I18N.Common

View File

@@ -0,0 +1,317 @@
//
// MonoEncoding.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2005 Novell, Inc. http://www.novell.com
//
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace I18N.Common
{
[Serializable]
public abstract class MonoEncoding : Encoding
{
readonly int win_code_page;
public MonoEncoding (int codePage)
: this (codePage, 0)
{
}
public MonoEncoding (int codePage, int windowsCodePage)
: base (codePage)
{
win_code_page = windowsCodePage;
}
public override int WindowsCodePage {
get { return win_code_page != 0 ? win_code_page : base.WindowsCodePage; }
}
#if NET_2_0
/// <summary>
/// GetBytes method used internally by state-full encoders/encodings.
/// </summary>
/// <param name="chars">The chars.</param>
/// <param name="charIndex">Index of the char.</param>
/// <param name="charCount">The char count.</param>
/// <param name="bytes">The bytes.</param>
/// <param name="byteIndex">Index of the byte.</param>
/// <param name="flush">if set to <c>true</c> [flush].</param>
/// <param name="encoding">The encoding class to use (or null if state-less).</param>
/// <returns></returns>
/// <remarks>
/// Only state-full encoders need to implement this method (ie. ISO-2022-JP)
/// </remarks>
protected unsafe virtual int GetBytesInternal(char *chars, int charCount,
byte *bytes, int byteCount, bool flush, object state)
{
throw new NotImplementedException("Statefull encoding is not implemented (yet?) by this encoding class.");
}
public unsafe void HandleFallback (ref EncoderFallbackBuffer buffer,
char* chars, ref int charIndex, ref int charCount,
byte* bytes, ref int byteIndex, ref int byteCount, object state)
{
if (buffer == null)
buffer = EncoderFallback.CreateFallbackBuffer ();
if (charCount > 1 && (Char.IsSurrogate (chars [charIndex]) && Char.IsSurrogate (chars [charIndex + 1]))) {
buffer.Fallback (chars [charIndex], chars [charIndex + 1], charIndex);
charIndex++;
charCount--;
}
else
buffer.Fallback (chars [charIndex], charIndex);
char [] tmp = new char [buffer.Remaining];
int idx = 0;
while (buffer.Remaining > 0)
tmp [idx++] = buffer.GetNextChar ();
fixed (char* tmparr = tmp) {
var outbytes = bytes == null ? null : bytes + byteIndex;
var len = state == null ?
GetBytes(tmparr, tmp.Length, outbytes, byteCount)
: GetBytesInternal(tmparr, tmp.Length, outbytes, byteCount, true, state);
byteIndex += len;
byteCount -= len;
}
}
public unsafe void HandleFallback (ref EncoderFallbackBuffer buffer,
char* chars, ref int charIndex, ref int charCount,
byte* bytes, ref int byteIndex, ref int byteCount)
{
HandleFallback(ref buffer, chars, ref charIndex, ref charCount,
bytes, ref byteIndex, ref byteCount, null);
}
#endif
// Get the bytes that result from encoding 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"));
if (count == 0)
return 0;
unsafe {
fixed (char* cptr = chars) {
return GetByteCountImpl (
cptr + index, count);
}
}
}
// 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", Strings.GetString ("ArgRange_Array"));
if (charCount < 0 || charCount > (chars.Length - charIndex))
throw new ArgumentOutOfRangeException
("charCount", Strings.GetString ("ArgRange_Array"));
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");
if (charCount == 0)
return 0;
unsafe {
fixed (char* cptr = chars) {
fixed (byte* bptr = bytes) {
return GetBytesImpl (
cptr + charIndex,
charCount,
bptr + byteIndex,
bytes.Length - 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");
if (charCount == 0 || bytes.Length == byteIndex)
return 0;
unsafe {
fixed (char* cptr = s) {
fixed (byte* bptr = bytes) {
return GetBytesImpl (
cptr + charIndex,
charCount,
bptr + byteIndex,
bytes.Length - byteIndex);
}
}
}
}
#if NET_2_0
public unsafe override int GetByteCount (char* chars, int count)
{
return GetByteCountImpl (chars, count);
}
public unsafe override int GetBytes (char* chars, int charCount,
byte* bytes, int byteCount)
{
return GetBytesImpl (chars, charCount, bytes, byteCount);
}
#endif
//[CLSCompliant (false)]
public unsafe abstract int GetByteCountImpl (char* chars, int charCount);
//[CLSCompliant (false)]
public unsafe abstract int GetBytesImpl (char* chars, int charCount,
byte* bytes, int byteCount);
}
public abstract class MonoEncoder : Encoder
{
#if NET_2_0
MonoEncoding encoding;
#endif
public MonoEncoder (MonoEncoding encoding)
{
#if NET_2_0
this.encoding = encoding;
#endif
}
public override int GetByteCount (
char [] chars, int index, int count, bool refresh)
{
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"));
if (count == 0)
return 0;
unsafe {
fixed (char* cptr = chars) {
return GetByteCountImpl (
cptr + index, count, refresh);
}
}
}
public override int GetBytes (char [] chars, int charIndex, int charCount, byte [] bytes, int byteIndex, bool flush)
{
if (chars == null)
throw new ArgumentNullException ("chars");
if (bytes == null)
throw new ArgumentNullException ("bytes");
if (charIndex < 0 || charIndex > chars.Length)
throw new ArgumentOutOfRangeException
("charIndex", Strings.GetString ("ArgRange_Array"));
if (charCount < 0 || charCount > (chars.Length - charIndex))
throw new ArgumentOutOfRangeException
("charCount", Strings.GetString ("ArgRange_Array"));
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");
if (charCount == 0)
return 0;
unsafe {
fixed (char* cptr = chars) {
fixed (byte* bptr = bytes) {
return GetBytesImpl (cptr + charIndex,
charCount,
bptr + byteIndex,
bytes.Length - byteIndex,
flush);
}
}
}
}
public unsafe abstract int GetByteCountImpl (char* chars, int charCount, bool refresh);
public unsafe abstract int GetBytesImpl (char* chars, int charCount, byte* bytes, int byteCount, bool refresh);
#if NET_2_0
public unsafe override int GetBytes (char* chars, int charCount, byte* bytes, int byteCount, bool flush)
{
return GetBytesImpl (chars, charCount, bytes, byteCount, flush);
}
public unsafe void HandleFallback (
char* chars, ref int charIndex, ref int charCount,
byte* bytes, ref int byteIndex, ref int byteCount, object state)
{
EncoderFallbackBuffer buffer = FallbackBuffer;
encoding.HandleFallback (ref buffer,
chars, ref charIndex, ref charCount,
bytes, ref byteIndex, ref byteCount, state);
}
/* public unsafe void HandleFallback(
char* chars, ref int charIndex, ref int charCount,
byte* bytes, ref int byteIndex, ref int byteCount)
{
HandleFallback(chars, ref charIndex, ref charCount,
bytes, ref byteIndex, ref byteCount, null);
}*/
#endif
}
}

View File

@@ -0,0 +1,111 @@
//
// MonoEncoding.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
// Pablo Ruiz Garc<72>a <pruiz@netway.org>
//
// Copyright (C) 2005 Novell, Inc. http://www.novell.com
// Copyright (C) 2011 Pablo Ruiz Garc<72>a
//
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace I18N.Common
{
#if DISABLE_UNSAFE
[Serializable]
public abstract class MonoSafeEncoding : Encoding
{
readonly int win_code_page;
public MonoSafeEncoding (int codePage)
: this (codePage, 0)
{
}
public MonoSafeEncoding(int codePage, int windowsCodePage)
: base (codePage)
{
win_code_page = windowsCodePage;
}
public override int WindowsCodePage {
get { return win_code_page != 0 ? win_code_page : base.WindowsCodePage; }
}
/// <summary>
/// GetBytes method used internally by state-full encoders/encodings.
/// </summary>
/// <param name="chars">The chars.</param>
/// <param name="charIndex">Index of the char.</param>
/// <param name="charCount">The char count.</param>
/// <param name="bytes">The bytes.</param>
/// <param name="byteIndex">Index of the byte.</param>
/// <param name="flush">if set to <c>true</c> [flush].</param>
/// <param name="encoding">The encoding class to use (or null if state-less).</param>
/// <returns></returns>
/// <remarks>
/// Only state-full encoders need to implement this method (ie. ISO-2022-JP)
/// </remarks>
protected virtual int GetBytesInternal(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex, bool flush, object state)
{
throw new NotImplementedException("Statefull encoding is not implemented (yet?) by this encoding class.");
}
public void HandleFallback(ref EncoderFallbackBuffer buffer,
char[] chars, ref int charIndex, ref int charCount,
byte[] bytes, ref int byteIndex, ref int byteCount, object state)
{
if (buffer == null)
buffer = EncoderFallback.CreateFallbackBuffer();
if (charCount > 1 && (Char.IsSurrogate(chars[charIndex]) && Char.IsSurrogate(chars[charIndex + 1])))
{
buffer.Fallback (chars[charIndex], chars[charIndex + 1], charIndex);
charIndex++;
charCount--;
}
else
buffer.Fallback (chars[charIndex], charIndex);
char[] tmp = new char[buffer.Remaining];
int idx = 0;
while (buffer.Remaining > 0)
tmp[idx++] = buffer.GetNextChar();
var len = state == null ?
GetBytes(tmp, 0, tmp.Length, bytes, byteIndex)
: GetBytesInternal(tmp, 0, tmp.Length, bytes, byteIndex, true, state);
byteIndex += len;
byteCount -= len;
}
}
public abstract class MonoSafeEncoder : Encoder
{
#if NET_2_0
MonoSafeEncoding encoding;
#endif
public MonoSafeEncoder (MonoSafeEncoding encoding)
{
#if NET_2_0
this.encoding = encoding;
#endif
}
public void HandleFallback(
char[] chars, ref int charIndex, ref int charCount,
byte[] bytes, ref int byteIndex, ref int byteCount, object state)
{
EncoderFallbackBuffer buffer = FallbackBuffer;
encoding.HandleFallback(ref buffer, chars, ref charIndex, ref charCount,
bytes, ref byteIndex, ref byteCount, state);
}
}
#endif
}

View File

@@ -0,0 +1,63 @@
/*
* Strings.cs - Implementation of the "I18N.Common.Strings" class.
*
* 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.Common
{
using System;
using System.Reflection;
using System.Resources;
// This class provides string resource support to the rest
// of the I18N library assemblies.
public sealed class Strings
{
// Cached copy of the resources for this assembly.
// private static ResourceManager resources = null;
// Helper for obtaining string resources for this assembly.
public static String GetString(String tag)
{
switch (tag) {
case "ArgRange_Array":
return "Argument index is out of array range.";
case "Arg_InsufficientSpace":
return "Insufficient space in the argument array.";
case "ArgRange_NonNegative":
return "Non-negative value is expected.";
case "NotSupp_MissingCodeTable":
return "This encoding is not supported. Code table is missing.";
case "ArgRange_StringIndex":
return "String index is out of range.";
case "ArgRange_StringRange":
return "String length is out of range.";
default:
throw new ArgumentException (String.Format ("Unexpected error tag name: {0}", tag));
}
}
}; // class Strings
}; // namespace I18N.Common