3c1f479b9d
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
149 lines
6.5 KiB
C#
149 lines
6.5 KiB
C#
// 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);
|
|
}
|
|
}
|
|
}
|