These will need to be tested. They are a straight port from the Windows implementation, but the implementation has diverged, and it's possible (likely) there are some differences I didn't catch.
get { return Environment.GetResourceString("Overflow_TimeSpanTooLong"); }
}
+ public static string Serialization_MemberOutOfRange
+ {
+ get { return Environment.GetResourceString("Serialization_MemberOutOfRange"); }
+ }
+
public static string Format(string formatString, params object[] args)
{
return string.Format(CultureInfo.CurrentCulture, formatString, args);
using System.Runtime.CompilerServices;
using System.Globalization;
using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
namespace System.Globalization
{
// The calculation of hour/minute/second is moved to Calendar from GregorianCalendar,
// since most of the calendars (or all?) have the same way of calcuating hour/minute/second.
-
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class Calendar : ICloneable
{
private int m_currentEraValue = -1;
-
+ [OptionalField(VersionAdded = 2)]
private bool m_isReadOnly = false;
#if INSIDE_CLR
namespace System.Globalization
{
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public enum CalendarWeekRule
{
** Gregorian 1901/02/19 2101/01/28
** ChineseLunisolar 1901/01/01 2100/12/29
*/
-
+ [Serializable]
public class ChineseLunisolarCalendar : EastAsianLunisolarCalendar
{
//
public partial class CompareInfo
{
[SecurityCritical]
- private readonly Interop.GlobalizationInterop.SafeSortHandle m_sortHandle;
+ [NonSerialized]
+ private Interop.GlobalizationInterop.SafeSortHandle m_sortHandle;
- private readonly bool m_isAsciiEqualityOrdinal;
+ [NonSerialized]
+ private bool m_isAsciiEqualityOrdinal;
[SecuritySafeCritical]
internal CompareInfo(CultureInfo culture)
{
m_name = culture.m_name;
+ InitSort(culture);
+ }
+
+ private void InitSort(CultureInfo culture)
+ {
m_sortName = culture.SortName;
m_sortHandle = Interop.GlobalizationInterop.GetSortHandle(GetNullTerminatedUtf8String(m_sortName));
m_isAsciiEqualityOrdinal = (m_sortName == "en-US" || m_sortName == "");
{
internal unsafe CompareInfo(CultureInfo culture)
{
- const uint LCMAP_SORTHANDLE = 0x20000000;
-
this.m_name = culture.m_name;
+ InitSort(culture);
+ }
+
+ private void InitSort(CultureInfo culture)
+ {
this.m_sortName = culture.SortName;
+ const uint LCMAP_SORTHANDLE = 0x20000000;
long handle;
int ret = Interop.mincore.LCMapStringEx(m_sortName, LCMAP_SORTHANDLE, null, 0, (IntPtr)(&handle), IntPtr.Size, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
}
// PAL ends here
+ [NonSerialized]
private readonly IntPtr _sortHandle;
private const uint LCMAP_HASH = 0x00040000;
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
using System.Threading;
-using System.Diagnostics.Contracts;
namespace System.Globalization
{
[Flags]
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public enum CompareOptions
{
Ordinal = 0x40000000, // This flag can not be used with other flags.
}
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
- public partial class CompareInfo
+ public partial class CompareInfo : IDeserializationCallback
{
// Mask used to check if IndexOf()/LastIndexOf()/IsPrefix()/IsPostfix() has the right flags.
private const CompareOptions ValidIndexMaskOffFlags =
// The interesting part is that since haw-US doesn't have its own sort, it has to point at another
// locale, which is what SCOMPAREINFO does.
- private readonly String m_name; // The name used to construct this CompareInfo
- private readonly String m_sortName; // The name that defines our behavior
+ [OptionalField(VersionAdded = 2)]
+ private String m_name; // The name used to construct this CompareInfo
+ [NonSerialized]
+ private String m_sortName; // The name that defines our behavior
/*=================================GetCompareInfo==========================
**Action: Get the CompareInfo for the specified culture.
return CultureInfo.GetCultureInfo(name).CompareInfo;
}
+ [OnDeserializing]
+ private void OnDeserializing(StreamingContext ctx)
+ {
+ m_name = null;
+ }
+
+ void IDeserializationCallback.OnDeserialization(Object sender)
+ {
+ OnDeserialized();
+ }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ OnDeserialized();
+ }
+
+ private void OnDeserialized()
+ {
+ if (m_name != null)
+ {
+ InitSort(CultureInfo.GetCultureInfo(m_name));
+ }
+ }
+
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx) { }
///////////////////////////----- Name -----/////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////
using System;
-using System.Security;
-using System.Threading;
using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using System.Diagnostics.Contracts;
-using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Security;
+using System.Threading;
namespace System.Globalization
{
using StringCultureInfoDictionary = LowLevelDictionary<string, CultureInfo>;
#endif
+ [Serializable]
public partial class CultureInfo : IFormatProvider, ICloneable
{
//--------------------------------------------------------------------//
// For supported culture, this will be the CultureData instance that read data from mscorlib assembly.
// For customized culture, this will be the CultureData instance that read data from user customized culture binary file.
//
+ [NonSerialized]
internal CultureData m_cultureData;
+ [NonSerialized]
internal bool m_isInherited;
// Names are confusing. Here are 3 names we have:
// This will hold the non sorting name to be returned from CultureInfo.Name property.
// This has a de-DE style name even for de-DE_phoneb type cultures
+ [NonSerialized]
private string m_nonSortName;
// This will hold the sorting name to be returned from CultureInfo.SortName property.
// This might be completely unrelated to the culture name if a custom culture. Ie en-US for fj-FJ.
// Otherwise its the sort name, ie: de-DE or de-DE_phoneb
+ [NonSerialized]
private string m_sortName;
private static volatile StringCultureInfoDictionary s_NameCachedCultures;
//The parent culture.
+ [NonSerialized]
private CultureInfo m_parent;
static AsyncLocal<CultureInfo> s_asyncLocalCurrentCulture;
SR.ArgumentNull_String);
}
+ InitializeFromName(name, useUserOverride);
+ }
+
+ private void InitializeFromName(string name, bool useUserOverride)
+ {
// Get our data providing record
this.m_cultureData = CultureData.GetCultureData(name, useUserOverride);
if (this.m_cultureData == null)
- throw new CultureNotFoundException(
- "name", name, SR.Argument_CultureNotSupported);
+ {
+ throw new CultureNotFoundException("name", name, SR.Argument_CultureNotSupported);
+ }
this.m_name = this.m_cultureData.CultureName;
this.m_isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
}
-
// We do this to try to return the system UI language and the default user languages
// This method will fallback if this fails (like Invariant)
//
return VerifyCultureName(culture.Name, throwException);
}
+ // We need to store the override from the culture data record.
+ private bool m_useUserOverride;
+
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx)
+ {
+ m_name = m_cultureData.CultureName;
+ m_useUserOverride = m_cultureData.UseUserOverride;
+ }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ Contract.Assert(m_name != null, "[CultureInfo.OnDeserialized] m_name != null");
+ InitializeFromName(m_name, m_useUserOverride);
+ }
+
////////////////////////////////////////////////////////////////////////
//
// CurrentCulture
using System;
using System.Threading;
+using System.Runtime.Serialization;
namespace System.Globalization
{
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
- public class CultureNotFoundException : ArgumentException
+ public class CultureNotFoundException : ArgumentException, ISerializable
{
private string m_invalidCultureName; // unrecognized culture name
m_invalidCultureName = invalidCultureName;
}
+ protected CultureNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ m_invalidCultureName = (string)info.GetValue("InvalidCultureName", typeof(string));
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException("info");
+ }
+
+ base.GetObjectData(info, context);
+ info.AddValue("InvalidCultureName", m_invalidCultureName, typeof(string));
+ }
public virtual string InvalidCultureName
{
// See the LICENSE file in the project root for more information.
using System;
-using System.Security;
-using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Security;
using System.Text;
+using System.Threading;
namespace System.Globalization
{
}
-
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class DateTimeFormatInfo : IFormatProvider, ICloneable
{
private static volatile DateTimeFormatInfo invariantInfo;
// an index which points to a record in Culture Data Table.
+ [NonSerialized]
private CultureData m_cultureData;
// The culture name used to create this DTFI.
+ [OptionalField(VersionAdded = 2)]
internal String m_name = null;
// The language name of the culture used to create this DTFI.
+ [NonSerialized]
private String m_langName = null;
// CompareInfo usually used by the parser.
+ [NonSerialized]
private CompareInfo m_compareInfo = null;
// Culture matches current DTFI. mainly used for string comparisons during parsing.
+ [NonSerialized]
private CultureInfo m_cultureInfo = null;
//
internal String longTimePattern = null;
internal String shortTimePattern = null;
+ [OptionalField(VersionAdded = 3)]
private String[] allYearMonthPatterns = null;
internal String[] allShortDatePatterns = null;
internal String[] allLongDatePatterns = null;
Contract.Assert(this.allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
}
+ [OptionalField(VersionAdded = 1)]
+ private bool m_useUserOverride;
+
// This was synthesized by Whidbey so we knew what words might appear in the middle of a date string
// Now we always synthesize so its not helpful
internal String[] m_dateWords = null;
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx)
+ {
+ m_name = this.CultureName; // make sure the m_name is initialized.
+ m_useUserOverride = this.m_cultureData.UseUserOverride;
+
+ // Important to initialize these fields otherwise we may run into exception when deserializing on Whidbey
+ // because Whidbey try to initialize some of these fields using calendar data which could be null values
+ // and then we get exceptions. So we call the accessors to force the caches to get loaded.
+ Object o;
+ o = this.LongTimePattern;
+ o = this.LongDatePattern;
+ o = this.ShortTimePattern;
+ o = this.ShortDatePattern;
+ o = this.YearMonthPattern;
+ o = this.AllLongTimePatterns;
+ o = this.AllLongDatePatterns;
+ o = this.AllShortTimePatterns;
+ o = this.AllShortDatePatterns;
+ o = this.AllYearMonthPatterns;
+ }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ if (m_name != null)
+ {
+ m_cultureData = CultureData.GetCultureData(m_name, m_useUserOverride);
+ if (m_cultureData == null)
+ {
+ throw new CultureNotFoundException("m_name", m_name, SR.Argument_CultureNotSupported);
+ }
+ }
+
+ if (calendar == null)
+ {
+ calendar = (Calendar)GregorianCalendar.GetDefaultInstance().Clone();
+ calendar.SetReadOnlyState(m_isReadOnly);
+ }
+
+ InitializeOverridableProperties(m_cultureData, calendar.ID);
+
+ //
+ // turn off read only state till we finish initializing all fields and then store read only state after we are done.
+ //
+ bool isReadOnly = m_isReadOnly;
+ m_isReadOnly = false;
+
+ // If we deserialized defaults ala Whidbey, make sure they're still defaults
+ // Whidbey's arrays could get a bit mixed up.
+ if (longDatePattern != null) this.LongDatePattern = longDatePattern;
+ if (shortDatePattern != null) this.ShortDatePattern = shortDatePattern;
+ if (yearMonthPattern != null) this.YearMonthPattern = yearMonthPattern;
+ if (longTimePattern != null) this.LongTimePattern = longTimePattern;
+ if (shortTimePattern != null) this.ShortTimePattern = shortTimePattern;
+
+ m_isReadOnly = isReadOnly;
+ }
+
// Returns a default DateTimeFormatInfo that will be universally
// supported and constant irrespective of the current culture.
// Used by FromString methods.
{
// This class represents a starting/ending time for a period of daylight saving time.
-
+ [Serializable]
internal class DaylightTime
{
internal DateTime m_start;
//
////////////////////////////////////////////////////////////////////////////
-
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class EastAsianLunisolarCalendar : Calendar
{
//
-using System.Threading;
using System;
using System.Globalization;
using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Threading;
namespace System.Globalization
{
// 0 CurrentEra (AD)
// 1 BeforeCurrentEra (BC)
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class GregorianCalendar : Calendar
private static volatile Calendar s_defaultInstance;
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ if (m_type < GregorianCalendarTypes.Localized ||
+ m_type > GregorianCalendarTypes.TransliteratedFrench)
+ {
+ throw new SerializationException(
+ String.Format(CultureInfo.CurrentCulture, SR.Serialization_MemberOutOfRange, "type", "GregorianCalendar"));
+ }
+ }
[System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MinSupportedDateTime
// See the LICENSE file in the project root for more information.
using System;
-using System.Threading;
using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Threading;
namespace System.Globalization
{
// Gregorian Calendars use Era Info
+ [Serializable]
internal class EraInfo
{
internal int era; // The value of the era.
// be affected by the DateTime.MinValue;
internal int maxEraYear; // Max year value in this era. (== the year length of the era + 1)
+ [OptionalField(VersionAdded = 4)]
internal String eraName; // The era name
+ [OptionalField(VersionAdded = 4)]
internal String abbrevEraName; // Abbreviated Era Name
+ [OptionalField(VersionAdded = 4)]
internal String englishEraName; // English era name
internal EraInfo(int era, int startYear, int startMonth, int startDay, int yearOffset, int minEraYear, int maxEraYear)
// This calendar recognizes two era values:
// 0 CurrentEra (AD)
// 1 BeforeCurrentEra (BC)
+ [Serializable]
internal class GregorianCalendarHelper
{
// 1 tick = 100ns = 10E-7 second
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
};
+ [OptionalField(VersionAdded = 1)]
internal int m_maxYear = 9999;
+ [OptionalField(VersionAdded = 1)]
internal int m_minYear;
internal Calendar m_Cal;
+ [OptionalField(VersionAdded = 1)]
internal EraInfo[] m_EraInfo;
+ [OptionalField(VersionAdded = 1)]
internal int[] m_eras = null;
{
// Note: The values of the members of this enum must match the coresponding values
// in the CalendarId enum (since we cast between GregorianCalendarTypes and CalendarId).
+ [Serializable]
public enum GregorianCalendarTypes
{
Localized = CalendarId.GREGORIAN,
// Gregorian to Hebrew Lunar from 1583 to 2239.
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class HebrewCalendar : Calendar
{
** Hijri 0001/01/01 9666/04/03
*/
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public partial class HijriCalendar : Calendar
{
============================================================================*/
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public partial class JapaneseCalendar : Calendar
{
** JapaneseLunisolar 1960/01/01 2049/12/29
*/
+ [Serializable]
public class JapaneseLunisolarCalendar : EastAsianLunisolarCalendar
{
//
//* Gregorian 0001/01/01 9999/12/31
//* Julia 0001/01/03 9999/10/19
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class JulianCalendar : Calendar
{
============================================================================*/
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class KoreanCalendar : Calendar
{
** KoreanLunisolar 918/01/01 2050/13/29
*/
+ [Serializable]
public class KoreanLunisolarCalendar : EastAsianLunisolarCalendar
{
//
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System.Text;
using System;
using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Text;
namespace System.Globalization
{
// CurrencySymbol "$" String used as local monetary symbol.
//
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
sealed public class NumberFormatInfo : IFormatProvider, ICloneable
{
internal String perMilleSymbol = "\u2030";
+ [OptionalField(VersionAdded = 2)]
internal String[] nativeDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
internal int numberDecimalDigits = 2;
// Is this NumberFormatInfo for invariant culture?
+ [OptionalField(VersionAdded = 2)]
internal bool m_isInvariant = false;
public NumberFormatInfo() : this(null)
{
}
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx) { }
+
+ [OnDeserializing]
+ private void OnDeserializing(StreamingContext ctx) { }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx) { }
static private void VerifyDecimalSeparator(String decSep, String propertyName)
{
** Persian 0001/01/01 9378/10/13
*/
+ [Serializable]
public class PersianCalendar : Calendar
{
public static readonly int PersianEra = 1;
using System;
using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
namespace System.Globalization
{
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class RegionInfo
{
this.m_name = this.m_cultureData.SREGIONNAME;
}
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx) { }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ m_cultureData = CultureData.GetCultureData(m_name, true);
+
+ if (m_cultureData == null)
+ {
+ throw new ArgumentException(
+ String.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidCultureName, m_name),
+ "m_name");
+ }
+
+ m_name = this.m_cultureData.SREGIONNAME;
+ }
+
////////////////////////////////////////////////////////////////////////
//
// GetCurrentRegion
using System;
using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
namespace System.Globalization
{
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class StringInfo
{
+ [OptionalField(VersionAdded = 2)]
private String m_str;
+ [NonSerialized]
private int[] m_indexes;
// Legacy constructor
this.String = value;
}
+ [OnDeserializing]
+ private void OnDeserializing(StreamingContext ctx)
+ {
+ m_str = String.Empty;
+ }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ if (m_str.Length == 0)
+ {
+ m_indexes = null;
+ }
+ }
+
[System.Runtime.InteropServices.ComVisible(false)]
public override bool Equals(Object value)
{
** Taiwan 01/01/01 8088/12/31
============================================================================*/
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class TaiwanCalendar : Calendar
{
** TaiwanLunisolar 1912/01/01 2050/13/29
*/
+ [Serializable]
public class TaiwanLunisolarCalendar : EastAsianLunisolarCalendar
{
// Since
using System.Collections;
using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
namespace System.Globalization
{
// This is public because GetTextElement() is public.
//
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class TextElementEnumerator : IEnumerator
{
private int index;
private int startIndex;
+ [NonSerialized]
private int strLen; // This is the length of the total string, counting from the beginning of string.
+ [NonSerialized]
private int currTextElementLen; // The current text element lenght after MoveNext() is called.
+ [OptionalField(VersionAdded = 2)]
private UnicodeCategory uc;
+ [OptionalField(VersionAdded = 2)]
private int charLen; // The next abstract char to look at after MoveNext() is called. It could be 1 or 2, depending on if it is a surrogate or not.
internal TextElementEnumerator(String str, int startIndex, int strLen)
Reset();
}
+ // the following fields is defined to keep the compatibility with Everett.
+ // don't change/remove the names/types of these fields.
+ private int endIndex;
+ private int nextTextElementLen;
+
+ [OnDeserializing]
+ private void OnDeserializing(StreamingContext ctx)
+ {
+ charLen = -1;
+ }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ strLen = endIndex + 1;
+ currTextElementLen = nextTextElementLen;
+
+ if (charLen == -1)
+ {
+ uc = CharUnicodeInfo.InternalGetUnicodeCategory(str, index, out charLen);
+ }
+ }
+
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx)
+ {
+ endIndex = strLen - 1;
+ nextTextElementLen = currTextElementLen;
+ }
+
public bool MoveNext()
{
if (index >= strLen)
{
public partial class TextInfo
{
- private readonly bool m_needsTurkishCasing;
+ private bool m_needsTurkishCasing;
//////////////////////////////////////////////////////////////////////////
////
m_cultureData = cultureData;
m_cultureName = m_cultureData.CultureName;
m_textInfoName = m_cultureData.STEXTINFO;
- m_needsTurkishCasing = NeedsTurkishCasing(m_textInfoName);
+ FinishInitialization(m_textInfoName);
+ }
+
+ private void FinishInitialization(string textInfoName)
+ {
+ m_needsTurkishCasing = NeedsTurkishCasing(textInfoName);
}
[SecuritySafeCritical]
//////////////////////////////////////////////////////////////////////////
internal unsafe TextInfo(CultureData cultureData)
{
- const uint LCMAP_SORTHANDLE = 0x20000000;
-
// This is our primary data source, we don't need most of the rest of this
this.m_cultureData = cultureData;
this.m_cultureName = this.m_cultureData.CultureName;
this.m_textInfoName = this.m_cultureData.STEXTINFO;
+ FinishInitialization(this.m_textInfoName);
+ }
+
+ private void FinishInitialization(string textInfoName)
+ {
+ const uint LCMAP_SORTHANDLE = 0x20000000;
long handle;
- int ret = Interop.mincore.LCMapStringEx(m_textInfoName, LCMAP_SORTHANDLE, null, 0, (IntPtr)(&handle), IntPtr.Size, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+ int ret = Interop.mincore.LCMapStringEx(textInfoName, LCMAP_SORTHANDLE, null, 0, (IntPtr)(&handle), IntPtr.Size, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
_sortHandle = ret > 0 ? (IntPtr)handle : IntPtr.Zero;
}
//
////////////////////////////////////////////////////////////////////////////
-using System.Security;
using System;
-using System.Text;
-using System.Threading;
-using System.Runtime;
using System.Diagnostics.Contracts;
-using System.Runtime.InteropServices;
+using System.Runtime;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Security;
+using System.Text;
+using System.Threading;
namespace System.Globalization
{
- public partial class TextInfo : ICloneable
+ [Serializable]
+ public partial class TextInfo : ICloneable, IDeserializationCallback
{
////--------------------------------------------------------------------//
//// Internal Information //
//// Variables.
////
+ [OptionalField(VersionAdded = 2)]
private String m_listSeparator;
+ [OptionalField(VersionAdded = 2)]
private bool m_isReadOnly = false;
////
//// know how to resolve custom locle names to sort ids so we have to have alredy resolved this.
////
- private readonly String m_cultureName; // Name of the culture that created this text info
- private readonly CultureData m_cultureData; // Data record for the culture that made us, not for this textinfo
- private readonly String m_textInfoName; // Name of the text info we're using (ie: m_cultureData.STEXTINFO)
+ [OptionalField(VersionAdded = 3)]
+ private String m_cultureName; // Name of the culture that created this text info
+ [NonSerialized]
+ private CultureData m_cultureData; // Data record for the culture that made us, not for this textinfo
+ [NonSerialized]
+ private String m_textInfoName; // Name of the text info we're using (ie: m_cultureData.STEXTINFO)
+ [NonSerialized]
private bool? m_IsAsciiCasingSameAsInvariant;
// Invariant text info
}
internal volatile static TextInfo s_Invariant;
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx) { }
+
+ [OnDeserializing]
+ private void OnDeserializing(StreamingContext ctx)
+ {
+ // Clear these so we can check if we've fixed them yet
+ this.m_cultureData = null;
+ this.m_cultureName = null;
+ }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ OnDeserialized();
+ }
+
+ void IDeserializationCallback.OnDeserialization(Object sender)
+ {
+ OnDeserialized();
+ }
+
+ private void OnDeserialized()
+ {
+ // this method will be called twice because of the support of IDeserializationCallback
+ if (this.m_cultureData == null)
+ {
+ // Get the text info name belonging to that culture
+ this.m_cultureData = CultureInfo.GetCultureInfo(m_cultureName).m_cultureData;
+ this.m_textInfoName = this.m_cultureData.STEXTINFO;
+ FinishInitialization(this.m_textInfoName);
+ }
+ }
+
//
// Internal ordinal comparison functions
//
** Thai 0544/01/01 10542/12/31
============================================================================*/
-
+ [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class ThaiBuddhistCalendar : Calendar
{
** UmAlQura 1318/01/01 1500/12/30
*/
+ [Serializable]
public class UmAlQuraCalendar : Calendar
{
internal const int MinCalendarYear = 1318;
namespace System.Globalization
{
+ [Serializable]
public enum UnicodeCategory
{
UppercaseLetter = 0,
#ifdef FEATURE_LEAK_CULTURE_INFO
CLR_BOOL m_isSafeCrossDomain;
#endif // FEATURE_LEAK_CULTURE_INFO
-#ifndef FEATURE_COREFX_GLOBALIZATION
CLR_BOOL m_useUserOverride;
-#endif
public:
CULTUREINFOBASEREF GetParent()