|
|
@@ -0,0 +1,148 @@
|
|
|
+// This is partially copied source from referencesource/mscorlib/system/text/encoding.cs, modifying a bit.
|
|
|
+
|
|
|
+// ==++==
|
|
|
+//
|
|
|
+// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
+//
|
|
|
+// ==--==
|
|
|
+
|
|
|
+
|
|
|
+using System;
|
|
|
+using System.Diagnostics.CodeAnalysis;
|
|
|
+using System.Diagnostics.Contracts;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
+using System.Runtime.Serialization;
|
|
|
+using System.Text;
|
|
|
+
|
|
|
+namespace I18N.Common
|
|
|
+{
|
|
|
+ [Serializable]
|
|
|
+ public class ReferenceSourceDefaultEncoder : Encoder, IObjectReference
|
|
|
+ {
|
|
|
+ private Encoding m_encoding;
|
|
|
+ [NonSerialized] private bool m_hasInitializedEncoding;
|
|
|
+
|
|
|
+ [NonSerialized] internal char charLeftOver;
|
|
|
+
|
|
|
+ public ReferenceSourceDefaultEncoder(Encoding encoding)
|
|
|
+ {
|
|
|
+ m_encoding = encoding;
|
|
|
+ m_hasInitializedEncoding = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Constructor called by serialization, have to handle deserializing from Everett
|
|
|
+ internal ReferenceSourceDefaultEncoder(SerializationInfo info, StreamingContext context)
|
|
|
+ {
|
|
|
+ if (info==null) throw new ArgumentNullException("info");
|
|
|
+ Contract.EndContractBlock();
|
|
|
+
|
|
|
+ // All we have is our encoding
|
|
|
+ this.m_encoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //this.m_fallback = (EncoderFallback) info.GetValue("m_fallback", typeof(EncoderFallback));
|
|
|
+ this.charLeftOver = (Char) info.GetValue("charLeftOver", typeof(Char));
|
|
|
+ }
|
|
|
+ catch (SerializationException)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Just get it from GetEncoding
|
|
|
+ [System.Security.SecurityCritical] // auto-generated
|
|
|
+ public Object GetRealObject(StreamingContext context)
|
|
|
+ {
|
|
|
+ // upon deserialization since the DefaultEncoder implement IObjectReference the
|
|
|
+ // serialization code tries to do the fixup. The fixup returns another
|
|
|
+ // IObjectReference (the DefaultEncoder) class and hence so on and on.
|
|
|
+ // Finally the deserialization logics fails after following maximum references
|
|
|
+ // unless we short circuit with the following
|
|
|
+ if (m_hasInitializedEncoding)
|
|
|
+ {
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ Encoder encoder = m_encoding.GetEncoder();
|
|
|
+ /*
|
|
|
+ if (m_fallback != null)
|
|
|
+ encoder.m_fallback = m_fallback;
|
|
|
+ if (charLeftOver != (char) 0)
|
|
|
+ {
|
|
|
+ EncoderNLS encoderNls = encoder as EncoderNLS;
|
|
|
+ if (encoderNls != null)
|
|
|
+ encoderNls.charLeftOver = charLeftOver;
|
|
|
+ }
|
|
|
+ */
|
|
|
+ return encoder;
|
|
|
+ }
|
|
|
+
|
|
|
+#if FEATURE_SERIALIZATION
|
|
|
+ // ISerializable implementation, get data for this object
|
|
|
+ [System.Security.SecurityCritical] // auto-generated_required
|
|
|
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
|
|
|
+ {
|
|
|
+ // Any info?
|
|
|
+ if (info==null) throw new ArgumentNullException("info");
|
|
|
+ Contract.EndContractBlock();
|
|
|
+
|
|
|
+ // All we have is our encoding
|
|
|
+ info.AddValue("encoding", this.m_encoding);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ // Returns the number of bytes the next call to GetBytes will
|
|
|
+ // produce if presented with the given range of characters and the given
|
|
|
+ // value of the flush parameter. The returned value takes into
|
|
|
+ // account the state in which the encoder was left following the last call
|
|
|
+ // to GetBytes. The state of the encoder is not affected by a call
|
|
|
+ // to this method.
|
|
|
+ //
|
|
|
+
|
|
|
+ public override int GetByteCount(char[] chars, int index, int count, bool flush)
|
|
|
+ {
|
|
|
+ return m_encoding.GetByteCount(chars, index, count);
|
|
|
+ }
|
|
|
+
|
|
|
+ [System.Security.SecurityCritical] // auto-generated
|
|
|
+ [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
|
|
|
+ public unsafe override int GetByteCount(char* chars, int count, bool flush)
|
|
|
+ {
|
|
|
+ return m_encoding.GetByteCount(chars, count);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Encodes a range of characters in a character array into a range of bytes
|
|
|
+ // in a byte array. The method encodes charCount characters from
|
|
|
+ // chars starting at index charIndex, storing the resulting
|
|
|
+ // bytes in bytes starting at index byteIndex. The encoding
|
|
|
+ // takes into account the state in which the encoder was left following the
|
|
|
+ // last call to this method. The flush parameter indicates whether
|
|
|
+ // the encoder should flush any shift-states and partial characters at the
|
|
|
+ // end of the conversion. To ensure correct termination of a sequence of
|
|
|
+ // blocks of encoded bytes, the last call to GetBytes should specify
|
|
|
+ // a value of true for the flush parameter.
|
|
|
+ //
|
|
|
+ // An exception occurs if the byte array is not large enough to hold the
|
|
|
+ // complete encoding of the characters. The GetByteCount method can
|
|
|
+ // be used to determine the exact number of bytes that will be produced for
|
|
|
+ // a given range of characters. Alternatively, the GetMaxByteCount
|
|
|
+ // method of the Encoding that produced this encoder can be used to
|
|
|
+ // determine the maximum number of bytes that will be produced for a given
|
|
|
+ // number of characters, regardless of the actual character values.
|
|
|
+ //
|
|
|
+
|
|
|
+ public override int GetBytes(char[] chars, int charIndex, int charCount,
|
|
|
+ byte[] bytes, int byteIndex, bool flush)
|
|
|
+ {
|
|
|
+ return m_encoding.GetBytes(chars, charIndex, charCount, bytes, byteIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ [System.Security.SecurityCritical] // auto-generated
|
|
|
+ [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
|
|
|
+ public unsafe override int GetBytes(char* chars, int charCount,
|
|
|
+ byte* bytes, int byteCount, bool flush)
|
|
|
+ {
|
|
|
+ return m_encoding.GetBytes(chars, charCount, bytes, byteCount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|