diff options
Diffstat (limited to 'src/mscorlib')
1082 files changed, 419502 insertions, 0 deletions
diff --git a/src/mscorlib/.gitmirrorall b/src/mscorlib/.gitmirrorall new file mode 100644 index 0000000000..9ee5c57b99 --- /dev/null +++ b/src/mscorlib/.gitmirrorall @@ -0,0 +1 @@ +This folder will be mirrored by the Git-TFS Mirror recursively.
\ No newline at end of file diff --git a/src/mscorlib/Common/PinnableBufferCache.cs b/src/mscorlib/Common/PinnableBufferCache.cs new file mode 100644 index 0000000000..fee3e46f46 --- /dev/null +++ b/src/mscorlib/Common/PinnableBufferCache.cs @@ -0,0 +1,666 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +#define ENABLE +#define MINBUFFERS +using System; +#if !FEATURE_CORECLR +using System.Diagnostics.Tracing; +#endif +using System.Runtime.InteropServices; +using System.Runtime.ConstrainedExecution; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Threading; +using System.Runtime.CompilerServices; +using System.Diagnostics; +using System.Security.Permissions; + +#if PINNABLEBUFFERCACHE_MSCORLIB +namespace System.Threading +#else +namespace System +#endif +{ + internal sealed class PinnableBufferCache + { + /// <summary> + /// Create a new cache for pinned byte[] buffers + /// </summary> + /// <param name="cacheName">A name used in diagnostic messages</param> + /// <param name="numberOfElements">The size of byte[] buffers in the cache (they are all the same size)</param> + public PinnableBufferCache(string cacheName, int numberOfElements) : this(cacheName, () => new byte[numberOfElements]) { } + + /// <summary> + /// Get a buffer from the buffer manager. If no buffers exist, allocate a new one. + /// </summary> + public byte[] AllocateBuffer() { return (byte[])Allocate(); } + + /// <summary> + /// Return a buffer back to the buffer manager. + /// </summary> + public void FreeBuffer(byte[] buffer) { Free(buffer); } + + /// <summary> + /// Create a PinnableBufferCache that works on any object (it is intended for OverlappedData) + /// This is only used in mscorlib. + /// </summary> +#if (ENABLE || MINBUFFERS) +#pragma warning disable 618 + [EnvironmentPermission(SecurityAction.Assert, Unrestricted = true)] +#pragma warning restore 618 + [System.Security.SecuritySafeCritical] +#endif + internal PinnableBufferCache(string cacheName, Func<object> factory) + { + m_NotGen2 = new List<object>(DefaultNumberOfBuffers); + m_factory = factory; +#if ENABLE + // Check to see if we should disable the cache. + string envVarName = "PinnableBufferCache_" + cacheName + "_Disabled"; + try + { + string envVar = Environment.GetEnvironmentVariable(envVarName); + if (envVar != null) + { + PinnableBufferCacheEventSource.Log.DebugMessage("Creating " + cacheName + " PinnableBufferCacheDisabled=" + envVar); + int index = envVar.IndexOf(cacheName, StringComparison.OrdinalIgnoreCase); + if (0 <= index) + { + // The cache is disabled because we haven't set the cache name. + PinnableBufferCacheEventSource.Log.DebugMessage("Disabling " + cacheName); + return; + } + } + } + catch + { + // Ignore failures when reading the environment variable. + } +#endif +#if MINBUFFERS + // Allow the environment to specify a minimum buffer count. + string minEnvVarName = "PinnableBufferCache_" + cacheName + "_MinCount"; + try + { + string minEnvVar = Environment.GetEnvironmentVariable(minEnvVarName); + if (minEnvVar != null) + { + if (int.TryParse(minEnvVar, out m_minBufferCount)) + CreateNewBuffers(); + } + } + catch + { + // Ignore failures when reading the environment variable. + } +#endif + + PinnableBufferCacheEventSource.Log.Create(cacheName); + m_CacheName = cacheName; + } + + /// <summary> + /// Get a object from the buffer manager. If no buffers exist, allocate a new one. + /// </summary> + [System.Security.SecuritySafeCritical] + internal object Allocate() + { +#if ENABLE + // Check to see whether or not the cache is disabled. + if (m_CacheName == null) + return m_factory(); +#endif + // Fast path, get it from our Gen2 aged m_FreeList. + object returnBuffer; + if (!m_FreeList.TryPop(out returnBuffer)) + Restock(out returnBuffer); + + // Computing free count is expensive enough that we don't want to compute it unless logging is on. + if (PinnableBufferCacheEventSource.Log.IsEnabled()) + { + int numAllocCalls = Interlocked.Increment(ref m_numAllocCalls); + if (numAllocCalls >= 1024) + { + lock (this) + { + int previousNumAllocCalls = Interlocked.Exchange(ref m_numAllocCalls, 0); + if (previousNumAllocCalls >= 1024) + { + int nonGen2Count = 0; + foreach (object o in m_FreeList) + { + if (GC.GetGeneration(o) < GC.MaxGeneration) + { + nonGen2Count++; + } + } + + PinnableBufferCacheEventSource.Log.WalkFreeListResult(m_CacheName, m_FreeList.Count, nonGen2Count); + } + } + } + + PinnableBufferCacheEventSource.Log.AllocateBuffer(m_CacheName, PinnableBufferCacheEventSource.AddressOf(returnBuffer), returnBuffer.GetHashCode(), GC.GetGeneration(returnBuffer), m_FreeList.Count); + } + return returnBuffer; + } + + /// <summary> + /// Return a buffer back to the buffer manager. + /// </summary> + [System.Security.SecuritySafeCritical] + internal void Free(object buffer) + { +#if ENABLE + // Check to see whether or not the cache is disabled. + if (m_CacheName == null) + return; +#endif + if (PinnableBufferCacheEventSource.Log.IsEnabled()) + PinnableBufferCacheEventSource.Log.FreeBuffer(m_CacheName, PinnableBufferCacheEventSource.AddressOf(buffer), buffer.GetHashCode(), m_FreeList.Count); + + + // After we've done 3 gen1 GCs, assume that all buffers have aged into gen2 on the free path. + if ((m_gen1CountAtLastRestock + 3) > GC.CollectionCount(GC.MaxGeneration - 1)) + { + lock (this) + { + if (GC.GetGeneration(buffer) < GC.MaxGeneration) + { + // The buffer is not aged, so put it in the non-aged free list. + m_moreThanFreeListNeeded = true; + PinnableBufferCacheEventSource.Log.FreeBufferStillTooYoung(m_CacheName, m_NotGen2.Count); + m_NotGen2.Add(buffer); + m_gen1CountAtLastRestock = GC.CollectionCount(GC.MaxGeneration - 1); + return; + } + } + } + + // If we discovered that it is indeed Gen2, great, put it in the Gen2 list. + m_FreeList.Push(buffer); + } + + #region Private + + /// <summary> + /// Called when we don't have any buffers in our free list to give out. + /// </summary> + /// <returns></returns> + [System.Security.SecuritySafeCritical] + private void Restock(out object returnBuffer) + { + lock (this) + { + // Try again after getting the lock as another thread could have just filled the free list. If we don't check + // then we unnecessarily grab a new set of buffers because we think we are out. + if (m_FreeList.TryPop(out returnBuffer)) + return; + + // Lazy init, Ask that TrimFreeListIfNeeded be called on every Gen 2 GC. + if (m_restockSize == 0) + Gen2GcCallback.Register(Gen2GcCallbackFunc, this); + + // Indicate to the trimming policy that the free list is insufficent. + m_moreThanFreeListNeeded = true; + PinnableBufferCacheEventSource.Log.AllocateBufferFreeListEmpty(m_CacheName, m_NotGen2.Count); + + // Get more buffers if needed. + if (m_NotGen2.Count == 0) + CreateNewBuffers(); + + // We have no buffers in the aged freelist, so get one from the newer list. Try to pick the best one. + // Debug.Assert(m_NotGen2.Count != 0); + int idx = m_NotGen2.Count - 1; + if (GC.GetGeneration(m_NotGen2[idx]) < GC.MaxGeneration && GC.GetGeneration(m_NotGen2[0]) == GC.MaxGeneration) + idx = 0; + returnBuffer = m_NotGen2[idx]; + m_NotGen2.RemoveAt(idx); + + // Remember any sub-optimial buffer so we don't put it on the free list when it gets freed. + if (PinnableBufferCacheEventSource.Log.IsEnabled() && GC.GetGeneration(returnBuffer) < GC.MaxGeneration) + { + PinnableBufferCacheEventSource.Log.AllocateBufferFromNotGen2(m_CacheName, m_NotGen2.Count); + } + + // If we have a Gen1 collection, then everything on m_NotGen2 should have aged. Move them to the m_Free list. + if (!AgePendingBuffers()) + { + // Before we could age at set of buffers, we have handed out half of them. + // This implies we should be proactive about allocating more (since we will trim them if we over-allocate). + if (m_NotGen2.Count == m_restockSize / 2) + { + PinnableBufferCacheEventSource.Log.DebugMessage("Proactively adding more buffers to aging pool"); + CreateNewBuffers(); + } + } + } + } + + /// <summary> + /// See if we can promote the buffers to the free list. Returns true if sucessful. + /// </summary> + [System.Security.SecuritySafeCritical] + private bool AgePendingBuffers() + { + if (m_gen1CountAtLastRestock < GC.CollectionCount(GC.MaxGeneration - 1)) + { + // Allocate a temp list of buffers that are not actually in gen2, and swap it in once + // we're done scanning all buffers. + int promotedCount = 0; + List<object> notInGen2 = new List<object>(); + PinnableBufferCacheEventSource.Log.AllocateBufferAged(m_CacheName, m_NotGen2.Count); + for (int i = 0; i < m_NotGen2.Count; i++) + { + // We actually check every object to ensure that we aren't putting non-aged buffers into the free list. + object currentBuffer = m_NotGen2[i]; + if (GC.GetGeneration(currentBuffer) >= GC.MaxGeneration) + { + m_FreeList.Push(currentBuffer); + promotedCount++; + } + else + { + notInGen2.Add(currentBuffer); + } + } + PinnableBufferCacheEventSource.Log.AgePendingBuffersResults(m_CacheName, promotedCount, notInGen2.Count); + m_NotGen2 = notInGen2; + + return true; + } + return false; + } + + /// <summary> + /// Generates some buffers to age into Gen2. + /// </summary> + private void CreateNewBuffers() + { + // We choose a very modest number of buffers initially because for the client case. This is often enough. + if (m_restockSize == 0) + m_restockSize = 4; + else if (m_restockSize < DefaultNumberOfBuffers) + m_restockSize = DefaultNumberOfBuffers; + else if (m_restockSize < 256) + m_restockSize = m_restockSize * 2; // Grow quickly at small sizes + else if (m_restockSize < 4096) + m_restockSize = m_restockSize * 3 / 2; // Less agressively at large ones + else + m_restockSize = 4096; // Cap how agressive we are + + // Ensure we hit our minimums + if (m_minBufferCount > m_buffersUnderManagement) + m_restockSize = Math.Max(m_restockSize, m_minBufferCount - m_buffersUnderManagement); + + PinnableBufferCacheEventSource.Log.AllocateBufferCreatingNewBuffers(m_CacheName, m_buffersUnderManagement, m_restockSize); + for (int i = 0; i < m_restockSize; i++) + { + // Make a new buffer. + object newBuffer = m_factory(); + + // Create space between the objects. We do this because otherwise it forms a single plug (group of objects) + // and the GC pins the entire plug making them NOT move to Gen1 and Gen2. by putting space between them + // we ensure that object get a chance to move independently (even if some are pinned). + var dummyObject = new object(); + m_NotGen2.Add(newBuffer); + } + m_buffersUnderManagement += m_restockSize; + m_gen1CountAtLastRestock = GC.CollectionCount(GC.MaxGeneration - 1); + } + + /// <summary> + /// This is the static function that is called from the gen2 GC callback. + /// The input object is the cache itself. + /// NOTE: The reason that we make this functionstatic and take the cache as a parameter is that + /// otherwise, we root the cache to the Gen2GcCallback object, and leak the cache even when + /// the application no longer needs it. + /// </summary> + [System.Security.SecuritySafeCritical] + private static bool Gen2GcCallbackFunc(object targetObj) + { + return ((PinnableBufferCache)(targetObj)).TrimFreeListIfNeeded(); + } + + /// <summary> + /// This is called on every gen2 GC to see if we need to trim the free list. + /// NOTE: DO NOT CALL THIS DIRECTLY FROM THE GEN2GCCALLBACK. INSTEAD CALL IT VIA A STATIC FUNCTION (SEE ABOVE). + /// If you register a non-static function as a callback, then this object will be leaked. + /// </summary> + [System.Security.SecuritySafeCritical] + private bool TrimFreeListIfNeeded() + { + int curMSec = Environment.TickCount; + int deltaMSec = curMSec - m_msecNoUseBeyondFreeListSinceThisTime; + PinnableBufferCacheEventSource.Log.TrimCheck(m_CacheName, m_buffersUnderManagement, m_moreThanFreeListNeeded, deltaMSec); + + // If we needed more than just the set of aged buffers since the last time we were called, + // we obviously should not be trimming any memory, so do nothing except reset the flag + if (m_moreThanFreeListNeeded) + { + m_moreThanFreeListNeeded = false; + m_trimmingExperimentInProgress = false; + m_msecNoUseBeyondFreeListSinceThisTime = curMSec; + return true; + } + + // We require a minimum amount of clock time to pass (10 seconds) before we trim. Ideally this time + // is larger than the typical buffer hold time. + if (0 <= deltaMSec && deltaMSec < 10000) + return true; + + // If we got here we have spend the last few second without needing to lengthen the free list. Thus + // we have 'enough' buffers, but maybe we have too many. + // See if we can trim + lock (this) + { + // Hit a race, try again later. + if (m_moreThanFreeListNeeded) + { + m_moreThanFreeListNeeded = false; + m_trimmingExperimentInProgress = false; + m_msecNoUseBeyondFreeListSinceThisTime = curMSec; + return true; + } + + var freeCount = m_FreeList.Count; // This is expensive to fetch, do it once. + + // If there is something in m_NotGen2 it was not used for the last few seconds, it is trimable. + if (m_NotGen2.Count > 0) + { + // If we are not performing an experiment and we have stuff that is waiting to go into the + // free list but has not made it there, it could be becasue the 'slow path' of restocking + // has not happened, so force this (which should flush the list) and start over. + if (!m_trimmingExperimentInProgress) + { + PinnableBufferCacheEventSource.Log.TrimFlush(m_CacheName, m_buffersUnderManagement, freeCount, m_NotGen2.Count); + AgePendingBuffers(); + m_trimmingExperimentInProgress = true; + return true; + } + + PinnableBufferCacheEventSource.Log.TrimFree(m_CacheName, m_buffersUnderManagement, freeCount, m_NotGen2.Count); + m_buffersUnderManagement -= m_NotGen2.Count; + + // Possibly revise the restocking down. We don't want to grow agressively if we are trimming. + var newRestockSize = m_buffersUnderManagement / 4; + if (newRestockSize < m_restockSize) + m_restockSize = Math.Max(newRestockSize, DefaultNumberOfBuffers); + + m_NotGen2.Clear(); + m_trimmingExperimentInProgress = false; + return true; + } + + // Set up an experiment where we use 25% less buffers in our free list. We put them in + // m_NotGen2, and if they are needed they will be put back in the free list again. + var trimSize = freeCount / 4 + 1; + + // We are OK with a 15% overhead, do nothing in that case. + if (freeCount * 15 <= m_buffersUnderManagement || m_buffersUnderManagement - trimSize <= m_minBufferCount) + { + PinnableBufferCacheEventSource.Log.TrimFreeSizeOK(m_CacheName, m_buffersUnderManagement, freeCount); + return true; + } + + // Move buffers from the free list back to the non-aged list. If we don't use them by next time, then we'll consider trimming them. + PinnableBufferCacheEventSource.Log.TrimExperiment(m_CacheName, m_buffersUnderManagement, freeCount, trimSize); + object buffer; + for (int i = 0; i < trimSize; i++) + { + if (m_FreeList.TryPop(out buffer)) + m_NotGen2.Add(buffer); + } + m_msecNoUseBeyondFreeListSinceThisTime = curMSec; + m_trimmingExperimentInProgress = true; + } + + // Indicate that we want to be called back on the next Gen 2 GC. + return true; + } + + private const int DefaultNumberOfBuffers = 16; + private string m_CacheName; + private Func<object> m_factory; + + /// <summary> + /// Contains 'good' buffers to reuse. They are guarenteed to be Gen 2 ENFORCED! + /// </summary> + private ConcurrentStack<object> m_FreeList = new ConcurrentStack<object>(); + /// <summary> + /// Contains buffers that are not gen 2 and thus we do not wish to give out unless we have to. + /// To implement trimming we sometimes put aged buffers in here as a place to 'park' them + /// before true deletion. + /// </summary> + private List<object> m_NotGen2; + /// <summary> + /// What whas the gen 1 count the last time re restocked? If it is now greater, then + /// we know that all objects are in Gen 2 so we don't have to check. Should be updated + /// every time something gets added to the m_NotGen2 list. + /// </summary> + private int m_gen1CountAtLastRestock; + + /// <summary> + /// Used to ensure we have a minimum time between trimmings. + /// </summary> + private int m_msecNoUseBeyondFreeListSinceThisTime; + /// <summary> + /// To trim, we remove things from the free list (which is Gen 2) and see if we 'hit bottom' + /// This flag indicates that we hit bottom (we really needed a bigger free list). + /// </summary> + private bool m_moreThanFreeListNeeded; + /// <summary> + /// The total number of buffers that this cache has ever allocated. + /// Used in trimming heuristics. + /// </summary> + private int m_buffersUnderManagement; + /// <summary> + /// The number of buffers we added the last time we restocked. + /// </summary> + private int m_restockSize; + /// <summary> + /// Did we put some buffers into m_NotGen2 to see if we can trim? + /// </summary> + private bool m_trimmingExperimentInProgress; + /// <summary> + /// A forced minimum number of buffers. + /// </summary> + private int m_minBufferCount; + /// <summary> + /// The number of calls to Allocate. + /// </summary> + private int m_numAllocCalls; + + #endregion + } + + /// <summary> + /// Schedules a callback roughly every gen 2 GC (you may see a Gen 0 an Gen 1 but only once) + /// (We can fix this by capturing the Gen 2 count at startup and testing, but I mostly don't care) + /// </summary> + internal sealed class Gen2GcCallback : CriticalFinalizerObject + { + [System.Security.SecuritySafeCritical] + public Gen2GcCallback() + : base() + { + } + + /// <summary> + /// Schedule 'callback' to be called in the next GC. If the callback returns true it is + /// rescheduled for the next Gen 2 GC. Otherwise the callbacks stop. + /// + /// NOTE: This callback will be kept alive until either the callback function returns false, + /// or the target object dies. + /// </summary> + public static void Register(Func<object, bool> callback, object targetObj) + { + // Create a unreachable object that remembers the callback function and target object. + Gen2GcCallback gcCallback = new Gen2GcCallback(); + gcCallback.Setup(callback, targetObj); + } + + #region Private + + private Func<object, bool> m_callback; + private GCHandle m_weakTargetObj; + + [System.Security.SecuritySafeCritical] + private void Setup(Func<object, bool> callback, object targetObj) + { + m_callback = callback; + m_weakTargetObj = GCHandle.Alloc(targetObj, GCHandleType.Weak); + } + + [System.Security.SecuritySafeCritical] + ~Gen2GcCallback() + { + // Check to see if the target object is still alive. + object targetObj = m_weakTargetObj.Target; + if (targetObj == null) + { + // The target object is dead, so this callback object is no longer needed. + m_weakTargetObj.Free(); + return; + } + + // Execute the callback method. + try + { + if (!m_callback(targetObj)) + { + // If the callback returns false, this callback object is no longer needed. + return; + } + } + catch + { + // Ensure that we still get a chance to resurrect this object, even if the callback throws an exception. + } + + // Resurrect ourselves by re-registering for finalization. + if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload()) + { + GC.ReRegisterForFinalize(this); + } + } + + #endregion + } + + +#if FEATURE_CORECLR + internal sealed class PinnableBufferCacheEventSource + { + public static readonly PinnableBufferCacheEventSource Log = new PinnableBufferCacheEventSource(); + + public bool IsEnabled() { return false; } + public void DebugMessage(string message) {} + public void DebugMessage1(string message, long value) {} + public void DebugMessage2(string message, long value1, long value2) {} + public void DebugMessage3(string message, long value1, long value2, long value3) {} + public void Create(string cacheName) {} + public void AllocateBuffer(string cacheName, ulong objectId, int objectHash, int objectGen, int freeCountAfter) {} + public void AllocateBufferFromNotGen2(string cacheName, int notGen2CountAfter) {} + public void AllocateBufferCreatingNewBuffers(string cacheName, int totalBuffsBefore, int objectCount) {} + public void AllocateBufferAged(string cacheName, int agedCount) {} + public void AllocateBufferFreeListEmpty(string cacheName, int notGen2CountBefore) {} + public void FreeBuffer(string cacheName, ulong objectId, int objectHash, int freeCountBefore) {} + public void FreeBufferStillTooYoung(string cacheName, int notGen2CountBefore) {} + public void TrimCheck(string cacheName, int totalBuffs, bool neededMoreThanFreeList, int deltaMSec) {} + public void TrimFree(string cacheName, int totalBuffs, int freeListCount, int toBeFreed) {} + public void TrimExperiment(string cacheName, int totalBuffs, int freeListCount, int numTrimTrial) {} + public void TrimFreeSizeOK(string cacheName, int totalBuffs, int freeListCount) {} + public void TrimFlush(string cacheName, int totalBuffs, int freeListCount, int notGen2CountBefore) {} + public void AgePendingBuffersResults(string cacheName, int promotedToFreeListCount, int heldBackCount) {} + public void WalkFreeListResult(string cacheName, int freeListCount, int gen0BuffersInFreeList) {} + + static internal ulong AddressOf(object obj) + { + return 0; + } + + [System.Security.SecuritySafeCritical] + static internal unsafe long AddressOfObject(byte[] array) + { + return 0; + } + } +#else + /// <summary> + /// PinnableBufferCacheEventSource is a private eventSource that we are using to + /// debug and monitor the effectiveness of PinnableBufferCache + /// </summary> +#if PINNABLEBUFFERCACHE_MSCORLIB + [EventSource(Name = "Microsoft-DotNETRuntime-PinnableBufferCache")] +#else + [EventSource(Name = "Microsoft-DotNETRuntime-PinnableBufferCache-System")] +#endif + internal sealed class PinnableBufferCacheEventSource : EventSource + { + public static readonly PinnableBufferCacheEventSource Log = new PinnableBufferCacheEventSource(); + + [Event(1, Level = EventLevel.Verbose)] + public void DebugMessage(string message) { if (IsEnabled()) WriteEvent(1, message); } + [Event(2, Level = EventLevel.Verbose)] + public void DebugMessage1(string message, long value) { if (IsEnabled()) WriteEvent(2, message, value); } + [Event(3, Level = EventLevel.Verbose)] + public void DebugMessage2(string message, long value1, long value2) { if (IsEnabled()) WriteEvent(3, message, value1, value2); } + [Event(18, Level = EventLevel.Verbose)] + public void DebugMessage3(string message, long value1, long value2, long value3) { if (IsEnabled()) WriteEvent(18, message, value1, value2, value3); } + + [Event(4)] + public void Create(string cacheName) { if (IsEnabled()) WriteEvent(4, cacheName); } + + [Event(5, Level = EventLevel.Verbose)] + public void AllocateBuffer(string cacheName, ulong objectId, int objectHash, int objectGen, int freeCountAfter) { if (IsEnabled()) WriteEvent(5, cacheName, objectId, objectHash, objectGen, freeCountAfter); } + [Event(6)] + public void AllocateBufferFromNotGen2(string cacheName, int notGen2CountAfter) { if (IsEnabled()) WriteEvent(6, cacheName, notGen2CountAfter); } + [Event(7)] + public void AllocateBufferCreatingNewBuffers(string cacheName, int totalBuffsBefore, int objectCount) { if (IsEnabled()) WriteEvent(7, cacheName, totalBuffsBefore, objectCount); } + [Event(8)] + public void AllocateBufferAged(string cacheName, int agedCount) { if (IsEnabled()) WriteEvent(8, cacheName, agedCount); } + [Event(9)] + public void AllocateBufferFreeListEmpty(string cacheName, int notGen2CountBefore) { if (IsEnabled()) WriteEvent(9, cacheName, notGen2CountBefore); } + + [Event(10, Level = EventLevel.Verbose)] + public void FreeBuffer(string cacheName, ulong objectId, int objectHash, int freeCountBefore) { if (IsEnabled()) WriteEvent(10, cacheName, objectId, objectHash, freeCountBefore); } + [Event(11)] + public void FreeBufferStillTooYoung(string cacheName, int notGen2CountBefore) { if (IsEnabled()) WriteEvent(11, cacheName, notGen2CountBefore); } + + [Event(13)] + public void TrimCheck(string cacheName, int totalBuffs, bool neededMoreThanFreeList, int deltaMSec) { if (IsEnabled()) WriteEvent(13, cacheName, totalBuffs, neededMoreThanFreeList, deltaMSec); } + [Event(14)] + public void TrimFree(string cacheName, int totalBuffs, int freeListCount, int toBeFreed) { if (IsEnabled()) WriteEvent(14, cacheName, totalBuffs, freeListCount, toBeFreed); } + [Event(15)] + public void TrimExperiment(string cacheName, int totalBuffs, int freeListCount, int numTrimTrial) { if (IsEnabled()) WriteEvent(15, cacheName, totalBuffs, freeListCount, numTrimTrial); } + [Event(16)] + public void TrimFreeSizeOK(string cacheName, int totalBuffs, int freeListCount) { if (IsEnabled()) WriteEvent(16, cacheName, totalBuffs, freeListCount); } + [Event(17)] + public void TrimFlush(string cacheName, int totalBuffs, int freeListCount, int notGen2CountBefore) { if (IsEnabled()) WriteEvent(17, cacheName, totalBuffs, freeListCount, notGen2CountBefore); } + [Event(20)] + public void AgePendingBuffersResults(string cacheName, int promotedToFreeListCount, int heldBackCount) { if (IsEnabled()) WriteEvent(20, cacheName, promotedToFreeListCount, heldBackCount); } + [Event(21)] + public void WalkFreeListResult(string cacheName, int freeListCount, int gen0BuffersInFreeList) { if (IsEnabled()) WriteEvent(21, cacheName, freeListCount, gen0BuffersInFreeList); } + + + static internal ulong AddressOf(object obj) + { + var asByteArray = obj as byte[]; + if (asByteArray != null) + return (ulong)AddressOfByteArray(asByteArray); + return 0; + } + + [System.Security.SecuritySafeCritical] + static internal unsafe long AddressOfByteArray(byte[] array) + { + if (array == null) + return 0; + fixed (byte* ptr = array) + return (long)(ptr - 2 * sizeof(void*)); + } + } +#endif +} diff --git a/src/mscorlib/Common/Preprocessed/AssemblyRefs.g.cs b/src/mscorlib/Common/Preprocessed/AssemblyRefs.g.cs new file mode 100644 index 0000000000..24a1866a5d --- /dev/null +++ b/src/mscorlib/Common/Preprocessed/AssemblyRefs.g.cs @@ -0,0 +1,1082 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// #line 1 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\assemblyrefs.cspp" + +/* + * Assembly attributes. This file is preprocessed to generate a .cs file + * with the correct information. The original lives in VBL\Tools\DevDiv\ + */ + +using System; +using System.Reflection; +using System.Resources; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + + +// #line 1 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" +/** + * Version strings for Frameworks. + * + */ + +// +// Insert just the #defines in winver.h, so that the +// C# compiler can include this file after macro preprocessing. +// + + + + + + + + + +// #line 21 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + + +// +// winver.h is bad for rc.exe & csc.exe whereas verrsrc.h does not have an include guard +// yet defines the same structure twice if RC_INVOKED is not #defined. +// Temporarily enable RC_INVOKED protection around the #include. +// + + + + + + +// #line 1 "c:\\program files (x86)\\windows kits\\8.1\\include\\um\\verrsrc.h" +// #line 1 "c:\\program files (x86)\\windows kits\\8.1\\include\\shared\\winapifamily.h" +/* + + + +Module Name: + + winapifamily.h + +Abstract: + + Master include file for API family partitioning. + +*/ + + + + + +// #pragma once +// #line 21 "c:\\program files (x86)\\windows kits\\8.1\\include\\shared\\winapifamily.h" + +/* + * When compiling C and C++ code using SDK header files, the development + * environment can specify a target platform by #define-ing the + * pre-processor symbol WINAPI_FAMILY to one of the following values. + * Each FAMILY value denotes an application family for which a different + * subset of the total set of header-file-defined APIs are available. + * Setting the WINAPI_FAMILY value will effectively hide from the + * editing and compilation environments the existence of APIs that + * are not applicable to the family of applications targeting a + * specific platform. + */ + +/* + * The WINAPI_FAMILY values of 0 and 1 are reserved to ensure that + * an error will occur if WINAPI_FAMILY is set to any + * WINAPI_PARTITION value (which must be 0 or 1, see below). + */ + + + +/* The value of WINAPI_FAMILY_DESKTOP_APP may change in future SDKs. */ +/* Additional WINAPI_FAMILY values may be defined in future SDKs. */ + +/* + * For compatibility with Windows 8 header files, the following + * synonym for WINAPI_FAMILY_PC_APP is temporarily #define'd. + * Use of this symbol should be considered deprecated. + */ + + +/* + * If no WINAPI_FAMILY value is specified, then all APIs available to + * Windows desktop applications are exposed. + */ + + +// #line 59 "c:\\program files (x86)\\windows kits\\8.1\\include\\shared\\winapifamily.h" + +/* + * API PARTITONs are part of an indirection mechanism for mapping between + * individual APIs and the FAMILYs to which they apply. + * Each PARTITION is a category or subset of named APIs. PARTITIONs + * are permitted to have overlapping membership -- some single API + * might be part of more than one PARTITION. In support of new + * FAMILYs that might be added in future SDKs, any single current + * PARTITION might in that future SDK be split into two or more new PARTITIONs. + * Accordingly, application developers should avoid taking dependencies on + * PARTITION names; developers' only dependency upon the symbols defined + * in this file should be their reliance on the WINAPI_FAMILY names and values. + */ + +/* + * Current PARTITIONS are each #undef'ed below, and then will be #define-ed + * to be either 1 or 0 or depending on the active WINAPI_FAMILY. + */ + + + + + + + +/* + * The mapping between families and partitions is summarized here. + * An X indicates that the given partition is active for the given + * platform/family. + * + * +---------------+ + * | *Partition* | + * +---+---+---+---+ + * | | | | P | + * | | | | H | + * | D | | | O | + * | E | | P | N | + * | S | | C | E | + * | K | | _ | _ | + * | T | A | A | A | + * +-------------------------+-+ O | P | P | P | + * | *Platform/Family* \| P | P | P | P | + * +---------------------------+---+---+---+---+ + * | WINAPI_FAMILY_DESKTOP_APP | X | X | X | | + * +---------------------------+---+---+---+---+ + * | WINAPI_FAMILY_PC_APP | | X | X | | + * +---------------------------+---+---+---+---+ + * | WINAPI_FAMILY_PHONE_APP | | X | | X | + * +---------------------------+---+---+---+---+ + * + * The table above is encoded in the following expressions, + * each of which evaluates to 1 or 0. + * + * Whenever a new family is added, all of these expressions + * need to be reconsidered. + */ + + +// #line 118 "c:\\program files (x86)\\windows kits\\8.1\\include\\shared\\winapifamily.h" + + + + + +/* + * For compatibility with Windows Phone 8 header files, the following + * synonym for WINAPI_PARTITION_PHONE_APP is temporarily #define'd. + * Use of this symbol should be regarded as deprecated. + */ + + +/* + * Header files use the WINAPI_FAMILY_PARTITION macro to assign one or + * more declarations to some group of partitions. The macro chooses + * whether the preprocessor will emit or omit a sequence of declarations + * bracketed by an #if/#endif pair. All header file references to the + * WINAPI_PARTITION_* values should be in the form of occurrences of + * WINAPI_FAMILY_PARTITION(...). + * + * For example, the following usage of WINAPI_FAMILY_PARTITION identifies + * a sequence of declarations that are part of both the Windows Desktop + * Partition and the Windows-Phone-Specific Store Partition: + * + * #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP) + * ... + * #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP) + * + * The comment on the closing #endif allow tools as well as people to find the + * matching #ifdef properly. + * + * Usages of WINAPI_FAMILY_PARTITION may be combined, when the partitition definitions are + * related. In particular one might use declarations like + * + * #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + * + * or + * + * #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + * + * Direct references to WINAPI_PARTITION_ values (eg #if !WINAPI_FAMILY_PARTITION_...) + * should not be used. + */ + + +/* + * Macro used to #define or typedef a symbol used for selective deprecation + * of individual methods of a COM interfaces that are otherwise available + * for a given set of partitions. + */ + + +/* + * For compatibility with Windows 8 header files, the following + * symbol is temporarily conditionally #define'd. Additional symbols + * like this should be not defined in winapifamily.h, but rather should be + * introduced locally to the header files of the component that needs them. + */ + + +// #line 179 "c:\\program files (x86)\\windows kits\\8.1\\include\\shared\\winapifamily.h" + +// #line 181 "c:\\program files (x86)\\windows kits\\8.1\\include\\shared\\winapifamily.h" +// #line 2 "c:\\program files (x86)\\windows kits\\8.1\\include\\um\\verrsrc.h" + +/**************************************************************************** +** * +* verrsrc.h - Version Resource definitions * +* * +* Include file declaring version resources in rc files * +* * +* * +* * +\*****************************************************************************/ + +// #pragma region Application Family + + +/* ----- Symbols ----- */ + + + + +/* ----- VS_VERSION.dwFileFlags ----- */ + + + + +// #line 27 "c:\\program files (x86)\\windows kits\\8.1\\include\\um\\verrsrc.h" + + + +/* ----- VS_VERSION.dwFileFlags ----- */ + + + + + + + +/* ----- VS_VERSION.dwFileOS ----- */ + + + + + + + + + + + + + + + + + + + +/* ----- VS_VERSION.dwFileType ----- */ + + + + + + + + +/* ----- VS_VERSION.dwFileSubtype for VFT_WINDOWS_DRV ----- */ + + + + + + + + + + + + + + +/* ----- VS_VERSION.dwFileSubtype for VFT_WINDOWS_FONT ----- */ + + + + +// #line 88 "c:\\program files (x86)\\windows kits\\8.1\\include\\um\\verrsrc.h" +// // #pragma region + +// #pragma region Desktop Family + + +/* ----- VerFindFile() flags ----- */ + + + + + + +/* ----- VerInstallFile() flags ----- */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// #line 171 "c:\\program files (x86)\\windows kits\\8.1\\include\\um\\verrsrc.h" +// #pragma region + +// #line 37 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + + + + +// +// Include the definitions for rmj, rmm, rup, rpt +// + +// #line 1 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\product_version.h" + + + + +// #line 6 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\product_version.h" + +// #line 1 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\version.h" +// #line 1 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\ndpversion_generated.h" + + + + +// #line 6 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\ndpversion_generated.h" + + + + + +// #line 1 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\buildnumber.h" + + + + +// #line 6 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\buildnumber.h" + + + + + + + + + + + + + + + + + + + + + + + + + +// #line 12 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\ndpversion_generated.h" +// #line 2 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\version.h" + + + + + + + + + + + + +// #line 8 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\product_version.h" + + + +// #line 1 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\asm_version.h" + + + + + + + + + + + +// #line 13 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\asm_version.h" + + + + + +// #line 19 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\asm_version.h" + +// #line 12 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\product_version.h" +// #line 13 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\product_version.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// #line 161 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\product_version.h" + + + + + +// #line 167 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\product_version.h" + + + + + +// #line 173 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\product_version.h" + + + + + + +// #line 180 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\product_version.h" + +// #line 48 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +/* + * Product version, name and copyright + */ + +// #line 1 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" + + + + +// #line 6 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" + + + +// #line 10 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" + + + + +// #line 15 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" +// #line 16 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" + +// The following copyright is intended for display in the Windows Explorer property box for a DLL or EXE +// See \\lca\pdm\TMGUIDE\Copyright\Crt_Tmk_Notices.xls for copyright guidelines +// + + + + +// #line 25 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" + + + +// #line 29 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" + + + + + + + +// #line 37 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" +// #line 38 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" + +// VSWhidbey #495749 +// Note: The following legal copyright is intended for situations where the copyright symbol doesn't display +// properly. For example, the following copyright should be displayed as part of the logo for DOS command-line +// applications. If you change the format or wording of the following copyright, you should apply the same +// change to fxresstrings.txt (for managed applications). + + + +// #line 48 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxverstrings.h" +// #line 54 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +/* + * File version, names, description. + */ + +// FX_VER_INTERNALNAME_STR is passed in by the build environment. + + + + + + + +// FX_VER_FILEDESCRIPTION_STR is defined in RC files that include fxver.h + + + +// #line 72 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + + + +// #line 78 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + + + + +// #line 85 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + +//URT_VFT passed in by the build environment. + + + + + + + +/* default is nodebug */ + + + + +// #line 102 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +// DEBUG flag is set for debug build, not set for retail build +// #if defined(DEBUG) || defined(_DEBUG) +// #define VER_DEBUG VS_FF_DEBUG +// #else // DEBUG +// #define VER_DEBUG 0 +// #endif // DEBUG + + +/* default is prerelease */ + + +// #line 115 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +// #line 117 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +// PRERELEASE flag is always set unless building SHIP version +// #ifndef _SHIP +// #define VER_PRERELEASE VS_FF_PRERELEASE +// #else +// #define VER_PRERELEASE 0 +// #endif // _SHIP + + + +// #line 128 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +// #line 130 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +// PRIVATEBUILD flag is set if not built by build lab +// #ifndef _VSBUILD +// #define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD +// #else // _VSBUILD +// #define VER_PRIVATEBUILD 0 +// #endif // _VSBUILD + + + +// #line 141 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +// #line 143 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + + + + + + + + + + + + + + + + + + +// #line 164 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + + + + + + + +// #line 174 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + + + +// #line 180 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + + + + + + +// #line 189 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + +// #line 193 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// #line 248 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +// #line 250 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + + + +// #line 254 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" + +// #line 256 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\include\\fxver.h" +// #line 24 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\assemblyrefs.cspp" + +internal static class FXAssembly { + internal const string Version = "4.0.0.0"; +} + + + + + + + + + + + + + + + +// #line 44 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\assemblyrefs.cspp" + +internal static class ThisAssembly { + internal const string Title = "System.Private.CoreLib.dll"; + internal const string Description = "System.Private.CoreLib.dll"; + internal const string DefaultAlias = "System.Private.CoreLib.dll"; + internal const string Copyright = "\u00A9 Microsoft Corporation. All rights reserved."; + internal const string Version = "4.0.0.0"; + internal const string InformationalVersion = "4.0.22306.0"; + internal const string DailyBuildNumberStr = "22306"; + internal const string BuildRevisionStr = "0"; + internal const int DailyBuildNumber = 22306; +} + + +#pragma warning disable 436 +internal static class AssemblyRef { + internal const string EcmaPublicKey = "b77a5c561934e089"; + internal const string EcmaPublicKeyToken = "b77a5c561934e089"; + internal const string EcmaPublicKeyFull = "00000000000000000400000000000000"; + + internal const string SilverlightPublicKey = "31bf3856ad364e35"; + internal const string SilverlightPublicKeyToken = "31bf3856ad364e35"; + internal const string SilverlightPublicKeyFull = "0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9"; + + internal const string SilverlightPlatformPublicKey = "7cec85d7bea7798e"; + internal const string SilverlightPlatformPublicKeyToken = "7cec85d7bea7798e"; + internal const string SilverlightPlatformPublicKeyFull = "00240000048000009400000006020000002400005253413100040000010001008D56C76F9E8649383049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B37AB"; + + + internal const string PlatformPublicKey = SilverlightPlatformPublicKey; + internal const string PlatformPublicKeyToken = SilverlightPlatformPublicKeyToken; + internal const string PlatformPublicKeyFull = SilverlightPlatformPublicKeyFull; + + + + +// #line 81 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\assemblyrefs.cspp" + + internal const string Mscorlib = "mscorlib, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + PlatformPublicKey; + internal const string SystemData = "System.Data, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey; + internal const string SystemDataOracleClient = "System.Data.OracleClient, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey; + internal const string System = "System, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + PlatformPublicKey; + internal const string SystemCore = "System.Core, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + PlatformPublicKey; + internal const string SystemNumerics = "System.Numerics, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + PlatformPublicKey; + internal const string SystemRuntimeRemoting = "System.Runtime.Remoting, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey; + internal const string SystemThreadingTasksDataflow = "System.Threading.Tasks.Dataflow, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + PlatformPublicKey; + internal const string SystemWindowsForms = "System.Windows.Forms, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey; + internal const string SystemXml = "System.Xml, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey; + + internal const string MicrosoftPublicKey = "b03f5f7f11d50a3a"; + internal const string MicrosoftPublicKeyToken = "b03f5f7f11d50a3a"; + internal const string MicrosoftPublicKeyFull = "002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293"; + + internal const string SharedLibPublicKey = "31bf3856ad364e35"; + internal const string SharedLibPublicKeyToken = "31bf3856ad364e35"; + internal const string SharedLibPublicKeyFull = "0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9"; + + internal const string SystemComponentModelDataAnnotations = "System.ComponentModel.DataAnnotations, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + SharedLibPublicKey; + internal const string SystemConfiguration = "System.Configuration, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemConfigurationInstall = "System.Configuration.Install, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemDeployment = "System.Deployment, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemDesign = "System.Design, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemDirectoryServices = "System.DirectoryServices, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemDrawingDesign = "System.Drawing.Design, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemDrawing = "System.Drawing, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemEnterpriseServices = "System.EnterpriseServices, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemManagement = "System.Management, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemMessaging = "System.Messaging, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemNetHttp = "System.Net.Http, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemNetHttpWebRequest = "System.Net.Http.WebRequest, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemRuntimeSerializationFormattersSoap = "System.Runtime.Serialization.Formatters.Soap, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemRuntimeWindowsRuntime = "System.Runtime.WindowsRuntime, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey; + internal const string SystemRuntimeWindowsRuntimeUIXaml = "System.Runtime.WindowsRuntimeUIXaml, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey; + internal const string SystemSecurity = "System.Security, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemServiceModelWeb = "System.ServiceModel.Web, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + SharedLibPublicKey; + internal const string SystemServiceProcess = "System.ServiceProcess, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemWeb = "System.Web, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemWebAbstractions = "System.Web.Abstractions, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + SharedLibPublicKey; + internal const string SystemWebDynamicData = "System.Web.DynamicData, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + SharedLibPublicKey; + internal const string SystemWebDynamicDataDesign = "System.Web.DynamicData.Design, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + SharedLibPublicKey; + internal const string SystemWebEntityDesign = "System.Web.Entity.Design, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey; + internal const string SystemWebExtensions = "System.Web.Extensions, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + SharedLibPublicKey; + internal const string SystemWebExtensionsDesign = "System.Web.Extensions.Design, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + SharedLibPublicKey; + internal const string SystemWebMobile = "System.Web.Mobile, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemWebRegularExpressions = "System.Web.RegularExpressions, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string SystemWebRouting = "System.Web.Routing, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + SharedLibPublicKey; + internal const string SystemWebServices = "System.Web.Services, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + + internal const string WindowsBase = "WindowsBase, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + SharedLibPublicKey; + + internal const string MicrosoftVisualStudio = "Microsoft.VisualStudio, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string MicrosoftVisualStudioWindowsForms = "Microsoft.VisualStudio.Windows.Forms, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string VJSharpCodeProvider = "VJSharpCodeProvider, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + + internal const string ASPBrowserCapsPublicKey = "b7bd7678b977bd8f"; + internal const string ASPBrowserCapsFactory = "ASP.BrowserCapsFactory, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + ASPBrowserCapsPublicKey; + + + // We do not want these sitting in non-VS specific files. If you need them, + // add this line to sources: + // C_DEFINES=$(C_DEFINES) /DINCLUDE_VSREFS + // + // M.VS.dll and M.VSDesigner.dll should also be included here, but it + // turns out that everyone, from Data, to XSP to Winforms to diagnostics + // has thrown some designer-specific code into M.VS.dll or M.VSDesigner.dll. + // + + + + + + +// #line 157 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\assemblyrefs.cspp" + + // VS Provided Assemblies... we can't strong bind to these, they + // update their assembly versions too often + // + internal const string MicrosoftVSDesigner = "Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string MicrosoftVisualStudioWeb = "Microsoft.VisualStudio.Web, Version=10.0.0.0, Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string MicrosoftWebDesign = "Microsoft.Web.Design.Client, Version=10.0.0.0, Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string MicrosoftVSDesignerMobile = "Microsoft.VSDesigner.Mobile, Version=8.0.0.0, Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + internal const string MicrosoftJScript = "Microsoft.JScript, Version=8.0.0.0, Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + + //internal const string MicrosoftVSDesigner = "Microsoft.VSDesigner, Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; + //internal const string MicrosoftJScript = "Microsoft.JScript, Culture=neutral, PublicKeyToken=" + MicrosoftPublicKey; +} +#pragma warning restore 436 +// #line 172 "d:\\projectk_2\\src\\ndp\\clr\\src\\bcl.oss\\open\\src\\common\\assemblyrefs.cspp" diff --git a/src/mscorlib/GenerateCompilerResponseFile.targets b/src/mscorlib/GenerateCompilerResponseFile.targets new file mode 100644 index 0000000000..ed9136ffc6 --- /dev/null +++ b/src/mscorlib/GenerateCompilerResponseFile.targets @@ -0,0 +1,22 @@ +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + + <PropertyGroup> + <CompileDependsOn>GenerateCompilerResponseFile;$(CompileDependsOn)</CompileDependsOn> + </PropertyGroup> + + <Target Name="GenerateCompilerResponseFile"> + <Message Text="Generating module name response file: $(IntermediateOutputPath)\moduleName.$(AssemblyName).rsp" /> + + <!-- We need to set the runtimemetadataversion --> + <WriteLinesToFile File="$(IntermediateOutputPath)\moduleName.$(AssemblyName).rsp" + Lines="/runtimemetadataversion:v4.0.30319" + Overwrite="true" /> + + <ItemGroup> + <Clean Include="$(IntermediateOutputPath)\moduleName.$(AssemblyName).rsp" /> + </ItemGroup> + <PropertyGroup> + <CompilerResponseFile>$(IntermediateOutputPath)\moduleName.$(AssemblyName).rsp;$(CompilerResponseFile)</CompilerResponseFile> + </PropertyGroup> + </Target> +</Project>
\ No newline at end of file diff --git a/src/mscorlib/GenerateSplitStringResources.targets b/src/mscorlib/GenerateSplitStringResources.targets new file mode 100644 index 0000000000..88e01cb612 --- /dev/null +++ b/src/mscorlib/GenerateSplitStringResources.targets @@ -0,0 +1,42 @@ +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <PrepareResourcesDependsOn>GenerateSplitStringResources;$(PrepareResourcesDependsOn)</PrepareResourcesDependsOn> + </PropertyGroup> + + <PropertyGroup> + <PreprocessFileTaskAsssemblyPath Condition="'$(PreprocessFileTaskAsssemblyPath)' == ''">$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll</PreprocessFileTaskAsssemblyPath> + </PropertyGroup> + + <UsingTask TaskName="PreprocessFile" AssemblyFile="$(PreprocessFileTaskAsssemblyPath)" /> + + <Target Name="GenerateSplitStringResources" + Inputs="@(SplitTextStringResource)" + Outputs="@(SplitTextStringResource->'$(IntermediateOutputPath)%(Filename).txt')"> + + <ItemGroup> + <Internal_ResGenDefines Remove="" /> + <Internal_ResGenDefines Include="INCLUDE_DEBUG" /> + <Internal_ResGenDefines Include="INCLUDE_RUNTIME" /> + <Internal_ResGenDefines Include="%(SplitTextStringResource.ResGenDefines)" /> + </ItemGroup> + + <PreprocessFile SourceFile="%(SplitTextStringResource.Identity)" OutputFile="$(IntermediateOutputPath)%(SplitTextStringResource.Filename).txt" Defines="@(Internal_ResGenDefines)" /> + + <GenerateResource Sources="$(IntermediateOutputPath)%(SplitTextStringResource.Filename).txt" + OutputResources="$(IntermediateOutputPath)%(SplitTextStringResource.Filename).resources" + ExecuteAsTool="false" /> + + <ItemGroup> + <EmbeddedResource Include="@(SplitTextStringResource->'$(IntermediateOutputPath)%(Filename).resources')"> + <WithCulture>false</WithCulture> + <ManifestResourceName>%(Filename)</ManifestResourceName> + </EmbeddedResource> + <Clean Include="$(IntermediateOutputPath)%(SplitTextStringResource.Filename).txt" /> + <Clean Include="$(IntermediateOutputPath)%(SplitTextStringResource.Filename).resources" /> + </ItemGroup> + + <ItemGroup> + <Internal_ResGenDefines Remove="" /> + </ItemGroup> + </Target> +</Project>
\ No newline at end of file diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj new file mode 100644 index 0000000000..c14ce422fb --- /dev/null +++ b/src/mscorlib/System.Private.CoreLib.csproj @@ -0,0 +1,226 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + + <!-- Include common build properties --> + <Import Project="..\..\dir.props" /> + + <!-- Compilation options --> + <PropertyGroup> + <AvailablePlatforms>amd64,x86,arm,arm-softfp,arm64</AvailablePlatforms> + <Configuration Condition=" '$(Configuration)' == '' ">$(BuildType)</Configuration> + <Platform Condition=" '$(Platform)' == '' ">$(BuildArch)</Platform> + <!-- The CLR properties use amd64 as their platform string, we want to keep in sync with those, so set Platform appropriately, + though still use the 'x64' output path (see use of BuildArch below) --> + <Platform Condition=" '$(Platform)' == 'x64' ">amd64</Platform> + <Platform Condition=" '$(Platform)' == 'arm-softfp' ">arm</Platform> + <ProjectGuid>{3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}</ProjectGuid> + + <OutputType>Library</OutputType> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + + <!-- This prevents the default MsBuild targets from referencing System.Core.dll --> + <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences> + <!-- These prevent the default MsBuild targets from referencing System.dll and mscorlib.dll --> + <NoStdLib>true</NoStdLib> + <NoCompilerStandardLib>true</NoCompilerStandardLib> + + <SubsystemVersion>6.00</SubsystemVersion> + <UTF8OutPut>true</UTF8OutPut> + <HighEntropyVA>true</HighEntropyVA> + <ErrorReport>prompt</ErrorReport> + <CLSCompliant>true</CLSCompliant> + <WarningLevel>4</WarningLevel> + <TreatWarningsAsErrors>false</TreatWarningsAsErrors> + <WarningsNotAsErrors>$(WarningsNotAsErrors);618</WarningsNotAsErrors> + <NoWarn>649,3019,414,169,3015</NoWarn> + <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute> + + <BclRewriterModelFile>$(MSBuildThisFileDirectory)model.xml</BclRewriterModelFile> + + <SignAssembly>true</SignAssembly> + <DelaySign>true</DelaySign> + + <DefineConstants>$(DefineConstants);_USE_NLS_PLUS_TABLE;RESOURCE_SATELLITE_CONFIG;INSIDE_CLR;CODE_ANALYSIS_BASELINE</DefineConstants> + </PropertyGroup> + + <!-- Add Serviceable attribute to the project's metadata --> + <ItemGroup> + <AssemblyMetadata Include="Serviceable"> + <Value>True</Value> + </AssemblyMetadata> + </ItemGroup> + + <!-- Platform specific properties --> + <PropertyGroup Condition="'$(Platform)' == 'amd64'"> + <PlatformTarget>x64</PlatformTarget> + <Prefer32Bit>false</Prefer32Bit> + <BaseAddress>0x180000000</BaseAddress> + <DefineConstants>BIT64;AMD64;$(DefineConstants)</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition="'$(Platform)' == 'x86'"> + <PlatformTarget>x86</PlatformTarget> + <BaseAddress>0x10000000</BaseAddress> + <DefineConstants>BIT32;$(DefineConstants)</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition="'$(Platform)' == 'arm'"> + <PlatformTarget>arm</PlatformTarget> + <DefineConstants>BIT32;ARM;$(DefineConstants)</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition="'$(Platform)' == 'arm64'"> + <PlatformTarget>AnyCPU</PlatformTarget> + <DefineConstants>BIT64;ARM64;$(DefineConstants)</DefineConstants> + </PropertyGroup> + + <!-- Configuration specific properties --> + <PropertyGroup Condition="'$(Configuration)' == 'Debug' or '$(Configuration)' == 'Checked'"> + <DebugSymbols>true</DebugSymbols> + <Optimize Condition="'$(Optimize)' == '' and '$(Configuration)' == 'Debug'">false</Optimize> + <Optimize Condition="'$(Optimize)' == '' and '$(Configuration)' == 'Checked'">true</Optimize> + <DebugType>full</DebugType> + <DefineConstants>DBG;_DEBUG;_LOGGING;DEBUG;TRACE;$(DefineConstants)</DefineConstants> + <DefineConstants Condition="'$(Platform)' == 'x86' or '$(Platform)' == 'amd64'">CODE_ANALYSIS;$(DefineConstants)</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)' == 'Release'"> + <DebugSymbols>true</DebugSymbols> + <Optimize Condition="'$(Optimize)' == ''">true</Optimize> + <DebugType>pdbOnly</DebugType> + <DefineConstants>TRACE;$(DefineConstants)</DefineConstants> + </PropertyGroup> + + <!-- Roslyn does not support writing PDBs on Unix --> + <PropertyGroup Condition="'$(OsEnvironment)' == 'Unix'"> + <DebugSymbols>false</DebugSymbols> + <DebugType>none</DebugType> + </PropertyGroup> + + <!-- Assembly attributes --> + <PropertyGroup> + <AssemblyName>System.Private.CoreLib</AssemblyName> + <AssemblyVersion>4.0.0.0</AssemblyVersion> + <MajorVersion>4</MajorVersion> + <MinorVersion>6</MinorVersion> + </PropertyGroup> + <ItemGroup> + <AssemblyInfoLines Include="[assembly: System.Resources.SatelliteContractVersion("$(AssemblyVersion)")]" /> + <AssemblyInfoLines Include="[assembly: System.Security.AllowPartiallyTrustedCallers]" /> + <AssemblyInfoLines Include="[assembly: System.Runtime.InteropServices.ComVisible(false)]" /> + <AssemblyInfoLines Include="[assembly: System.Resources.NeutralResourcesLanguage("en-US")]" /> + </ItemGroup> + + <!-- + Helper Paths + --> + <PropertyGroup> + <PostProcessingToolsPath Condition="'$(PostProcessingToolsPath)'==''">$(MSBuildThisFileDirectory)Tools\PostProcessingTools.targets</PostProcessingToolsPath> + <CommonPath>$(MSBuildThisFileDirectory)Common</CommonPath> + <BclSourcesRoot>$(MSBuildThisFileDirectory)src</BclSourcesRoot> + <CoreFxSourcesRoot>$(MSBuildThisFileDirectory)corefx</CoreFxSourcesRoot> + <MscorlibDir>$(MSBuildThisFileDirectory)</MscorlibDir> + <NlpObjDir>$(BclSourcesRoot)\System\Globalization\Tables</NlpObjDir> + </PropertyGroup> + + <!-- Output paths --> + <PropertyGroup> + <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)' == ''">$(RootBinDir)obj</BaseIntermediateOutputPath> + <IntermediateOutputPath Condition="'$(IntermediateOutputPath)' == ''">$(BaseIntermediateOutputPath)\$(BuildOS).$(BuildArch).$(Configuration)</IntermediateOutputPath> + <OutputPath Condition="'$(OutputPath)' == ''">$(BaseIntermediateOutputPath)\$(BuildOS).$(BuildArch).$(Configuration)</OutputPath> + <FinalOutputPath Condition="'$(FinalOutputPath)' == ''">$(BinDir)</FinalOutputPath> + </PropertyGroup> + + <!-- Msbuild variables needed to get CoreCLR features to be set properly. --> + <PropertyGroup> + <ClrProduct>core_clr</ClrProduct> + <BuildForCoreSystem>true</BuildForCoreSystem> + + <!-- These are needed by BCLRewriter --> + <_BuildType Condition="'$(Configuration)' == 'Debug'">chk</_BuildType> + <_BuildType Condition="'$(Configuration)' == 'Checked'">chk</_BuildType> + <_BuildType Condition="'$(Configuration)' == 'Release'">ret</_BuildType> + + <!-- These are needed to make sure we have the right set of defines --> + <TargetArch Condition="'$(Platform)'=='x86'">i386</TargetArch> + <TargetArch Condition="'$(Platform)'!='x86'">$(Platform)</TargetArch> + </PropertyGroup> + + <!-- CLR Features --> + <Import Project="$(MSBuildThisFileDirectory)..\..\clr.coreclr.props" /> + <Import Project="$(MSBuildThisFileDirectory)..\..\clr.defines.targets" /> + + <!-- Sources --> + <Import Project="$(MSBuildThisFileDirectory)\mscorlib.shared.sources.props" /> + + <!-- Include additional sources shared files in the compilation --> + <ItemGroup> + <!-- These are files are preprocessed --> + <MscorlibSources Include="$(CommonPath)\Preprocessed\AssemblyRefs.g.cs" /> + + <!-- These files are shared with other framework components and don't live the same folder as the rest of them--> + <MscorlibSources Include="$(CommonPath)\PinnableBufferCache.cs" /> + + <!-- Include Internals visible to file in the compilation --> + <MscorlibSources Include="$(BclSourcesRoot)\mscorlib.Friends.cs" /> + </ItemGroup> + + <ItemGroup> + <!-- We want the sources to show up nicely in VS--> + <Compile Include="@(MscorlibSources)"> + </Compile> + </ItemGroup> + + <!-- Resources --> + <ItemGroup> + <SplitTextStringResource Include="$(BclSourcesRoot)\System.Private.CoreLib.txt"> + <ResFile>System.Private.CoreLib</ResFile> + <ResGenDefines>$(DefineConstants)</ResGenDefines> + </SplitTextStringResource> + </ItemGroup> + + <PropertyGroup> + <CheckCDefines Condition="'$(CheckCDefines)'==''">true</CheckCDefines> + </PropertyGroup> + + <Target Name="CDefineChecker" BeforeTargets="Build" Condition="'$(CheckCDefines)'=='true'"> + <!-- Compiler Definition Verification --> + <Message Importance="High" Text="============" /> + <PropertyGroup> + <IgnoreDefineConstants>FEATURE_IMPLICIT_TLS;FEATURE_HIJACK</IgnoreDefineConstants> + <CMakeDefinitionSaveFile>$(IntermediateOutputPath)\cmake.definitions</CMakeDefinitionSaveFile> + </PropertyGroup> + <Exec Command='python $(MSBuildThisFileDirectory)..\scripts\check-definitions.py "$(CMakeDefinitionSaveFile)" "$(DefineConstants)" "$(IgnoreDefineConstants)" ' /> + <Message Importance="High" Text="============" /> + </Target> + + <ItemGroup> + <EmbeddedResource Include="$(NlpObjDir)\charinfo.nlp"> + <LogicalName>charinfo.nlp</LogicalName> + </EmbeddedResource> + </ItemGroup> + + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.Targets" /> + + <PropertyGroup> + <StrongNameSig>Silverlight</StrongNameSig> + </PropertyGroup> + + <!-- Import signing tools --> + <Import Condition="Exists('$(ToolsDir)\sign.targets')" Project="$(ToolsDir)\sign.targets" /> + + <!-- Overwrite the key that we are going to use for signing --> + <PropertyGroup> + <AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)Tools\Signing\mscorlib.snk</AssemblyOriginatorKeyFile> + </PropertyGroup> + + <Import Project="$(MSBuildThisFileDirectory)Tools\Versioning\GenerateVersionInfo.targets"/> + <!-- Override versioning targets --> + <Import Condition="Exists('$(ToolsDir)versioning.targets')" Project="$(ToolsDir)versioning.targets" /> + + <PropertyGroup> + <!-- Use a different nativeresource file to avoid conflicts with mscorlib--> + <Win32Resource Condition="'$(GenerateNativeVersionInfo)'=='true'">$(IntermediateOutputPath)\System.Private.CoreLib.res</Win32Resource> + </PropertyGroup> + + <Import Project="GenerateSplitStringResources.targets"/> + <Import Project="GenerateCompilerResponseFile.targets"/> + <Import Project="$(PostProcessingToolsPath)" /> +</Project> diff --git a/src/mscorlib/System.Private.CoreLib.sln b/src/mscorlib/System.Private.CoreLib.sln new file mode 100644 index 0000000000..4ab28af2d9 --- /dev/null +++ b/src/mscorlib/System.Private.CoreLib.sln @@ -0,0 +1,52 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Private.CoreLib", "System.Private.CoreLib.csproj", "{3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Checked|amd64 = Checked|amd64 + Checked|arm = Checked|arm + Checked|arm64 = Checked|arm64 + Checked|x86 = Checked|x86 + Debug|amd64 = Debug|amd64 + Debug|arm = Debug|arm + Debug|arm64 = Debug|arm64 + Debug|x86 = Debug|x86 + Release|amd64 = Release|amd64 + Release|arm = Release|arm + Release|arm64 = Release|arm64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|amd64.ActiveCfg = Checked|amd64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|amd64.Build.0 = Checked|amd64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm.ActiveCfg = Checked|arm + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm.Build.0 = Checked|arm + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm64.ActiveCfg = Checked|arm64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm64.Build.0 = Checked|arm64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|x86.ActiveCfg = Checked|x86 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|x86.Build.0 = Checked|x86 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|amd64.ActiveCfg = Debug|amd64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|amd64.Build.0 = Debug|amd64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|arm.ActiveCfg = Debug|arm + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|arm.Build.0 = Debug|arm + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|arm64.ActiveCfg = Debug|arm64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|arm64.Build.0 = Debug|arm64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|x86.ActiveCfg = Debug|x86 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|x86.Build.0 = Debug|x86 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Release|amd64.ActiveCfg = Release|amd64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Release|amd64.Build.0 = Release|amd64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Release|arm.ActiveCfg = Release|arm + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Release|arm.Build.0 = Release|arm + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Release|arm64.ActiveCfg = Release|arm64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Release|arm64.Build.0 = Release|arm64 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Release|x86.ActiveCfg = Release|x86 + {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/mscorlib/Tools/BclRewriter/BclRewriter.targets b/src/mscorlib/Tools/BclRewriter/BclRewriter.targets new file mode 100644 index 0000000000..5515b000a7 --- /dev/null +++ b/src/mscorlib/Tools/BclRewriter/BclRewriter.targets @@ -0,0 +1,35 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> + + <!-- ********************************************************************************************* --> + <!-- *** Task --> + <!-- ********************************************************************************************* --> + + <PropertyGroup> + <BclRewriterModelFile Condition="'$(BclRewriterModelFile)'==''">$(MscorlibDir)model.xml</BclRewriterModelFile> + <BclRewriterWorkDir>$(IntermediateOutputPath)\BclRewriter</BclRewriterWorkDir> + <BclRewriterSymbolOutput>$(IntermediateOutputPath)\BclRewriter\$(TargetName).pdb</BclRewriterSymbolOutput> + <BclRewriterOutput>$(IntermediateOutputPath)\BclRewriter\$(TargetName)$(TargetExt)</BclRewriterOutput> + <TargetPath>$(BclRewriterOutput)</TargetPath> + </PropertyGroup> + + <ItemGroup> + <RewrittenAssembly Include="$(BclRewriterOutput)" /> + </ItemGroup> + + <Target Name="RewriteWithBclRewriter" + Inputs="$(BclRewriterModelFile);@(AnnotatedAssembly)" Outputs="@(RewrittenAssembly)" DependsOnTargets="$(BclRewriterDependencyTargets)"> + + <PropertyGroup> + <OSPlatform Condition="'$(TargetsWindows)' == 'true'">win</OSPlatform> + <OSPlatform Condition="'$(TargetsWindows)' != 'true'">unix</OSPlatform> + <BclRewriterCommand Condition="'$(BclRewriterCommand)'==''">"$(ToolRuntimePath)dotnetcli/$(ToolHost)" "$(ToolsDir)BclRewriter.exe"</BclRewriterCommand> + </PropertyGroup> + + <Exec Command="$(BclRewriterCommand) -in:"@(AnnotatedAssembly)" -out:"$(BclRewriterOutput)" -include:"$(BclRewriterModelFile)" -platform:$(OSPlatform) -architecture:$(Platform) -flavor:$(_BuildType) -removeSerializable- -define:"$(DefineConstants)" -keepTempFiles+" StandardOutputImportance="Normal" /> + + <!-- Update the location of the symbol file--> + <PropertyGroup> + <CurrentAssemblyPdb>$(BclRewriterSymbolOutput)</CurrentAssemblyPdb> + </PropertyGroup> + </Target> +</Project>
\ No newline at end of file diff --git a/src/mscorlib/Tools/PostProcessingTools.targets b/src/mscorlib/Tools/PostProcessingTools.targets new file mode 100644 index 0000000000..2f48efcecb --- /dev/null +++ b/src/mscorlib/Tools/PostProcessingTools.targets @@ -0,0 +1,28 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> + <Import Project="$(MSBuildThisFileDirectory)\BclRewriter\BclRewriter.targets" /> + + <ItemGroup> + <AnnotatedAssembly Include="$(IntermediateOutputPath)$(TargetName)$(TargetExt)"/> + + <Clean Include="@(RewrittenAssembly->'$(FinalOutputPath)\%(Filename)%(Extension)')" /> + <Clean Include="$(FinalOutputPath)\$(TargetName).pdb" /> + </ItemGroup> + + <Import Project="$(ToolsDir)toolruntime.targets" /> + + <PropertyGroup> + <CurrentAssemblyPdb>$(IntermediateOutputPath)$(TargetName).pdb</CurrentAssemblyPdb> + <PostProcessingTargets>RewriteWithBclRewriter</PostProcessingTargets> + <BclRewriterDependencyTargets>EnsureBuildToolsRuntime</BclRewriterDependencyTargets> + </PropertyGroup> + + <Target Name="AfterBuild" DependsOnTargets="$(PostProcessingTargets)" + Inputs="@(RewrittenAssembly)" Outputs="$(FinalOutputPath)\%(RewrittenAssembly.FileName)%(RewrittenAssembly.Extension)"> + + <!-- Copy to the final output location --> + <Copy Retries="3" SourceFiles="@(RewrittenAssembly)" DestinationFiles="$(FinalOutputPath)\%(RewrittenAssembly.FileName)%(RewrittenAssembly.Extension)"/> + <Message Importance="High" Text="$(MSBuildProjectName) -> $(FinalOutputPath)%(RewrittenAssembly.FileName)%(RewrittenAssembly.Extension)" /> + <Copy Condition="Exists('$(CurrentAssemblyPdb)')" Retries="3" SourceFiles="$(CurrentAssemblyPdb)" DestinationFiles="$(FinalOutputPath)\$(TargetName).pdb"/> + </Target> + +</Project>
\ No newline at end of file diff --git a/src/mscorlib/Tools/Signing/mscorlib.snk b/src/mscorlib/Tools/Signing/mscorlib.snk Binary files differnew file mode 100644 index 0000000000..60146e8891 --- /dev/null +++ b/src/mscorlib/Tools/Signing/mscorlib.snk diff --git a/src/mscorlib/Tools/Versioning/GenerateVersionInfo.targets b/src/mscorlib/Tools/Versioning/GenerateVersionInfo.targets new file mode 100644 index 0000000000..00f5282c7c --- /dev/null +++ b/src/mscorlib/Tools/Versioning/GenerateVersionInfo.targets @@ -0,0 +1,114 @@ +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <!-- Setup the default file version information --> + <PropertyGroup> + <MajorVersion Condition="'$(MajorVersion)' == ''">1</MajorVersion> + <MinorVersion Condition="'$(MinorVersion)' == ''">0</MinorVersion> + <BuildNumberMajor Condition="'$(BuildNumberMajor)' == ''">0</BuildNumberMajor> + <BuildNumberMinor Condition="'$(BuildNumberMinor)' == ''">0</BuildNumberMinor> + </PropertyGroup> + + <!-- #################################### --> + <!-- Generate Assembly Info --> + <!-- #################################### --> + <PropertyGroup> + <AssemblyVersion Condition="'$(AssemblyVersion)'==''">999.999.999.0</AssemblyVersion> + <CLSCompliant Condition="'$(CLSCompliant)'==''">false</CLSCompliant> + <AssemblyFileVersion Condition="'$(AssemblyFileVersionOverride)'==''">$(MajorVersion).$(MinorVersion).$(BuildNumberMajor).$(BuildNumberMinor)</AssemblyFileVersion> + </PropertyGroup> + + <PropertyGroup> + <GenerateAssemblyInfo Condition="'$(GenerateAssemblyInfo)'==''">true</GenerateAssemblyInfo> + </PropertyGroup> + + <PropertyGroup Condition="'$(GenerateAssemblyInfo)'=='true'"> + <AssemblyInfoFile>$(IntermediateOutputPath)GeneratedAssemblyInfo.cs</AssemblyInfoFile> + <CoreCompileDependsOn>$(CoreCompileDependsOn);GenerateAssemblyInfo</CoreCompileDependsOn> + </PropertyGroup> + + <Target Name="GenerateAssemblyInfo" + Inputs="$(MSBuildProjectFile)" + Outputs="$(AssemblyInfoFile)" + Condition="'$(GenerateAssemblyInfo)'=='true'"> + + <Error Condition="!Exists('$(IntermediateOutputPath)')" Text="GenerateAssemblyInfo failed because IntermediateOutputPath isn't set to a valid directory" /> + + <ItemGroup> + <AssemblyInfoUsings Include="using System%3B" /> + <AssemblyInfoUsings Include="using System.Reflection%3B" /> + <AssemblyInfoLines Include="[assembly:AssemblyTitle("$(AssemblyName)")]" /> + <AssemblyInfoLines Include="[assembly:AssemblyDescription("$(AssemblyName)")]" /> + <AssemblyInfoLines Include="[assembly:AssemblyDefaultAlias("$(AssemblyName)")]" /> + <AssemblyInfoLines Include="[assembly:AssemblyCompany("Microsoft Corporation")]" /> + <AssemblyInfoLines Include="[assembly:AssemblyProduct("Microsoft\x00ae .NET Framework")]" /> + <AssemblyInfoLines Include="[assembly:AssemblyCopyright("\x00a9 Microsoft Corporation. All rights reserved.")]" /> + <AssemblyInfoLines Include="[assembly:AssemblyVersion("$(AssemblyVersion)")]" /> + <AssemblyInfoLines Include="[assembly:AssemblyFileVersion("$(AssemblyFileVersion)")]" /> + <AssemblyInfoLines Include="[assembly:AssemblyInformationalVersion(@"$(AssemblyFileVersion)$(BuiltByString)")]" /> + <AssemblyInfoLines Condition="'$(CLSCompliant)'=='true'" Include="[assembly:CLSCompliant(true)]" /> + </ItemGroup> + + <WriteLinesToFile File="$(AssemblyInfoFile)" + Lines="@(AssemblyInfoUsings);@(AssemblyInfoLines)" + Overwrite="true" /> + + <ItemGroup> + <Compile Include="$(AssemblyInfoFile)" /> + <FileWrites Include="$(AssemblyInfoFile)" /> + </ItemGroup> + </Target> + + <!-- #################################### --> + <!-- Generate Native Version Info --> + <!-- #################################### --> + <PropertyGroup Condition="'$(GenerateNativeVersionInfo)'=='true'"> + <NativeVersionHeaderFile>$(IntermediateOutputPath)GeneratedVersion.h</NativeVersionHeaderFile> + <BeforeResourceCompileTargets>$(BeforeResourceCompileTargets);GenerateVersionHeader</BeforeResourceCompileTargets> + <Win32Resource>$(IntermediateOutputPath)\NativeVersion.res</Win32Resource> + <CoreCompileDependsOn>$(CoreCompileDependsOn);NativeResourceCompile</CoreCompileDependsOn> + </PropertyGroup> + + <Target Name="GenerateVersionHeader" + Condition="'$(GenerateNativeVersionInfo)'=='true'" + Inputs="$(MSBuildProjectFile)" + Outputs="$(NativeVersionHeaderFile)"> + + <ItemGroup> + <NativeVersionLines Include="#define VER_COMPANYNAME_STR "Microsoft Corporation"" /> + <NativeVersionLines Include="#define VER_FILEDESCRIPTION_STR "$(AssemblyName)"" /> + <NativeVersionLines Include="#define VER_INTERNALNAME_STR VER_FILEDESCRIPTION_STR" /> + <NativeVersionLines Include="#define VER_ORIGINALFILENAME_STR VER_FILEDESCRIPTION_STR" /> + <NativeVersionLines Include="#define VER_PRODUCTNAME_STR "Microsoft\xae .NET Framework"" /> + <NativeVersionLines Include="#define VER_PRODUCTVERSION $(MajorVersion),$(MinorVersion),$(BuildNumberMajor),$(BuildNumberMinor)" /> + <NativeVersionLines Include="#define VER_PRODUCTVERSION_STR "$(MajorVersion).$(MinorVersion).$(BuildNumberMajor).$(BuildNumberMinor)"" /> + <NativeVersionLines Include="#define VER_FILEVERSION $(MajorVersion),$(MinorVersion),$(BuildNumberMajor),$(BuildNumberMinor)" /> + <NativeVersionLines Include="#define VER_FILEVERSION_STR "$(MajorVersion).$(MinorVersion).$(BuildNumberMajor).$(BuildNumberMinor)"" /> + <NativeVersionLines Include="#define VER_LEGALCOPYRIGHT_STR "\xa9 Microsoft Corporation. All rights reserved."" /> + <NativeVersionLines Condition="'$(Configuration)'=='Debug'" Include="#define VER_DEBUG VS_FF_DEBUG" /> + <NativeVersionLines Condition="'$(Configuration)'!='Debug'" Include="#define VER_DEBUG 0" /> + </ItemGroup> + + <WriteLinesToFile File="$(NativeVersionHeaderFile)" + Lines="@(NativeVersionLines)" + Overwrite="true" /> + + <ItemGroup> + <FileWrites Include="$(NativeVersionHeaderFile)" /> + </ItemGroup> + </Target> + + + <PropertyGroup Condition="'$(GenerateNativeVersionInfo)'=='true'"> + <WindowsSdkDir Condition="'$(WindowsSdkDir)'==''">$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v8.1@InstallationFolder)</WindowsSdkDir> + <RCPath Condition="'$(RCPath)' == ''">$(WindowsSdkDir)bin\x86\rc.exe</RCPath> + </PropertyGroup> + + <Target Name="NativeResourceCompile" + Condition="'$(GenerateNativeVersionInfo)'=='true'" + DependsOnTargets="GenerateVersionHeader" + Inputs="$(MsBuildThisFileDirectory)NativeVersion.rc" + Outputs="$(Win32Resource)"> + + <Exec Command=""$(RCPath)" /nologo /x /i "$(IntermediateOutputPath.TrimEnd('\'))" /i "$(WindowsSdkDir)Include\$(WindowsSDKVersion)um" /i "$(WindowsSdkDir)Include\$(WindowsSDKVersion)\shared" /D _UNICODE /D UNICODE /l"0x0409" /r /fo "$(Win32Resource)" "$(MsBuildThisFileDirectory)NativeVersion.rc"" /> + + </Target> +</Project> diff --git a/src/mscorlib/Tools/Versioning/NativeVersion.rc b/src/mscorlib/Tools/Versioning/NativeVersion.rc new file mode 100644 index 0000000000..6a26d16c27 --- /dev/null +++ b/src/mscorlib/Tools/Versioning/NativeVersion.rc @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "GeneratedVersion.h" + +#include <windows.h> + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEFLAGS VER_DEBUG +FILEOS VOS__WINDOWS32 +FILETYPE VFT_DLL +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", VER_COMPANYNAME_STR + VALUE "FileDescription", VER_FILEDESCRIPTION_STR + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", VER_INTERNALNAME_STR + VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR + VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR + VALUE "ProductName", VER_PRODUCTNAME_STR + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + /* The following line should only be modified for localized versions. */ + /* It consists of any number of WORD,WORD pairs, with each pair */ + /* describing a language,codepage combination supported by the file. */ + /* */ + /* For example, a file might have values "0x409,1252" indicating that it */ + /* supports English language (0x409) in the Windows ANSI codepage (1252). */ + + VALUE "Translation", 0x409, 1252 + + END +END diff --git a/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs b/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs new file mode 100644 index 0000000000..f8c5b26e44 --- /dev/null +++ b/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + private static partial class Libraries + { + internal const string GlobalizationInterop = "System.Globalization.Native"; // CoreFX wrappers for ICU + } +} diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs new file mode 100644 index 0000000000..7b3caeabdd --- /dev/null +++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; + +internal static partial class Interop +{ + internal static partial class GlobalizationInterop + { + internal delegate void EnumCalendarInfoCallback( + [MarshalAs(UnmanagedType.LPWStr)] string calendarString, + IntPtr context); + + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetCalendars")] + internal static extern int GetCalendars(string localeName, CalendarId[] calendars, int calendarsCapacity); + + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetCalendarInfo")] + internal static extern ResultCode GetCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType calendarDataType, [Out] StringBuilder result, int resultCapacity); + + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EnumCalendarInfo")] + internal static extern bool EnumCalendarInfo(EnumCalendarInfoCallback callback, string localeName, CalendarId calendarId, CalendarDataType calendarDataType, IntPtr context); + + [DllImport(Libraries.GlobalizationInterop, EntryPoint = "GlobalizationNative_GetLatestJapaneseEra")] + internal static extern int GetLatestJapaneseEra(); + + [DllImport(Libraries.GlobalizationInterop, EntryPoint = "GlobalizationNative_GetJapaneseEraStartDate")] + internal static extern bool GetJapaneseEraStartDate(int era, out int startYear, out int startMonth, out int startDay); + } +} diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Casing.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Casing.cs new file mode 100644 index 0000000000..115a8393be --- /dev/null +++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Casing.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +internal static partial class Interop +{ + internal static partial class GlobalizationInterop + { + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ChangeCase")] + internal unsafe static extern void ChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ChangeCaseInvariant")] + internal unsafe static extern void ChangeCaseInvariant(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ChangeCaseTurkish")] + internal unsafe static extern void ChangeCaseTurkish(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper); + } +} diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs new file mode 100644 index 0000000000..6acf55e17b --- /dev/null +++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Security; + +internal static partial class Interop +{ + internal static partial class GlobalizationInterop + { + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetSortHandle")] + internal unsafe static extern SafeSortHandle GetSortHandle(byte[] localeName); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CloseSortHandle")] + internal unsafe static extern void CloseSortHandle(IntPtr handle); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CompareString")] + internal unsafe static extern int CompareString(SafeSortHandle sortHandle, char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len, CompareOptions options); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOf")] + internal unsafe static extern int IndexOf(SafeSortHandle sortHandle, string target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_LastIndexOf")] + internal unsafe static extern int LastIndexOf(SafeSortHandle sortHandle, string target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOfOrdinalIgnoreCase")] + internal unsafe static extern int IndexOfOrdinalIgnoreCase(string target, int cwTargetLength, char* pSource, int cwSourceLength, bool findLast); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_StartsWith")] + [return: MarshalAs(UnmanagedType.Bool)] + internal unsafe static extern bool StartsWith(SafeSortHandle sortHandle, string target, int cwTargetLength, string source, int cwSourceLength, CompareOptions options); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EndsWith")] + [return: MarshalAs(UnmanagedType.Bool)] + internal unsafe static extern bool EndsWith(SafeSortHandle sortHandle, string target, int cwTargetLength, string source, int cwSourceLength, CompareOptions options); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetSortKey")] + internal unsafe static extern int GetSortKey(SafeSortHandle sortHandle, string str, int strLength, byte* sortKey, int sortKeyLength, CompareOptions options); + + [SecurityCritical] + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CompareStringOrdinalIgnoreCase")] + internal unsafe static extern int CompareStringOrdinalIgnoreCase(char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len); + + [SecurityCritical] + internal class SafeSortHandle : SafeHandle + { + private SafeSortHandle() : + base(IntPtr.Zero, true) + { + } + + public override bool IsInvalid + { + [SecurityCritical] + get { return handle == IntPtr.Zero; } + } + + [SecurityCritical] + protected override bool ReleaseHandle() + { + CloseSortHandle(handle); + SetHandle(IntPtr.Zero); + return true; + } + } + } +} diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs new file mode 100644 index 0000000000..3912581c73 --- /dev/null +++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Runtime.InteropServices; +using System.Text; + +internal static partial class Interop +{ + internal static partial class GlobalizationInterop + { + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleName")] + [return: MarshalAs(UnmanagedType.Bool)] + internal unsafe static extern bool GetLocaleName(string localeName, [Out] StringBuilder value, int valueLength); + + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleInfoString")] + [return: MarshalAs(UnmanagedType.Bool)] + internal unsafe static extern bool GetLocaleInfoString(string localeName, uint localeStringData, [Out] StringBuilder value, int valueLength); + + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetDefaultLocaleName")] + [return: MarshalAs(UnmanagedType.Bool)] + internal unsafe static extern bool GetDefaultLocaleName([Out] StringBuilder value, int valueLength); + + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleTimeFormat")] + [return: MarshalAs(UnmanagedType.Bool)] + internal unsafe static extern bool GetLocaleTimeFormat(string localeName, bool shortFormat, [Out] StringBuilder value, int valueLength); + + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleInfoInt")] + [return: MarshalAs(UnmanagedType.Bool)] + internal unsafe static extern bool GetLocaleInfoInt(string localeName, uint localeNumberData, ref int value); + + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleInfoGroupingSizes")] + [return: MarshalAs(UnmanagedType.Bool)] + internal unsafe static extern bool GetLocaleInfoGroupingSizes(string localeName, uint localeGroupingData, ref int primaryGroupSize, ref int secondaryGroupSize); + } +} diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs new file mode 100644 index 0000000000..4621580063 --- /dev/null +++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class GlobalizationInterop + { + // needs to be kept in sync with ResultCode in System.Globalization.Native + internal enum ResultCode + { + Success = 0, + UnknownError = 1, + InsufficentBuffer = 2, + } + } +} diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs new file mode 100644 index 0000000000..26a9fe0579 --- /dev/null +++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Runtime.InteropServices; +using System.Text; + +internal static partial class Interop +{ + internal static partial class GlobalizationInterop + { + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Ansi, EntryPoint = "GlobalizationNative_ReadLink")] // readlink requires char* + internal static extern bool ReadLink(string filePath, [Out] StringBuilder result, uint resultCapacity); + + // needs to be kept in sync with TimeZoneDisplayNameType in System.Globalization.Native + internal enum TimeZoneDisplayNameType + { + Generic = 0, + Standard = 1, + DaylightSavings = 2, + } + + [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetTimeZoneDisplayName")] + internal static extern ResultCode GetTimeZoneDisplayName( + string localeName, + string timeZoneId, + TimeZoneDisplayNameType type, + [Out] StringBuilder result, + int resultLength); + } +} diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Utils.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Utils.cs new file mode 100644 index 0000000000..33b10c0d74 --- /dev/null +++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Utils.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Text; + +internal static partial class Interop +{ + /// <summary> + /// Helper for making interop calls that return a string, but we don't know + /// the correct size of buffer to make. So invoke the interop call with an + /// increasing buffer until the size is big enough. + /// </summary> + internal static bool CallStringMethod<TArg1, TArg2, TArg3>( + Func<TArg1, TArg2, TArg3, StringBuilder, GlobalizationInterop.ResultCode> interopCall, + TArg1 arg1, + TArg2 arg2, + TArg3 arg3, + out string result) + { + const int initialStringSize = 80; + const int maxDoubleAttempts = 5; + + StringBuilder stringBuilder = StringBuilderCache.Acquire(initialStringSize); + + for (int i = 0; i < maxDoubleAttempts; i++) + { + GlobalizationInterop.ResultCode resultCode = interopCall(arg1, arg2, arg3, stringBuilder); + + if (resultCode == GlobalizationInterop.ResultCode.Success) + { + result = StringBuilderCache.GetStringAndRelease(stringBuilder); + return true; + } + else if (resultCode == GlobalizationInterop.ResultCode.InsufficentBuffer) + { + // increase the string size and loop + stringBuilder.EnsureCapacity(stringBuilder.Capacity * 2); + } + else + { + // if there is an unknown error, don't proceed + break; + } + } + + StringBuilderCache.Release(stringBuilder); + result = null; + return false; + } +} diff --git a/src/mscorlib/corefx/SR.cs b/src/mscorlib/corefx/SR.cs new file mode 100644 index 0000000000..513bd9d94d --- /dev/null +++ b/src/mscorlib/corefx/SR.cs @@ -0,0 +1,247 @@ +using System; + +namespace System.Globalization +{ + internal static class SR + { + public static string Arg_HexStyleNotSupported + { + get { return Environment.GetResourceString("Arg_HexStyleNotSupported"); } + } + + public static string Arg_InvalidHexStyle + { + get { return Environment.GetResourceString("Arg_InvalidHexStyle"); } + } + + public static string ArgumentNull_Array + { + get { return Environment.GetResourceString("ArgumentNull_Array"); } + } + + public static string ArgumentNull_ArrayValue + { + get { return Environment.GetResourceString("ArgumentNull_ArrayValue"); } + } + + public static string ArgumentNull_Obj + { + get { return Environment.GetResourceString("ArgumentNull_Obj"); } + } + + public static string ArgumentNull_String + { + get { return Environment.GetResourceString("ArgumentNull_String"); } + } + + public static string ArgumentOutOfRange_AddValue + { + get { return Environment.GetResourceString("ArgumentOutOfRange_AddValue"); } + } + + public static string ArgumentOutOfRange_BadHourMinuteSecond + { + get { return Environment.GetResourceString("ArgumentOutOfRange_BadHourMinuteSecond"); } + } + + public static string ArgumentOutOfRange_BadYearMonthDay + { + get { return Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"); } + } + + public static string ArgumentOutOfRange_Bounds_Lower_Upper + { + get { return Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"); } + } + + public static string ArgumentOutOfRange_CalendarRange + { + get { return Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"); } + } + + public static string ArgumentOutOfRange_Count + { + get { return Environment.GetResourceString("ArgumentOutOfRange_Count"); } + } + + public static string ArgumentOutOfRange_Day + { + get { return Environment.GetResourceString("ArgumentOutOfRange_Day"); } + } + + public static string ArgumentOutOfRange_Enum + { + get { return Environment.GetResourceString("ArgumentOutOfRange_Enum"); } + } + + public static string ArgumentOutOfRange_Era + { + get { return Environment.GetResourceString("ArgumentOutOfRange_Era"); } + } + + public static string ArgumentOutOfRange_Index + { + get { return Environment.GetResourceString("ArgumentOutOfRange_Index"); } + } + + public static string ArgumentOutOfRange_InvalidEraValue + { + get { return Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"); } + } + + public static string ArgumentOutOfRange_Month + { + get { return Environment.GetResourceString("ArgumentOutOfRange_Month"); } + } + + public static string ArgumentOutOfRange_NeedNonNegNum + { + get { return Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"); } + } + + public static string ArgumentOutOfRange_NeedPosNum + { + get { return Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"); } + } + + public static string ArgumentOutOfRange_OffsetLength + { + get { return Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"); } + } + + public static string ArgumentOutOfRange_Range + { + get { return Environment.GetResourceString("ArgumentOutOfRange_Range"); } + } + + public static string Argument_CompareOptionOrdinal + { + get { return Environment.GetResourceString("Argument_CompareOptionOrdinal"); } + } + + public static string Argument_ConflictingDateTimeRoundtripStyles + { + get { return Environment.GetResourceString("Argument_ConflictingDateTimeRoundtripStyles"); } + } + + public static string Argument_ConflictingDateTimeStyles + { + get { return Environment.GetResourceString("Argument_ConflictingDateTimeStyles"); } + } + + public static string Argument_CultureInvalidIdentifier + { + get { return Environment.GetResourceString("Argument_CultureInvalidIdentifier"); } + } + + public static string Argument_CultureNotSupported + { + get { return Environment.GetResourceString("Argument_CultureNotSupported"); } + } + + public static string Argument_EmptyDecString + { + get { return Environment.GetResourceString("Argument_EmptyDecString"); } + } + + public static string Argument_InvalidArrayLength + { + get { return Environment.GetResourceString("Argument_InvalidArrayLength"); } + } + + public static string Argument_InvalidCalendar + { + get { return Environment.GetResourceString("Argument_InvalidCalendar"); } + } + + public static string Argument_InvalidCultureName + { + get { return Environment.GetResourceString("Argument_InvalidCultureName"); } + } + + public static string Argument_InvalidDateTimeStyles + { + get { return Environment.GetResourceString("Argument_InvalidDateTimeStyles"); } + } + + public static string Argument_InvalidFlag + { + get { return Environment.GetResourceString("Argument_InvalidFlag"); } + } + + public static string Argument_InvalidGroupSize + { + get { return Environment.GetResourceString("Argument_InvalidGroupSize"); } + } + + public static string Argument_InvalidNeutralRegionName + { + get { return Environment.GetResourceString("Argument_InvalidNeutralRegionName"); } + } + + public static string Argument_InvalidNumberStyles + { + get { return Environment.GetResourceString("Argument_InvalidNumberStyles"); } + } + + public static string Argument_InvalidResourceCultureName + { + get { return Environment.GetResourceString("Argument_InvalidResourceCultureName"); } + } + + public static string Argument_NoEra + { + get { return Environment.GetResourceString("Argument_NoEra"); } + } + + public static string Argument_NoRegionInvariantCulture + { + get { return Environment.GetResourceString("Argument_NoRegionInvariantCulture"); } + } + + public static string Argument_ResultCalendarRange + { + get { return Environment.GetResourceString("Argument_ResultCalendarRange"); } + } + + public static string Format_BadFormatSpecifier + { + get { return Environment.GetResourceString("Format_BadFormatSpecifier"); } + } + + public static string InvalidOperation_DateTimeParsing + { + get { return Environment.GetResourceString("InvalidOperation_DateTimeParsing"); } + } + + public static string InvalidOperation_EnumEnded + { + get { return Environment.GetResourceString("InvalidOperation_EnumEnded"); } + } + + public static string InvalidOperation_EnumNotStarted + { + get { return Environment.GetResourceString("InvalidOperation_EnumNotStarted"); } + } + + public static string InvalidOperation_ReadOnly + { + get { return Environment.GetResourceString("InvalidOperation_ReadOnly"); } + } + + public static string Overflow_TimeSpanTooLong + { + 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); + } + } +} diff --git a/src/mscorlib/corefx/System/Globalization/Calendar.cs b/src/mscorlib/corefx/System/Globalization/Calendar.cs new file mode 100644 index 0000000000..343682d156 --- /dev/null +++ b/src/mscorlib/corefx/System/Globalization/Calendar.cs @@ -0,0 +1,854 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Runtime.CompilerServices; +using System.Globalization; +using System.Diagnostics.Contracts; +using System.Runtime.Serialization; + +namespace System.Globalization +{ + // This abstract class represents a calendar. A calendar reckons time in + // divisions such as weeks, months and years. The number, length and start of + // the divisions vary in each calendar. + // + // Any instant in time can be represented as an n-tuple of numeric values using + // a particular calendar. For example, the next vernal equinox occurs at (0.0, 0 + // , 46, 8, 20, 3, 1999) in the Gregorian calendar. An implementation of + // Calendar can map any DateTime value to such an n-tuple and vice versa. The + // DateTimeFormat class can map between such n-tuples and a textual + // representation such as "8:46 AM March 20th 1999 AD". + // + // Most calendars identify a year which begins the current era. There may be any + // number of previous eras. The Calendar class identifies the eras as enumerated + // integers where the current era (CurrentEra) has the value zero. + // + // For consistency, the first unit in each interval, e.g. the first month, is + // assigned the value one. + // 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 partial class Calendar : ICloneable + { + // Number of 100ns (10E-7 second) ticks per time unit + internal const long TicksPerMillisecond = 10000; + internal const long TicksPerSecond = TicksPerMillisecond * 1000; + internal const long TicksPerMinute = TicksPerSecond * 60; + internal const long TicksPerHour = TicksPerMinute * 60; + internal const long TicksPerDay = TicksPerHour * 24; + + // Number of milliseconds per time unit + internal const int MillisPerSecond = 1000; + internal const int MillisPerMinute = MillisPerSecond * 60; + internal const int MillisPerHour = MillisPerMinute * 60; + internal const int MillisPerDay = MillisPerHour * 24; + + // Number of days in a non-leap year + internal const int DaysPerYear = 365; + // Number of days in 4 years + internal const int DaysPer4Years = DaysPerYear * 4 + 1; + // Number of days in 100 years + internal const int DaysPer100Years = DaysPer4Years * 25 - 1; + // Number of days in 400 years + internal const int DaysPer400Years = DaysPer100Years * 4 + 1; + + // Number of days from 1/1/0001 to 1/1/10000 + internal const int DaysTo10000 = DaysPer400Years * 25 - 366; + + internal const long MaxMillis = (long)DaysTo10000 * MillisPerDay; + + + private int _currentEraValue = -1; + + [OptionalField(VersionAdded = 2)] + private bool _isReadOnly = false; + +#if INSIDE_CLR + internal const CalendarId CAL_HEBREW = CalendarId.HEBREW; + internal const CalendarId CAL_HIJRI = CalendarId.HIJRI; + internal const CalendarId CAL_JAPAN = CalendarId.JAPAN; + internal const CalendarId CAL_JULIAN = CalendarId.JULIAN; + internal const CalendarId CAL_TAIWAN = CalendarId.TAIWAN; + internal const CalendarId CAL_UMALQURA = CalendarId.UMALQURA; + internal const CalendarId CAL_PERSIAN = CalendarId.PERSIAN; +#endif + + // The minimum supported DateTime range for the calendar. + + [System.Runtime.InteropServices.ComVisible(false)] + public virtual DateTime MinSupportedDateTime + { + get + { + return (DateTime.MinValue); + } + } + + // The maximum supported DateTime range for the calendar. + + [System.Runtime.InteropServices.ComVisible(false)] + public virtual DateTime MaxSupportedDateTime + { + get + { + return (DateTime.MaxValue); + } + } + + + + + protected Calendar() + { + //Do-nothing constructor. + } + + /// + // This can not be abstract, otherwise no one can create a subclass of Calendar. + // + internal virtual CalendarId ID + { + get + { + return CalendarId.UNINITIALIZED_VALUE; + } + } + + /// + // Return the Base calendar ID for calendars that didn't have defined data in calendarData + // + + internal virtual CalendarId BaseCalendarID + { + get { return ID; } + } + + //////////////////////////////////////////////////////////////////////// + // + // IsReadOnly + // + // Detect if the object is readonly. + // + //////////////////////////////////////////////////////////////////////// + [System.Runtime.InteropServices.ComVisible(false)] + public bool IsReadOnly + { + get { return (_isReadOnly); } + } + + //////////////////////////////////////////////////////////////////////// + // + // Clone + // + // Is the implementation of ICloneable. + // + //////////////////////////////////////////////////////////////////////// + [System.Runtime.InteropServices.ComVisible(false)] + public virtual object Clone() + { + object o = MemberwiseClone(); + ((Calendar)o).SetReadOnlyState(false); + return (o); + } + + //////////////////////////////////////////////////////////////////////// + // + // ReadOnly + // + // Create a cloned readonly instance or return the input one if it is + // readonly. + // + //////////////////////////////////////////////////////////////////////// + [System.Runtime.InteropServices.ComVisible(false)] + internal static Calendar ReadOnly(Calendar calendar) + { + if (calendar == null) { throw new ArgumentNullException("calendar"); } + Contract.EndContractBlock(); + if (calendar.IsReadOnly) { return (calendar); } + + Calendar clonedCalendar = (Calendar)(calendar.MemberwiseClone()); + clonedCalendar.SetReadOnlyState(true); + + return (clonedCalendar); + } + + internal void VerifyWritable() + { + if (_isReadOnly) + { + throw new InvalidOperationException(SR.InvalidOperation_ReadOnly); + } + } + + internal void SetReadOnlyState(bool readOnly) + { + _isReadOnly = readOnly; + } + + + /*=================================CurrentEraValue========================== + **Action: This is used to convert CurretEra(0) to an appropriate era value. + **Returns: + **Arguments: + **Exceptions: + **Notes: + ** The value is from calendar.nlp. + ============================================================================*/ + + internal virtual int CurrentEraValue + { + get + { + // The following code assumes that the current era value can not be -1. + if (_currentEraValue == -1) + { + Contract.Assert(BaseCalendarID != CalendarId.UNINITIALIZED_VALUE, "[Calendar.CurrentEraValue] Expected a real calendar ID"); + _currentEraValue = CalendarData.GetCalendarData(BaseCalendarID).iCurrentEra; + } + return (_currentEraValue); + } + } + + // The current era for a calendar. + + public const int CurrentEra = 0; + + internal int twoDigitYearMax = -1; + + internal static void CheckAddResult(long ticks, DateTime minValue, DateTime maxValue) + { + if (ticks < minValue.Ticks || ticks > maxValue.Ticks) + { + throw new ArgumentException( + String.Format(CultureInfo.InvariantCulture, SR.Format(SR.Argument_ResultCalendarRange, + minValue, maxValue))); + } + Contract.EndContractBlock(); + } + + internal DateTime Add(DateTime time, double value, int scale) + { + // From ECMA CLI spec, Partition III, section 3.27: + // + // If overflow occurs converting a floating-point type to an integer, or if the floating-point value + // being converted to an integer is a NaN, the value returned is unspecified. + // + // Based upon this, this method should be performing the comparison against the double + // before attempting a cast. Otherwise, the result is undefined. + double tempMillis = (value * scale + (value >= 0 ? 0.5 : -0.5)); + if (!((tempMillis > -(double)MaxMillis) && (tempMillis < (double)MaxMillis))) + { + throw new ArgumentOutOfRangeException("value", SR.ArgumentOutOfRange_AddValue); + } + + long millis = (long)tempMillis; + long ticks = time.Ticks + millis * TicksPerMillisecond; + CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime); + return (new DateTime(ticks)); + } + + // Returns the DateTime resulting from adding the given number of + // milliseconds to the specified DateTime. The result is computed by rounding + // the number of milliseconds given by value to the nearest integer, + // and adding that interval to the specified DateTime. The value + // argument is permitted to be negative. + // + + public virtual DateTime AddMilliseconds(DateTime time, double milliseconds) + { + return (Add(time, milliseconds, 1)); + } + + + // Returns the DateTime resulting from adding a fractional number of + // days to the specified DateTime. The result is computed by rounding the + // fractional number of days given by value to the nearest + // millisecond, and adding that interval to the specified DateTime. The + // value argument is permitted to be negative. + // + + public virtual DateTime AddDays(DateTime time, int days) + { + return (Add(time, days, MillisPerDay)); + } + + // Returns the DateTime resulting from adding a fractional number of + // hours to the specified DateTime. The result is computed by rounding the + // fractional number of hours given by value to the nearest + // millisecond, and adding that interval to the specified DateTime. The + // value argument is permitted to be negative. + // + + public virtual DateTime AddHours(DateTime time, int hours) + { + return (Add(time, hours, MillisPerHour)); + } + + + // Returns the DateTime resulting from adding a fractional number of + // minutes to the specified DateTime. The result is computed by rounding the + // fractional number of minutes given by value to the nearest + // millisecond, and adding that interval to the specified DateTime. The + // value argument is permitted to be negative. + // + + public virtual DateTime AddMinutes(DateTime time, int minutes) + { + return (Add(time, minutes, MillisPerMinute)); + } + + + // Returns the DateTime resulting from adding the given number of + // months to the specified DateTime. The result is computed by incrementing + // (or decrementing) the year and month parts of the specified DateTime by + // value months, and, if required, adjusting the day part of the + // resulting date downwards to the last day of the resulting month in the + // resulting year. The time-of-day part of the result is the same as the + // time-of-day part of the specified DateTime. + // + // In more precise terms, considering the specified DateTime to be of the + // form y / m / d + t, where y is the + // year, m is the month, d is the day, and t is the + // time-of-day, the result is y1 / m1 / d1 + t, + // where y1 and m1 are computed by adding value months + // to y and m, and d1 is the largest value less than + // or equal to d that denotes a valid day in month m1 of year + // y1. + // + + public abstract DateTime AddMonths(DateTime time, int months); + + // Returns the DateTime resulting from adding a number of + // seconds to the specified DateTime. The result is computed by rounding the + // fractional number of seconds given by value to the nearest + // millisecond, and adding that interval to the specified DateTime. The + // value argument is permitted to be negative. + // + + public virtual DateTime AddSeconds(DateTime time, int seconds) + { + return Add(time, seconds, MillisPerSecond); + } + + // Returns the DateTime resulting from adding a number of + // weeks to the specified DateTime. The + // value argument is permitted to be negative. + // + + public virtual DateTime AddWeeks(DateTime time, int weeks) + { + return (AddDays(time, weeks * 7)); + } + + + // Returns the DateTime resulting from adding the given number of + // years to the specified DateTime. The result is computed by incrementing + // (or decrementing) the year part of the specified DateTime by value + // years. If the month and day of the specified DateTime is 2/29, and if the + // resulting year is not a leap year, the month and day of the resulting + // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day + // parts of the result are the same as those of the specified DateTime. + // + + public abstract DateTime AddYears(DateTime time, int years); + + // Returns the day-of-month part of the specified DateTime. The returned + // value is an integer between 1 and 31. + // + + public abstract int GetDayOfMonth(DateTime time); + + // Returns the day-of-week part of the specified DateTime. The returned value + // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates + // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates + // Thursday, 5 indicates Friday, and 6 indicates Saturday. + // + + public abstract DayOfWeek GetDayOfWeek(DateTime time); + + // Returns the day-of-year part of the specified DateTime. The returned value + // is an integer between 1 and 366. + // + + public abstract int GetDayOfYear(DateTime time); + + // Returns the number of days in the month given by the year and + // month arguments. + // + + public virtual int GetDaysInMonth(int year, int month) + { + return (GetDaysInMonth(year, month, CurrentEra)); + } + + // Returns the number of days in the month given by the year and + // month arguments for the specified era. + // + + public abstract int GetDaysInMonth(int year, int month, int era); + + // Returns the number of days in the year given by the year argument for the current era. + // + + public virtual int GetDaysInYear(int year) + { + return (GetDaysInYear(year, CurrentEra)); + } + + // Returns the number of days in the year given by the year argument for the current era. + // + + public abstract int GetDaysInYear(int year, int era); + + // Returns the era for the specified DateTime value. + + public abstract int GetEra(DateTime time); + + /*=================================Eras========================== + **Action: Get the list of era values. + **Returns: The int array of the era names supported in this calendar. + ** null if era is not used. + **Arguments: None. + **Exceptions: None. + ============================================================================*/ + + + public abstract int[] Eras + { + get; + } + + + // Returns the hour part of the specified DateTime. The returned value is an + // integer between 0 and 23. + // + + public virtual int GetHour(DateTime time) + { + return ((int)((time.Ticks / TicksPerHour) % 24)); + } + + // Returns the millisecond part of the specified DateTime. The returned value + // is an integer between 0 and 999. + // + + public virtual double GetMilliseconds(DateTime time) + { + return (double)((time.Ticks / TicksPerMillisecond) % 1000); + } + + // Returns the minute part of the specified DateTime. The returned value is + // an integer between 0 and 59. + // + + public virtual int GetMinute(DateTime time) + { + return ((int)((time.Ticks / TicksPerMinute) % 60)); + } + + // Returns the month part of the specified DateTime. The returned value is an + // integer between 1 and 12. + // + + public abstract int GetMonth(DateTime time); + + // Returns the number of months in the specified year in the current era. + + public virtual int GetMonthsInYear(int year) + { + return (GetMonthsInYear(year, CurrentEra)); + } + + // Returns the number of months in the specified year and era. + + public abstract int GetMonthsInYear(int year, int era); + + // Returns the second part of the specified DateTime. The returned value is + // an integer between 0 and 59. + // + + public virtual int GetSecond(DateTime time) + { + return ((int)((time.Ticks / TicksPerSecond) % 60)); + } + + /*=================================GetFirstDayWeekOfYear========================== + **Action: Get the week of year using the FirstDay rule. + **Returns: the week of year. + **Arguments: + ** time + ** firstDayOfWeek the first day of week (0=Sunday, 1=Monday, ... 6=Saturday) + **Notes: + ** The CalendarWeekRule.FirstDay rule: Week 1 begins on the first day of the year. + ** Assume f is the specifed firstDayOfWeek, + ** and n is the day of week for January 1 of the specified year. + ** Assign offset = n - f; + ** Case 1: offset = 0 + ** E.g. + ** f=1 + ** weekday 0 1 2 3 4 5 6 0 1 + ** date 1/1 + ** week# 1 2 + ** then week of year = (GetDayOfYear(time) - 1) / 7 + 1 + ** + ** Case 2: offset < 0 + ** e.g. + ** n=1 f=3 + ** weekday 0 1 2 3 4 5 6 0 + ** date 1/1 + ** week# 1 2 + ** This means that the first week actually starts 5 days before 1/1. + ** So week of year = (GetDayOfYear(time) + (7 + offset) - 1) / 7 + 1 + ** Case 3: offset > 0 + ** e.g. + ** f=0 n=2 + ** weekday 0 1 2 3 4 5 6 0 1 2 + ** date 1/1 + ** week# 1 2 + ** This means that the first week actually starts 2 days before 1/1. + ** So Week of year = (GetDayOfYear(time) + offset - 1) / 7 + 1 + ============================================================================*/ + + internal int GetFirstDayWeekOfYear(DateTime time, int firstDayOfWeek) + { + int dayOfYear = GetDayOfYear(time) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0. + // Calculate the day of week for the first day of the year. + // dayOfWeek - (dayOfYear % 7) is the day of week for the first day of this year. Note that + // this value can be less than 0. It's fine since we are making it positive again in calculating offset. + int dayForJan1 = (int)GetDayOfWeek(time) - (dayOfYear % 7); + int offset = (dayForJan1 - firstDayOfWeek + 14) % 7; + Contract.Assert(offset >= 0, "Calendar.GetFirstDayWeekOfYear(): offset >= 0"); + return ((dayOfYear + offset) / 7 + 1); + } + + private int GetWeekOfYearFullDays(DateTime time, int firstDayOfWeek, int fullDays) + { + int dayForJan1; + int offset; + int day; + + int dayOfYear = GetDayOfYear(time) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0. + // + // Calculate the number of days between the first day of year (1/1) and the first day of the week. + // This value will be a positive value from 0 ~ 6. We call this value as "offset". + // + // If offset is 0, it means that the 1/1 is the start of the first week. + // Assume the first day of the week is Monday, it will look like this: + // Sun Mon Tue Wed Thu Fri Sat + // 12/31 1/1 1/2 1/3 1/4 1/5 1/6 + // +--> First week starts here. + // + // If offset is 1, it means that the first day of the week is 1 day ahead of 1/1. + // Assume the first day of the week is Monday, it will look like this: + // Sun Mon Tue Wed Thu Fri Sat + // 1/1 1/2 1/3 1/4 1/5 1/6 1/7 + // +--> First week starts here. + // + // If offset is 2, it means that the first day of the week is 2 days ahead of 1/1. + // Assume the first day of the week is Monday, it will look like this: + // Sat Sun Mon Tue Wed Thu Fri Sat + // 1/1 1/2 1/3 1/4 1/5 1/6 1/7 1/8 + // +--> First week starts here. + + + + // Day of week is 0-based. + // Get the day of week for 1/1. This can be derived from the day of week of the target day. + // Note that we can get a negative value. It's ok since we are going to make it a positive value when calculating the offset. + dayForJan1 = (int)GetDayOfWeek(time) - (dayOfYear % 7); + + // Now, calculate the offset. Subtract the first day of week from the dayForJan1. And make it a positive value. + offset = (firstDayOfWeek - dayForJan1 + 14) % 7; + if (offset != 0 && offset >= fullDays) + { + // + // If the offset is greater than the value of fullDays, it means that + // the first week of the year starts on the week where Jan/1 falls on. + // + offset -= 7; + } + // + // Calculate the day of year for specified time by taking offset into account. + // + day = dayOfYear - offset; + if (day >= 0) + { + // + // If the day of year value is greater than zero, get the week of year. + // + return (day / 7 + 1); + } + // + // Otherwise, the specified time falls on the week of previous year. + // Call this method again by passing the last day of previous year. + // + // the last day of the previous year may "underflow" to no longer be a valid date time for + // this calendar if we just subtract so we need the subclass to provide us with + // that information + if (time <= MinSupportedDateTime.AddDays(dayOfYear)) + { + return GetWeekOfYearOfMinSupportedDateTime(firstDayOfWeek, fullDays); + } + return (GetWeekOfYearFullDays(time.AddDays(-(dayOfYear + 1)), firstDayOfWeek, fullDays)); + } + + private int GetWeekOfYearOfMinSupportedDateTime(int firstDayOfWeek, int minimumDaysInFirstWeek) + { + int dayOfYear = GetDayOfYear(MinSupportedDateTime) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0. + int dayOfWeekOfFirstOfYear = (int)GetDayOfWeek(MinSupportedDateTime) - dayOfYear % 7; + + // Calculate the offset (how many days from the start of the year to the start of the week) + int offset = (firstDayOfWeek + 7 - dayOfWeekOfFirstOfYear) % 7; + if (offset == 0 || offset >= minimumDaysInFirstWeek) + { + // First of year falls in the first week of the year + return 1; + } + + int daysInYearBeforeMinSupportedYear = DaysInYearBeforeMinSupportedYear - 1; // Make the day of year to be 0-based, so that 1/1 is day 0. + int dayOfWeekOfFirstOfPreviousYear = dayOfWeekOfFirstOfYear - 1 - (daysInYearBeforeMinSupportedYear % 7); + + // starting from first day of the year, how many days do you have to go forward + // before getting to the first day of the week? + int daysInInitialPartialWeek = (firstDayOfWeek - dayOfWeekOfFirstOfPreviousYear + 14) % 7; + int day = daysInYearBeforeMinSupportedYear - daysInInitialPartialWeek; + if (daysInInitialPartialWeek >= minimumDaysInFirstWeek) + { + // If the offset is greater than the minimum Days in the first week, it means that + // First of year is part of the first week of the year even though it is only a partial week + // add another week + day += 7; + } + + return (day / 7 + 1); + } + + // it would be nice to make this abstract but we can't since that would break previous implementations + protected virtual int DaysInYearBeforeMinSupportedYear + { + get + { + return 365; + } + } + + + // Returns the week of year for the specified DateTime. The returned value is an + // integer between 1 and 53. + // + + public virtual int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek) + { + if ((int)firstDayOfWeek < 0 || (int)firstDayOfWeek > 6) + { + throw new ArgumentOutOfRangeException( + "firstDayOfWeek", SR.Format(SR.ArgumentOutOfRange_Range, + DayOfWeek.Sunday, DayOfWeek.Saturday)); + } + Contract.EndContractBlock(); + switch (rule) + { + case CalendarWeekRule.FirstDay: + return (GetFirstDayWeekOfYear(time, (int)firstDayOfWeek)); + case CalendarWeekRule.FirstFullWeek: + return (GetWeekOfYearFullDays(time, (int)firstDayOfWeek, 7)); + case CalendarWeekRule.FirstFourDayWeek: + return (GetWeekOfYearFullDays(time, (int)firstDayOfWeek, 4)); + } + throw new ArgumentOutOfRangeException( + "rule", SR.Format(SR.ArgumentOutOfRange_Range, + CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek)); + } + + // Returns the year part of the specified DateTime. The returned value is an + // integer between 1 and 9999. + // + + public abstract int GetYear(DateTime time); + + // Checks whether a given day in the current era is a leap day. This method returns true if + // the date is a leap day, or false if not. + // + + public virtual bool IsLeapDay(int year, int month, int day) + { + return (IsLeapDay(year, month, day, CurrentEra)); + } + + // Checks whether a given day in the specified era is a leap day. This method returns true if + // the date is a leap day, or false if not. + // + + public abstract bool IsLeapDay(int year, int month, int day, int era); + + // Checks whether a given month in the current era is a leap month. This method returns true if + // month is a leap month, or false if not. + // + + public virtual bool IsLeapMonth(int year, int month) + { + return (IsLeapMonth(year, month, CurrentEra)); + } + + // Checks whether a given month in the specified era is a leap month. This method returns true if + // month is a leap month, or false if not. + // + + public abstract bool IsLeapMonth(int year, int month, int era); + + // Returns the leap month in a calendar year of the specified era. This method returns 0 + // if this calendar does not have leap month, or this year is not a leap year. + // + + [System.Runtime.InteropServices.ComVisible(false)] + public virtual int GetLeapMonth(int year, int era) + { + if (!IsLeapYear(year, era)) + return 0; + + int monthsCount = GetMonthsInYear(year, era); + for (int month = 1; month <= monthsCount; month++) + { + if (IsLeapMonth(year, month, era)) + return month; + } + + return 0; + } + + // Checks whether a given year in the current era is a leap year. This method returns true if + // year is a leap year, or false if not. + // + + public virtual bool IsLeapYear(int year) + { + return (IsLeapYear(year, CurrentEra)); + } + + // Checks whether a given year in the specified era is a leap year. This method returns true if + // year is a leap year, or false if not. + // + + public abstract bool IsLeapYear(int year, int era); + + // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid. + // + + public virtual DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) + { + return (ToDateTime(year, month, day, hour, minute, second, millisecond, CurrentEra)); + } + + // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid. + // + + public abstract DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era); + + internal virtual Boolean TryToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era, out DateTime result) + { + result = DateTime.MinValue; + try + { + result = ToDateTime(year, month, day, hour, minute, second, millisecond, era); + return true; + } + catch (ArgumentException) + { + return false; + } + } + + internal virtual bool IsValidYear(int year, int era) + { + return (year >= GetYear(MinSupportedDateTime) && year <= GetYear(MaxSupportedDateTime)); + } + + internal virtual bool IsValidMonth(int year, int month, int era) + { + return (IsValidYear(year, era) && month >= 1 && month <= GetMonthsInYear(year, era)); + } + + internal virtual bool IsValidDay(int year, int month, int day, int era) + { + return (IsValidMonth(year, month, era) && day >= 1 && day <= GetDaysInMonth(year, month, era)); + } + + + // Returns and assigns the maximum value to represent a two digit year. This + // value is the upper boundary of a 100 year range that allows a two digit year + // to be properly translated to a four digit year. For example, if 2029 is the + // upper boundary, then a two digit value of 30 should be interpreted as 1930 + // while a two digit value of 29 should be interpreted as 2029. In this example + // , the 100 year range would be from 1930-2029. See ToFourDigitYear(). + + public virtual int TwoDigitYearMax + { + get + { + return (twoDigitYearMax); + } + + set + { + VerifyWritable(); + twoDigitYearMax = value; + } + } + + // Converts the year value to the appropriate century by using the + // TwoDigitYearMax property. For example, if the TwoDigitYearMax value is 2029, + // then a two digit value of 30 will get converted to 1930 while a two digit + // value of 29 will get converted to 2029. + + public virtual int ToFourDigitYear(int year) + { + if (year < 0) + { + throw new ArgumentOutOfRangeException("year", + SR.ArgumentOutOfRange_NeedNonNegNum); + } + Contract.EndContractBlock(); + if (year < 100) + { + return ((TwoDigitYearMax / 100 - (year > TwoDigitYearMax % 100 ? 1 : 0)) * 100 + year); + } + // If the year value is above 100, just return the year value. Don't have to do + // the TwoDigitYearMax comparison. + return (year); + } + + // Return the tick count corresponding to the given hour, minute, second. + // Will check the if the parameters are valid. + internal static long TimeToTicks(int hour, int minute, int second, int millisecond) + { + if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60) + { + if (millisecond < 0 || millisecond >= MillisPerSecond) + { + throw new ArgumentOutOfRangeException( + "millisecond", + String.Format( + CultureInfo.InvariantCulture, + SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1))); + } + return InternalGloablizationHelper.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond; + } + throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond); + } + + internal static int GetSystemTwoDigitYearSetting(CalendarId CalID, int defaultYearValue) + { + // Call nativeGetTwoDigitYearMax + int twoDigitYearMax = CalendarData.GetTwoDigitYearMax(CalID); + if (twoDigitYearMax < 0) + { + twoDigitYearMax = defaultYearValue; + } + return (twoDigitYearMax); + } + } +} diff --git a/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs b/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs new file mode 100644 index 0000000000..6c6a18ec37 --- /dev/null +++ b/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs @@ -0,0 +1,341 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Collections.Generic; +using System.Diagnostics.Contracts; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace System.Globalization +{ + // needs to be kept in sync with CalendarDataType in System.Globalization.Native + internal enum CalendarDataType + { + Uninitialized = 0, + NativeName = 1, + MonthDay = 2, + ShortDates = 3, + LongDates = 4, + YearMonths = 5, + DayNames = 6, + AbbrevDayNames = 7, + MonthNames = 8, + AbbrevMonthNames = 9, + SuperShortDayNames = 10, + MonthGenitiveNames = 11, + AbbrevMonthGenitiveNames = 12, + EraNames = 13, + AbbrevEraNames = 14, + } + + internal partial class CalendarData + { + private bool LoadCalendarDataFromSystem(String localeName, CalendarId calendarId) + { + bool result = true; + result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.NativeName, out this.sNativeName); + result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.MonthDay, out this.sMonthDay); + this.sMonthDay = NormalizeDatePattern(this.sMonthDay); + + result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.ShortDates, out this.saShortDates); + result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.LongDates, out this.saLongDates); + result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.YearMonths, out this.saYearMonths); + result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.DayNames, out this.saDayNames); + result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.AbbrevDayNames, out this.saAbbrevDayNames); + result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.SuperShortDayNames, out this.saSuperShortDayNames); + result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthNames, out this.saMonthNames); + result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthNames, out this.saAbbrevMonthNames); + result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthGenitiveNames, out this.saMonthGenitiveNames); + result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames, out this.saAbbrevMonthGenitiveNames); + result &= EnumEraNames(localeName, calendarId, CalendarDataType.EraNames, out this.saEraNames); + result &= EnumEraNames(localeName, calendarId, CalendarDataType.AbbrevEraNames, out this.saAbbrevEraNames); + + return result; + } + + internal static int GetTwoDigitYearMax(CalendarId calendarId) + { + // There is no user override for this value on Linux or in ICU. + // So just return -1 to use the hard-coded defaults. + return -1; + } + + // Call native side to figure out which calendars are allowed + [SecuritySafeCritical] + internal static int GetCalendars(string localeName, bool useUserOverride, CalendarId[] calendars) + { + // NOTE: there are no 'user overrides' on Linux + int count = Interop.GlobalizationInterop.GetCalendars(localeName, calendars, calendars.Length); + + // ensure there is at least 1 calendar returned + if (count == 0 && calendars.Length > 0) + { + calendars[0] = CalendarId.GREGORIAN; + count = 1; + } + + return count; + } + + private static bool SystemSupportsTaiwaneseCalendar() + { + return true; + } + + // PAL Layer ends here + + [SecuritySafeCritical] + private static bool GetCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string calendarString) + { + return Interop.CallStringMethod( + (locale, calId, type, stringBuilder) => + Interop.GlobalizationInterop.GetCalendarInfo( + locale, + calId, + type, + stringBuilder, + stringBuilder.Capacity), + localeName, + calendarId, + dataType, + out calendarString); + } + + private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] datePatterns) + { + datePatterns = null; + + CallbackContext callbackContext = new CallbackContext(); + callbackContext.DisallowDuplicates = true; + bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext); + if (result) + { + List<string> datePatternsList = callbackContext.Results; + + datePatterns = new string[datePatternsList.Count]; + for (int i = 0; i < datePatternsList.Count; i++) + { + datePatterns[i] = NormalizeDatePattern(datePatternsList[i]); + } + } + + return result; + } + + /// <summary> + /// The ICU date format characters are not exactly the same as the .NET date format characters. + /// NormalizeDatePattern will take in an ICU date pattern and return the equivalent .NET date pattern. + /// </summary> + /// <remarks> + /// see Date Field Symbol Table in http://userguide.icu-project.org/formatparse/datetime + /// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx + /// </remarks> + private static string NormalizeDatePattern(string input) + { + StringBuilder destination = StringBuilderCache.Acquire(input.Length); + + int index = 0; + while (index < input.Length) + { + switch (input[index]) + { + case '\'': + // single quotes escape characters, like 'de' in es-SP + // so read verbatim until the next single quote + destination.Append(input[index++]); + while (index < input.Length) + { + char current = input[index++]; + destination.Append(current); + if (current == '\'') + { + break; + } + } + break; + case 'E': + case 'e': + case 'c': + // 'E' in ICU is the day of the week, which maps to 3 or 4 'd's in .NET + // 'e' in ICU is the local day of the week, which has no representation in .NET, but + // maps closest to 3 or 4 'd's in .NET + // 'c' in ICU is the stand-alone day of the week, which has no representation in .NET, but + // maps closest to 3 or 4 'd's in .NET + NormalizeDayOfWeek(input, destination, ref index); + break; + case 'L': + case 'M': + // 'L' in ICU is the stand-alone name of the month, + // which maps closest to 'M' in .NET since it doesn't support stand-alone month names in patterns + // 'M' in both ICU and .NET is the month, + // but ICU supports 5 'M's, which is the super short month name + int occurrences = CountOccurrences(input, input[index], ref index); + if (occurrences > 4) + { + // 5 'L's or 'M's in ICU is the super short name, which maps closest to MMM in .NET + occurrences = 3; + } + destination.Append('M', occurrences); + break; + case 'G': + // 'G' in ICU is the era, which maps to 'g' in .NET + occurrences = CountOccurrences(input, 'G', ref index); + + // it doesn't matter how many 'G's, since .NET only supports 'g' or 'gg', and they + // have the same meaning + destination.Append('g'); + break; + case 'y': + // a single 'y' in ICU is the year with no padding or trimming. + // a single 'y' in .NET is the year with 1 or 2 digits + // so convert any single 'y' to 'yyyy' + occurrences = CountOccurrences(input, 'y', ref index); + if (occurrences == 1) + { + occurrences = 4; + } + destination.Append('y', occurrences); + break; + default: + const string unsupportedDateFieldSymbols = "YuUrQqwWDFg"; + Contract.Assert(unsupportedDateFieldSymbols.IndexOf(input[index]) == -1, + string.Format(CultureInfo.InvariantCulture, + "Encountered an unexpected date field symbol '{0}' from ICU which has no known corresponding .NET equivalent.", + input[index])); + + destination.Append(input[index++]); + break; + } + } + + return StringBuilderCache.GetStringAndRelease(destination); + } + + private static void NormalizeDayOfWeek(string input, StringBuilder destination, ref int index) + { + char dayChar = input[index]; + int occurrences = CountOccurrences(input, dayChar, ref index); + occurrences = Math.Max(occurrences, 3); + if (occurrences > 4) + { + // 5 and 6 E/e/c characters in ICU is the super short names, which maps closest to ddd in .NET + occurrences = 3; + } + + destination.Append('d', occurrences); + } + + private static int CountOccurrences(string input, char value, ref int index) + { + int startIndex = index; + while (index < input.Length && input[index] == value) + { + index++; + } + + return index - startIndex; + } + + [SecuritySafeCritical] + private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] monthNames) + { + monthNames = null; + + CallbackContext callbackContext = new CallbackContext(); + bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext); + if (result) + { + // the month-name arrays are expected to have 13 elements. If ICU only returns 12, add an + // extra empty string to fill the array. + if (callbackContext.Results.Count == 12) + { + callbackContext.Results.Add(string.Empty); + } + + monthNames = callbackContext.Results.ToArray(); + } + + return result; + } + + [SecuritySafeCritical] + private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] eraNames) + { + bool result = EnumCalendarInfo(localeName, calendarId, dataType, out eraNames); + + // .NET expects that only the Japanese calendars have more than 1 era. + // So for other calendars, only return the latest era. + if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames.Length > 0) + { + string[] latestEraName = new string[] { eraNames[eraNames.Length - 1] }; + eraNames = latestEraName; + } + + return result; + } + + [SecuritySafeCritical] + internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] calendarData) + { + calendarData = null; + + CallbackContext callbackContext = new CallbackContext(); + bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext); + if (result) + { + calendarData = callbackContext.Results.ToArray(); + } + + return result; + } + + [SecuritySafeCritical] + private static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, CallbackContext callbackContext) + { + GCHandle context = GCHandle.Alloc(callbackContext); + try + { + return Interop.GlobalizationInterop.EnumCalendarInfo(EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)context); + } + finally + { + context.Free(); + } + } + + [SecuritySafeCritical] + private static void EnumCalendarInfoCallback(string calendarString, IntPtr context) + { + CallbackContext callbackContext = (CallbackContext)((GCHandle)context).Target; + + if (callbackContext.DisallowDuplicates) + { + foreach (string existingResult in callbackContext.Results) + { + if (string.Equals(calendarString, existingResult, StringComparison.Ordinal)) + { + // the value is already in the results, so don't add it again + return; + } + } + } + + callbackContext.Results.Add(calendarString); + } + + private class CallbackContext + { + private List<string> _results = new List<string>(); + + public CallbackContext() + { + } + + public List<string> Results { get { return _results; } } + + public bool DisallowDuplicates { get; set; } + } + } +} diff --git a/src/mscorlib/corefx/System/Globalization/CalendarData.Windows.cs b/src/mscorlib/corefx/System/Globalization/CalendarData.Windows.cs new file mode 100644 index 0000000000..bdf3ff1881 --- /dev/null +++ b/src/mscorlib/corefx/System/Globalization/CalendarData.Windows.cs @@ -0,0 +1,469 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Diagnostics.Contracts; +using System.Collections.Generic; + +namespace System.Globalization +{ + internal partial class CalendarData + { + private bool LoadCalendarDataFromSystem(String localeName, CalendarId calendarId) + { + bool ret = true; + + uint useOverrides = this.bUseUserOverrides ? 0 : CAL_NOUSEROVERRIDE; + + // + // Windows doesn't support some calendars right now, so remap those. + // + switch (calendarId) + { + case CalendarId.JAPANESELUNISOLAR: // Data looks like Japanese + calendarId = CalendarId.JAPAN; + break; + case CalendarId.JULIAN: // Data looks like gregorian US + case CalendarId.CHINESELUNISOLAR: // Algorithmic, so actual data is irrelevent + case CalendarId.SAKA: // reserved to match Office but not implemented in our code, so data is irrelevent + case CalendarId.LUNAR_ETO_CHN: // reserved to match Office but not implemented in our code, so data is irrelevent + case CalendarId.LUNAR_ETO_KOR: // reserved to match Office but not implemented in our code, so data is irrelevent + case CalendarId.LUNAR_ETO_ROKUYOU: // reserved to match Office but not implemented in our code, so data is irrelevent + case CalendarId.KOREANLUNISOLAR: // Algorithmic, so actual data is irrelevent + case CalendarId.TAIWANLUNISOLAR: // Algorithmic, so actual data is irrelevent + calendarId = CalendarId.GREGORIAN_US; + break; + } + + // + // Special handling for some special calendar due to OS limitation. + // This includes calendar like Taiwan calendar, UmAlQura calendar, etc. + // + CheckSpecialCalendar(ref calendarId, ref localeName); + + // Numbers + ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_ITWODIGITYEARMAX | useOverrides, out this.iTwoDigitYearMax); + + // Strings + ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SCALNAME, out this.sNativeName); + ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SMONTHDAY | useOverrides, out this.sMonthDay); + + // String Arrays + // Formats + ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SSHORTDATE, LOCALE_SSHORTDATE | useOverrides, out this.saShortDates); + ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SLONGDATE, LOCALE_SLONGDATE | useOverrides, out this.saLongDates); + + // Get the YearMonth pattern. + ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SYEARMONTH, LOCALE_SYEARMONTH, out this.saYearMonths); + + // Day & Month Names + // These are all single calType entries, 1 per day, so we have to make 7 or 13 calls to collect all the names + + // Day + // Note that we're off-by-one since managed starts on sunday and windows starts on monday + ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SDAYNAME7, out this.saDayNames); + ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SABBREVDAYNAME7, out this.saAbbrevDayNames); + + // Month names + ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1, out this.saMonthNames); + ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1, out this.saAbbrevMonthNames); + + // + // The following LCTYPE are not supported in some platforms. If the call fails, + // don't return a failure. + // + GetCalendarDayInfo(localeName, calendarId, CAL_SSHORTESTDAYNAME7, out this.saSuperShortDayNames); + + // Gregorian may have genitive month names + if (calendarId == CalendarId.GREGORIAN) + { + GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saMonthGenitiveNames); + GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saAbbrevMonthGenitiveNames); + } + + // Calendar Parts Names + // This doesn't get always get localized names for gregorian (not available in windows < 7) + // so: eg: coreclr on win < 7 won't get these + CallEnumCalendarInfo(localeName, calendarId, CAL_SERASTRING, 0, out this.saEraNames); + CallEnumCalendarInfo(localeName, calendarId, CAL_SABBREVERASTRING, 0, out this.saAbbrevEraNames); + + // + // Calendar Era Info + // Note that calendar era data (offsets, etc) is hard coded for each calendar since this + // data is implementation specific and not dynamic (except perhaps Japanese) + // + + // Clean up the escaping of the formats + this.saShortDates = CultureData.ReescapeWin32Strings(this.saShortDates); + this.saLongDates = CultureData.ReescapeWin32Strings(this.saLongDates); + this.saYearMonths = CultureData.ReescapeWin32Strings(this.saYearMonths); + this.sMonthDay = CultureData.ReescapeWin32String(this.sMonthDay); + + return ret; + } + + // Get native two digit year max + internal static int GetTwoDigitYearMax(CalendarId calendarId) + { + int twoDigitYearMax = -1; + + if (!CallGetCalendarInfoEx(null, calendarId, (uint)CAL_ITWODIGITYEARMAX, out twoDigitYearMax)) + { + twoDigitYearMax = -1; + } + + return twoDigitYearMax; + } + + // Call native side to figure out which calendars are allowed + internal static int GetCalendars(String localeName, bool useUserOverride, CalendarId[] calendars) + { + EnumCalendarsData data = new EnumCalendarsData(); + data.userOverride = 0; + data.calendars = new LowLevelList<int>(); + + // First call GetLocaleInfo if necessary + if (useUserOverride) + { + // They want user overrides, see if the user calendar matches the input calendar + int userCalendar = Interop.mincore.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE); + + // If we got a default, then use it as the first calendar + if (userCalendar != 0) + { + data.userOverride = userCalendar; + data.calendars.Add(userCalendar); + } + } + + GCHandle contextHandle = GCHandle.Alloc(data); + try + { + // Now call the enumeration API. Work is done by our callback function + IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, IntPtr, Interop.BOOL>>(EnumCalendarsCallback); + Interop.mincore.EnumCalendarInfoExEx(callback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, (IntPtr)contextHandle); + } + finally + { + contextHandle.Free(); + } + + // Copy to the output array + for (int i = 0; i < Math.Min(calendars.Length, data.calendars.Count); i++) + calendars[i] = (CalendarId)data.calendars[i]; + + // Now we have a list of data, return the count + return data.calendars.Count; + } + + private static bool SystemSupportsTaiwaneseCalendar() + { + string data; + // Taiwanese calendar get listed as one of the optional zh-TW calendars only when having zh-TW UI + return CallGetCalendarInfoEx("zh-TW", CalendarId.TAIWAN, CAL_SCALNAME, out data); + } + + // PAL Layer ends here + + private const uint CAL_RETURN_NUMBER = 0x20000000; + private const uint CAL_RETURN_GENITIVE_NAMES = 0x10000000; + private const uint CAL_NOUSEROVERRIDE = 0x80000000; + private const uint CAL_SCALNAME = 0x00000002; + private const uint CAL_SMONTHDAY = 0x00000038; + private const uint CAL_SSHORTDATE = 0x00000005; + private const uint CAL_SLONGDATE = 0x00000006; + private const uint CAL_SYEARMONTH = 0x0000002f; + private const uint CAL_SDAYNAME7 = 0x0000000d; + private const uint CAL_SABBREVDAYNAME7 = 0x00000014; + private const uint CAL_SMONTHNAME1 = 0x00000015; + private const uint CAL_SABBREVMONTHNAME1 = 0x00000022; + private const uint CAL_SSHORTESTDAYNAME7 = 0x00000037; + private const uint CAL_SERASTRING = 0x00000004; + private const uint CAL_SABBREVERASTRING = 0x00000039; + private const uint CAL_ICALINTVALUE = 0x00000001; + private const uint CAL_ITWODIGITYEARMAX = 0x00000030; + + private const uint ENUM_ALL_CALENDARS = 0xffffffff; + + private const uint LOCALE_SSHORTDATE = 0x0000001F; + private const uint LOCALE_SLONGDATE = 0x00000020; + private const uint LOCALE_SYEARMONTH = 0x00001006; + private const uint LOCALE_ICALENDARTYPE = 0x00001009; + + //////////////////////////////////////////////////////////////////////// + // + // For calendars like Gregorain US/Taiwan/UmAlQura, they are not available + // in all OS or all localized versions of OS. + // If OS does not support these calendars, we will fallback by using the + // appropriate fallback calendar and locale combination to retrieve data from OS. + // + // Parameters: + // __deref_inout pCalendarInt: + // Pointer to the calendar ID. This will be updated to new fallback calendar ID if needed. + // __in_out pLocaleNameStackBuffer + // Pointer to the StackSString object which holds the locale name to be checked. + // This will be updated to new fallback locale name if needed. + // + //////////////////////////////////////////////////////////////////////// + private static void CheckSpecialCalendar(ref CalendarId calendar, ref string localeName) + { + string data; + + // Gregorian-US isn't always available in the OS, however it is the same for all locales + switch (calendar) + { + case CalendarId.GREGORIAN_US: + // See if this works + if (!CallGetCalendarInfoEx(localeName, calendar, CAL_SCALNAME, out data)) + { + // Failed, set it to a locale (fa-IR) that's alway has Gregorian US available in the OS + localeName = "fa-IR"; + } + // See if that works + if (!CallGetCalendarInfoEx(localeName, calendar, CAL_SCALNAME, out data)) + { + // Failed again, just use en-US with the gregorian calendar + localeName = "en-US"; + calendar = CalendarId.GREGORIAN; + } + break; + case CalendarId.TAIWAN: + // Taiwan calendar data is not always in all language version of OS due to Geopolical reasons. + // It is only available in zh-TW localized versions of Windows. + // Let's check if OS supports it. If not, fallback to Greogrian localized for Taiwan calendar. + if (!SystemSupportsTaiwaneseCalendar()) + { + calendar = CalendarId.GREGORIAN; + } + break; + } + } + + private static bool CallGetCalendarInfoEx(string localeName, CalendarId calendar, uint calType, out int data) + { + return (Interop.mincore.GetCalendarInfoEx(localeName, (uint)calendar, IntPtr.Zero, calType | CAL_RETURN_NUMBER, IntPtr.Zero, 0, out data) != 0); + } + + private static unsafe bool CallGetCalendarInfoEx(string localeName, CalendarId calendar, uint calType, out string data) + { + const int BUFFER_LENGTH = 80; + + // The maximum size for values returned from GetCalendarInfoEx is 80 characters. + char* buffer = stackalloc char[BUFFER_LENGTH]; + + int ret = Interop.mincore.GetCalendarInfoEx(localeName, (uint)calendar, IntPtr.Zero, calType, (IntPtr)buffer, BUFFER_LENGTH, IntPtr.Zero); + if (ret > 0) + { + if (buffer[ret - 1] == '\0') + { + ret--; // don't include the null termination in the string + } + data = new string(buffer, 0, ret); + return true; + } + data = ""; + return false; + } + + // Context for EnumCalendarInfoExEx callback. + private class EnumData + { + public string userOverride; + public LowLevelList<string> strings; + } + + // EnumCalendarInfoExEx callback itself. + [NativeCallable(CallingConvention = CallingConvention.StdCall)] + private static unsafe Interop.BOOL EnumCalendarInfoCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr pReserved, IntPtr lParam) + { + EnumData context = (EnumData)((GCHandle)lParam).Target; + try + { + string calendarInfo = new string((char*)lpCalendarInfoString); + + // If we had a user override, check to make sure this differs + if (context.userOverride != calendarInfo) + context.strings.Add(calendarInfo); + + return Interop.BOOL.TRUE; + } + catch (Exception) + { + return Interop.BOOL.FALSE; + } + } + + private static unsafe bool CallEnumCalendarInfo(string localeName, CalendarId calendar, uint calType, uint lcType, out string[] data) + { + EnumData context = new EnumData(); + context.userOverride = null; + context.strings = new LowLevelList<string>(); + + // First call GetLocaleInfo if necessary + if (((lcType != 0) && ((lcType & CAL_NOUSEROVERRIDE) == 0)) && + // Get user locale, see if it matches localeName. + // Note that they should match exactly, including letter case + GetUserDefaultLocaleName() == localeName) + { + // They want user overrides, see if the user calendar matches the input calendar + CalendarId userCalendar = (CalendarId)Interop.mincore.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE); + + // If the calendars were the same, see if the locales were the same + if (userCalendar == calendar) + { + // They matched, get the user override since locale & calendar match + string res = Interop.mincore.GetLocaleInfoEx(localeName, lcType); + + // if it succeeded remember the override for the later callers + if (res != "") + { + // Remember this was the override (so we can look for duplicates later in the enum function) + context.userOverride = res; + + // Add to the result strings. + context.strings.Add(res); + } + } + } + + GCHandle contextHandle = GCHandle.Alloc(context); + try + { + // Now call the enumeration API. Work is done by our callback function + IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, IntPtr, Interop.BOOL>>(EnumCalendarInfoCallback); + Interop.mincore.EnumCalendarInfoExEx(callback, localeName, (uint)calendar, null, calType, (IntPtr)contextHandle); + } + finally + { + contextHandle.Free(); + } + + // Now we have a list of data, fail if we didn't find anything. + if (context.strings.Count == 0) + { + data = null; + return false; + } + + string[] output = context.strings.ToArray(); + + if (calType == CAL_SABBREVERASTRING || calType == CAL_SERASTRING) + { + // Eras are enumerated backwards. (oldest era name first, but + // Japanese calendar has newest era first in array, and is only + // calendar with multiple eras) + Array.Reverse(output, 0, output.Length); + } + + data = output; + + return true; + } + + //////////////////////////////////////////////////////////////////////// + // + // Get the native day names + // + // NOTE: There's a disparity between .Net & windows day orders, the input day should + // start with Sunday + // + // Parameters: + // OUT pOutputStrings The output string[] value. + // + //////////////////////////////////////////////////////////////////////// + private static bool GetCalendarDayInfo(string localeName, CalendarId calendar, uint calType, out string[] outputStrings) + { + bool result = true; + + // + // We'll need a new array of 7 items + // + string[] results = new string[7]; + + // Get each one of them + for (int i = 0; i < 7; i++, calType++) + { + result &= CallGetCalendarInfoEx(localeName, calendar, calType, out results[i]); + + // On the first iteration we need to go from CAL_SDAYNAME7 to CAL_SDAYNAME1, so subtract 7 before the ++ happens + // This is because the framework starts on sunday and windows starts on monday when counting days + if (i == 0) + calType -= 7; + } + + outputStrings = results; + + return result; + } + + //////////////////////////////////////////////////////////////////////// + // + // Get the native month names + // + // Parameters: + // OUT pOutputStrings The output string[] value. + // + //////////////////////////////////////////////////////////////////////// + private static bool GetCalendarMonthInfo(string localeName, CalendarId calendar, uint calType, out string[] outputStrings) + { + // + // We'll need a new array of 13 items + // + string[] results = new string[13]; + + // Get each one of them + for (int i = 0; i < 13; i++, calType++) + { + if (!CallGetCalendarInfoEx(localeName, calendar, calType, out results[i])) + results[i] = ""; + } + + outputStrings = results; + + return true; + } + + // + // struct to help our calendar data enumaration callback + // + private class EnumCalendarsData + { + public int userOverride; // user override value (if found) + public LowLevelList<int> calendars; // list of calendars found so far + } + + [NativeCallable(CallingConvention = CallingConvention.StdCall)] + private static Interop.BOOL EnumCalendarsCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr reserved, IntPtr lParam) + { + EnumCalendarsData context = (EnumCalendarsData)((GCHandle)lParam).Target; + try + { + // If we had a user override, check to make sure this differs + if (context.userOverride != calendar) + context.calendars.Add((int)calendar); + + return Interop.BOOL.TRUE; + } + catch (Exception) + { + return Interop.BOOL.FALSE; + } + } + + private static unsafe String GetUserDefaultLocaleName() + { + const int LOCALE_NAME_MAX_LENGTH = 85; + const uint LOCALE_SNAME = 0x0000005c; + const string LOCALE_NAME_USER_DEFAULT = null; + + int result; + char* localeName = stackalloc char[LOCALE_NAME_MAX_LENGTH]; + result = Interop.mincore.GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, localeName, LOCALE_NAME_MAX_LENGTH); + + return result <= 0 ? "" : new String(localeName, 0, result - 1); // exclude the null termination + } + } +} diff --git a/src/mscorlib/corefx/System/Globalization/CalendarData.cs b/src/mscorlib/corefx/System/Globalization/CalendarData.cs new file mode 100644 index 0000000000..2dbd1b8069 --- /dev/null +++ b/src/mscorlib/corefx/System/Globalization/CalendarData.cs @@ -0,0 +1,381 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Diagnostics.Contracts; +using System.Collections.Generic; + +namespace System.Globalization +{ + // List of calendar data + // Note the we cache overrides. + // Note that localized names (resource names) aren't available from here. + // + // NOTE: Calendars depend on the locale name that creates it. Only a few + // properties are available without locales using CalendarData.GetCalendar(CalendarData) + + internal partial class CalendarData + { + // Max calendars + internal const int MAX_CALENDARS = 23; + + // Identity + internal String sNativeName; // Calendar Name for the locale + + // Formats + internal String[] saShortDates; // Short Data format, default first + internal String[] saYearMonths; // Year/Month Data format, default first + internal String[] saLongDates; // Long Data format, default first + internal String sMonthDay; // Month/Day format + + // Calendar Parts Names + internal String[] saEraNames; // Names of Eras + internal String[] saAbbrevEraNames; // Abbreviated Era Names + internal String[] saAbbrevEnglishEraNames; // Abbreviated Era Names in English + internal String[] saDayNames; // Day Names, null to use locale data, starts on Sunday + internal String[] saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday + internal String[] saSuperShortDayNames; // Super short Day of week names + internal String[] saMonthNames; // Month Names (13) + internal String[] saAbbrevMonthNames; // Abbrev Month Names (13) + internal String[] saMonthGenitiveNames; // Genitive Month Names (13) + internal String[] saAbbrevMonthGenitiveNames; // Genitive Abbrev Month Names (13) + internal String[] saLeapYearMonthNames; // Multiple strings for the month names in a leap year. + + // Integers at end to make marshaller happier + internal int iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry) + internal int iCurrentEra = 0; // current era # (usually 1) + + // Use overrides? + internal bool bUseUserOverrides; // True if we want user overrides. + + // Static invariant for the invariant locale + internal static CalendarData Invariant; + + // Private constructor + private CalendarData() { } + + // Invariant constructor + static CalendarData() + { + // Set our default/gregorian US calendar data + // Calendar IDs are 1-based, arrays are 0 based. + CalendarData invariant = new CalendarData(); + + // Set default data for calendar + // Note that we don't load resources since this IS NOT supposed to change (by definition) + invariant.sNativeName = "Gregorian Calendar"; // Calendar Name + + // Year + invariant.iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry) + invariant.iCurrentEra = 1; // Current era # + + // Formats + invariant.saShortDates = new String[] { "MM/dd/yyyy", "yyyy-MM-dd" }; // short date format + invariant.saLongDates = new String[] { "dddd, dd MMMM yyyy" }; // long date format + invariant.saYearMonths = new String[] { "yyyy MMMM" }; // year month format + invariant.sMonthDay = "MMMM dd"; // Month day pattern + + // Calendar Parts Names + invariant.saEraNames = new String[] { "A.D." }; // Era names + invariant.saAbbrevEraNames = new String[] { "AD" }; // Abbreviated Era names + invariant.saAbbrevEnglishEraNames = new String[] { "AD" }; // Abbreviated era names in English + invariant.saDayNames = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };// day names + invariant.saAbbrevDayNames = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; // abbreviated day names + invariant.saSuperShortDayNames = new String[] { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }; // The super short day names + invariant.saMonthNames = new String[] { "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December", String.Empty}; // month names + invariant.saAbbrevMonthNames = new String[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", String.Empty}; // abbreviated month names + invariant.saMonthGenitiveNames = invariant.saMonthNames; // Genitive month names (same as month names for invariant) + invariant.saAbbrevMonthGenitiveNames = invariant.saAbbrevMonthNames; // Abbreviated genitive month names (same as abbrev month names for invariant) + invariant.saLeapYearMonthNames = invariant.saMonthNames; // leap year month names are unused in Gregorian English (invariant) + + invariant.bUseUserOverrides = false; + + // Calendar was built, go ahead and assign it... + Invariant = invariant; + } + + // + // Get a bunch of data for a calendar + // + internal CalendarData(String localeName, CalendarId calendarId, bool bUseUserOverrides) + { + this.bUseUserOverrides = bUseUserOverrides; + + if (!LoadCalendarDataFromSystem(localeName, calendarId)) + { + Contract.Assert(false, "[CalendarData] LoadCalendarDataFromSystem call isn't expected to fail for calendar " + calendarId + " locale " + localeName); + + // Something failed, try invariant for missing parts + // This is really not good, but we don't want the callers to crash. + if (this.sNativeName == null) this.sNativeName = String.Empty; // Calendar Name for the locale. + + // Formats + if (this.saShortDates == null) this.saShortDates = Invariant.saShortDates; // Short Data format, default first + if (this.saYearMonths == null) this.saYearMonths = Invariant.saYearMonths; // Year/Month Data format, default first + if (this.saLongDates == null) this.saLongDates = Invariant.saLongDates; // Long Data format, default first + if (this.sMonthDay == null) this.sMonthDay = Invariant.sMonthDay; // Month/Day format + + // Calendar Parts Names + if (this.saEraNames == null) this.saEraNames = Invariant.saEraNames; // Names of Eras + if (this.saAbbrevEraNames == null) this.saAbbrevEraNames = Invariant.saAbbrevEraNames; // Abbreviated Era Names + if (this.saAbbrevEnglishEraNames == null) this.saAbbrevEnglishEraNames = Invariant.saAbbrevEnglishEraNames; // Abbreviated Era Names in English + if (this.saDayNames == null) this.saDayNames = Invariant.saDayNames; // Day Names, null to use locale data, starts on Sunday + if (this.saAbbrevDayNames == null) this.saAbbrevDayNames = Invariant.saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday + if (this.saSuperShortDayNames == null) this.saSuperShortDayNames = Invariant.saSuperShortDayNames; // Super short Day of week names + if (this.saMonthNames == null) this.saMonthNames = Invariant.saMonthNames; // Month Names (13) + if (this.saAbbrevMonthNames == null) this.saAbbrevMonthNames = Invariant.saAbbrevMonthNames; // Abbrev Month Names (13) + // Genitive and Leap names can follow the fallback below + } + + if (calendarId == CalendarId.TAIWAN) + { + if (SystemSupportsTaiwaneseCalendar()) + { + // We got the month/day names from the OS (same as gregorian), but the native name is wrong + this.sNativeName = "\x4e2d\x83ef\x6c11\x570b\x66c6"; + } + else + { + this.sNativeName = String.Empty; + } + } + + // Check for null genitive names (in case unmanaged side skips it for non-gregorian calendars, etc) + if (this.saMonthGenitiveNames == null || this.saMonthGenitiveNames.Length == 0 || String.IsNullOrEmpty(this.saMonthGenitiveNames[0])) + this.saMonthGenitiveNames = this.saMonthNames; // Genitive month names (same as month names for invariant) + if (this.saAbbrevMonthGenitiveNames == null || this.saAbbrevMonthGenitiveNames.Length == 0 || String.IsNullOrEmpty(this.saAbbrevMonthGenitiveNames[0])) + this.saAbbrevMonthGenitiveNames = this.saAbbrevMonthNames; // Abbreviated genitive month names (same as abbrev month names for invariant) + if (this.saLeapYearMonthNames == null || this.saLeapYearMonthNames.Length == 0 || String.IsNullOrEmpty(this.saLeapYearMonthNames[0])) + this.saLeapYearMonthNames = this.saMonthNames; + + InitializeEraNames(localeName, calendarId); + + InitializeAbbreviatedEraNames(localeName, calendarId); + + // Abbreviated English Era Names are only used for the Japanese calendar. + if (calendarId == CalendarId.JAPAN) + { + this.saAbbrevEnglishEraNames = JapaneseCalendar.EnglishEraNames(); + } + else + { + // For all others just use the an empty string (doesn't matter we'll never ask for it for other calendars) + this.saAbbrevEnglishEraNames = new String[] { "" }; + } + + // Japanese is the only thing with > 1 era. Its current era # is how many ever + // eras are in the array. (And the others all have 1 string in the array) + this.iCurrentEra = this.saEraNames.Length; + } + + private void InitializeEraNames(string localeName, CalendarId calendarId) + { + // Note that the saEraNames only include "A.D." We don't have localized names for other calendars available from windows + switch (calendarId) + { + // For Localized Gregorian we really expect the data from the OS. + case CalendarId.GREGORIAN: + // Fallback for CoreCLR < Win7 or culture.dll missing + if (this.saEraNames == null || this.saEraNames.Length == 0 || String.IsNullOrEmpty(this.saEraNames[0])) + { + this.saEraNames = new String[] { "A.D." }; + } + break; + + // The rest of the calendars have constant data, so we'll just use that + case CalendarId.GREGORIAN_US: + case CalendarId.JULIAN: + this.saEraNames = new String[] { "A.D." }; + break; + case CalendarId.HEBREW: + this.saEraNames = new String[] { "C.E." }; + break; + case CalendarId.HIJRI: + case CalendarId.UMALQURA: + if (localeName == "dv-MV") + { + // Special case for Divehi + this.saEraNames = new String[] { "\x0780\x07a8\x0796\x07b0\x0783\x07a9" }; + } + else + { + this.saEraNames = new String[] { "\x0628\x0639\x062F \x0627\x0644\x0647\x062C\x0631\x0629" }; + } + break; + case CalendarId.GREGORIAN_ARABIC: + case CalendarId.GREGORIAN_XLIT_ENGLISH: + case CalendarId.GREGORIAN_XLIT_FRENCH: + // These are all the same: + this.saEraNames = new String[] { "\x0645" }; + break; + + case CalendarId.GREGORIAN_ME_FRENCH: + this.saEraNames = new String[] { "ap. J.-C." }; + break; + + case CalendarId.TAIWAN: + if (SystemSupportsTaiwaneseCalendar()) + { + this.saEraNames = new String[] { "\x4e2d\x83ef\x6c11\x570b" }; + } + else + { + this.saEraNames = new String[] { String.Empty }; + } + break; + + case CalendarId.KOREA: + this.saEraNames = new String[] { "\xb2e8\xae30" }; + break; + + case CalendarId.THAI: + this.saEraNames = new String[] { "\x0e1e\x002e\x0e28\x002e" }; + break; + + case CalendarId.JAPAN: + case CalendarId.JAPANESELUNISOLAR: + this.saEraNames = JapaneseCalendar.EraNames(); + break; + + case CalendarId.PERSIAN: + if (this.saEraNames == null || this.saEraNames.Length == 0 || String.IsNullOrEmpty(this.saEraNames[0])) + { + this.saEraNames = new String[] { "\x0647\x002e\x0634" }; + } + break; + + default: + // Most calendars are just "A.D." + this.saEraNames = Invariant.saEraNames; + break; + } + } + + private void InitializeAbbreviatedEraNames(string localeName, CalendarId calendarId) + { + // Note that the saAbbrevEraNames only include "AD" We don't have localized names for other calendars available from windows + switch (calendarId) + { + // For Localized Gregorian we really expect the data from the OS. + case CalendarId.GREGORIAN: + // Fallback for CoreCLR < Win7 or culture.dll missing + if (this.saAbbrevEraNames == null || this.saAbbrevEraNames.Length == 0 || String.IsNullOrEmpty(this.saAbbrevEraNames[0])) + { + this.saAbbrevEraNames = new String[] { "AD" }; + } + break; + + // The rest of the calendars have constant data, so we'll just use that + case CalendarId.GREGORIAN_US: + case CalendarId.JULIAN: + this.saAbbrevEraNames = new String[] { "AD" }; + break; + case CalendarId.JAPAN: + case CalendarId.JAPANESELUNISOLAR: + this.saAbbrevEraNames = JapaneseCalendar.AbbrevEraNames(); + break; + case CalendarId.HIJRI: + case CalendarId.UMALQURA: + if (localeName == "dv-MV") + { + // Special case for Divehi + this.saAbbrevEraNames = new String[] { "\x0780\x002e" }; + } + else + { + this.saAbbrevEraNames = new String[] { "\x0647\x0640" }; + } + break; + case CalendarId.TAIWAN: + // Get era name and abbreviate it + this.saAbbrevEraNames = new String[1]; + if (this.saEraNames[0].Length == 4) + { + this.saAbbrevEraNames[0] = this.saEraNames[0].Substring(2, 2); + } + else + { + this.saAbbrevEraNames[0] = this.saEraNames[0]; + } + break; + + case CalendarId.PERSIAN: + if (this.saAbbrevEraNames == null || this.saAbbrevEraNames.Length == 0 || String.IsNullOrEmpty(this.saAbbrevEraNames[0])) + { + this.saAbbrevEraNames = this.saEraNames; + } + break; + + default: + // Most calendars just use the full name + this.saAbbrevEraNames = this.saEraNames; + break; + } + } + + internal static CalendarData GetCalendarData(CalendarId calendarId) + { + // + // Get a calendar. + // Unfortunately we depend on the locale in the OS, so we need a locale + // no matter what. So just get the appropriate calendar from the + // appropriate locale here + // + + // Get a culture name + // TODO: Note that this doesn't handle the new calendars (lunisolar, etc) + String culture = CalendarIdToCultureName(calendarId); + + // Return our calendar + return CultureInfo.GetCultureInfo(culture).m_cultureData.GetCalendar(calendarId); + } + + private static String CalendarIdToCultureName(CalendarId calendarId) + { + switch (calendarId) + { + case CalendarId.GREGORIAN_US: + return "fa-IR"; // "fa-IR" Iran + + case CalendarId.JAPAN: + return "ja-JP"; // "ja-JP" Japan + + case CalendarId.TAIWAN: + return "zh-TW"; // zh-TW Taiwan + + case CalendarId.KOREA: + return "ko-KR"; // "ko-KR" Korea + + case CalendarId.HIJRI: + case CalendarId.GREGORIAN_ARABIC: + case CalendarId.UMALQURA: + return "ar-SA"; // "ar-SA" Saudi Arabia + + case CalendarId.THAI: + return "th-TH"; // "th-TH" Thailand + + case CalendarId.HEBREW: + return "he-IL"; // "he-IL" Israel + + case CalendarId.GREGORIAN_ME_FRENCH: + return "ar-DZ"; // "ar-DZ" Algeria + + case CalendarId.GREGORIAN_XLIT_ENGLISH: + case CalendarId.GREGORIAN_XLIT_FRENCH: + return "ar-IQ"; // "ar-IQ"; Iraq + + default: + // Default to gregorian en-US + break; + } + + return "en-US"; + } + } +} + diff --git a/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs b/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs new file mode 100644 index 0000000000..490951e1f0 --- /dev/null +++ b/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; + +namespace System.Globalization +{ + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public enum CalendarWeekRule + { + FirstDay = 0, // Week 1 begins on the first day of the year + + FirstFullWeek = 1, // Week 1 begins on first FirstDayOfWeek not before the first day of the year + + FirstFourDayWeek = 2 // Week 1 begins on first FirstDayOfWeek such that FirstDayOfWeek+3 is not before the first day of the year + }; +} diff --git a/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs b/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs new file mode 100644 index 0000000000..ba7601b420 --- /dev/null +++ b/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs @@ -0,0 +1,413 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; +using System.Diagnostics.Contracts; + +namespace System.Globalization +{ + internal class CalendricalCalculationsHelper + { + private const double FullCircleOfArc = 360.0; // 360.0; + private const int HalfCircleOfArc = 180; + private const double TwelveHours = 0.5; // half a day + private const double Noon2000Jan01 = 730120.5; + internal const double MeanTropicalYearInDays = 365.242189; + private const double MeanSpeedOfSun = MeanTropicalYearInDays / FullCircleOfArc; + private const double LongitudeSpring = 0.0; + private const double TwoDegreesAfterSpring = 2.0; + private const int SecondsPerDay = 24 * 60 * 60; // 24 hours * 60 minutes * 60 seconds + + private const int DaysInUniformLengthCentury = 36525; + private const int SecondsPerMinute = 60; + private const int MinutesPerDegree = 60; + + private static readonly long StartOf1810 = GetNumberOfDays(new DateTime(1810, 1, 1)); + private static readonly long StartOf1900Century = GetNumberOfDays(new DateTime(1900, 1, 1)); + + private static readonly double[] s_coefficients1900to1987 = new double[] { -0.00002, 0.000297, 0.025184, -0.181133, 0.553040, -0.861938, 0.677066, -0.212591 }; + private static readonly double[] s_coefficients1800to1899 = new double[] { -0.000009, 0.003844, 0.083563, 0.865736, 4.867575, 15.845535, 31.332267, 38.291999, 28.316289, 11.636204, 2.043794 }; + private static readonly double[] s_coefficients1700to1799 = new double[] { 8.118780842, -0.005092142, 0.003336121, -0.0000266484 }; + private static readonly double[] s_coefficients1620to1699 = new double[] { 196.58333, -4.0675, 0.0219167 }; + private static readonly double[] s_lambdaCoefficients = new double[] { 280.46645, 36000.76983, 0.0003032 }; + private static readonly double[] s_anomalyCoefficients = new double[] { 357.52910, 35999.05030, -0.0001559, -0.00000048 }; + private static readonly double[] s_eccentricityCoefficients = new double[] { 0.016708617, -0.000042037, -0.0000001236 }; + private static readonly double[] s_coefficients = new double[] { Angle(23, 26, 21.448), Angle(0, 0, -46.8150), Angle(0, 0, -0.00059), Angle(0, 0, 0.001813) }; + private static readonly double[] s_coefficientsA = new double[] { 124.90, -1934.134, 0.002063 }; + private static readonly double[] s_coefficientsB = new double[] { 201.11, 72001.5377, 0.00057 }; + + private static double RadiansFromDegrees(double degree) + { + return degree * Math.PI / 180; + } + + private static double SinOfDegree(double degree) + { + return Math.Sin(RadiansFromDegrees(degree)); + } + + private static double CosOfDegree(double degree) + { + return Math.Cos(RadiansFromDegrees(degree)); + } + private static double TanOfDegree(double degree) + { + return Math.Tan(RadiansFromDegrees(degree)); + } + + public static double Angle(int degrees, int minutes, double seconds) + { + return ((seconds / SecondsPerMinute + minutes) / MinutesPerDegree) + degrees; + } + + private static double Obliquity(double julianCenturies) + { + return PolynomialSum(s_coefficients, julianCenturies); + } + + internal static long GetNumberOfDays(DateTime date) + { + return date.Ticks / GregorianCalendar.TicksPerDay; + } + + private static int GetGregorianYear(double numberOfDays) + { + return new DateTime(Math.Min((long)(Math.Floor(numberOfDays) * GregorianCalendar.TicksPerDay), DateTime.MaxValue.Ticks)).Year; + } + + private enum CorrectionAlgorithm + { + Default, + Year1988to2019, + Year1900to1987, + Year1800to1899, + Year1700to1799, + Year1620to1699 + } + + private struct EphemerisCorrectionAlgorithmMap + { + public EphemerisCorrectionAlgorithmMap(int year, CorrectionAlgorithm algorithm) + { + _lowestYear = year; + _algorithm = algorithm; + } + + internal int _lowestYear; + internal CorrectionAlgorithm _algorithm; + }; + + private static readonly EphemerisCorrectionAlgorithmMap[] s_ephemerisCorrectionTable = new EphemerisCorrectionAlgorithmMap[] + { + // lowest year that starts algorithm, algorithm to use + new EphemerisCorrectionAlgorithmMap(2020, CorrectionAlgorithm.Default), + new EphemerisCorrectionAlgorithmMap(1988, CorrectionAlgorithm.Year1988to2019), + new EphemerisCorrectionAlgorithmMap(1900, CorrectionAlgorithm.Year1900to1987), + new EphemerisCorrectionAlgorithmMap(1800, CorrectionAlgorithm.Year1800to1899), + new EphemerisCorrectionAlgorithmMap(1700, CorrectionAlgorithm.Year1700to1799), + new EphemerisCorrectionAlgorithmMap(1620, CorrectionAlgorithm.Year1620to1699), + new EphemerisCorrectionAlgorithmMap(int.MinValue, CorrectionAlgorithm.Default) // default must be last + }; + + private static double Reminder(double divisor, double dividend) + { + double whole = Math.Floor(divisor / dividend); + return divisor - (dividend * whole); + } + + private static double NormalizeLongitude(double longitude) + { + longitude = Reminder(longitude, FullCircleOfArc); + if (longitude < 0) + { + longitude += FullCircleOfArc; + } + return longitude; + } + + static public double AsDayFraction(double longitude) + { + return longitude / FullCircleOfArc; + } + + private static double PolynomialSum(double[] coefficients, double indeterminate) + { + double sum = coefficients[0]; + double indeterminateRaised = 1; + for (int i = 1; i < coefficients.Length; i++) + { + indeterminateRaised *= indeterminate; + sum += (coefficients[i] * indeterminateRaised); + } + + return sum; + } + + private static double CenturiesFrom1900(int gregorianYear) + { + long july1stOfYear = GetNumberOfDays(new DateTime(gregorianYear, 7, 1)); + return (double)(july1stOfYear - StartOf1900Century) / DaysInUniformLengthCentury; + } + + // the following formulas defines a polynomial function which gives us the amount that the earth is slowing down for specific year ranges + private static double DefaultEphemerisCorrection(int gregorianYear) + { + Contract.Assert(gregorianYear < 1620 || 2020 <= gregorianYear); + long january1stOfYear = GetNumberOfDays(new DateTime(gregorianYear, 1, 1)); + double daysSinceStartOf1810 = january1stOfYear - StartOf1810; + double x = TwelveHours + daysSinceStartOf1810; + return ((Math.Pow(x, 2) / 41048480) - 15) / SecondsPerDay; + } + + private static double EphemerisCorrection1988to2019(int gregorianYear) + { + Contract.Assert(1988 <= gregorianYear && gregorianYear <= 2019); + return (double)(gregorianYear - 1933) / SecondsPerDay; + } + + private static double EphemerisCorrection1900to1987(int gregorianYear) + { + Contract.Assert(1900 <= gregorianYear && gregorianYear <= 1987); + double centuriesFrom1900 = CenturiesFrom1900(gregorianYear); + return PolynomialSum(s_coefficients1900to1987, centuriesFrom1900); + } + + private static double EphemerisCorrection1800to1899(int gregorianYear) + { + Contract.Assert(1800 <= gregorianYear && gregorianYear <= 1899); + double centuriesFrom1900 = CenturiesFrom1900(gregorianYear); + return PolynomialSum(s_coefficients1800to1899, centuriesFrom1900); + } + + private static double EphemerisCorrection1700to1799(int gregorianYear) + { + Contract.Assert(1700 <= gregorianYear && gregorianYear <= 1799); + double yearsSince1700 = gregorianYear - 1700; + return PolynomialSum(s_coefficients1700to1799, yearsSince1700) / SecondsPerDay; + } + + private static double EphemerisCorrection1620to1699(int gregorianYear) + { + Contract.Assert(1620 <= gregorianYear && gregorianYear <= 1699); + double yearsSince1600 = gregorianYear - 1600; + return PolynomialSum(s_coefficients1620to1699, yearsSince1600) / SecondsPerDay; + } + + // ephemeris-correction: correction to account for the slowing down of the rotation of the earth + private static double EphemerisCorrection(double time) + { + int year = GetGregorianYear(time); + foreach (EphemerisCorrectionAlgorithmMap map in s_ephemerisCorrectionTable) + { + if (map._lowestYear <= year) + { + switch (map._algorithm) + { + case CorrectionAlgorithm.Default: return DefaultEphemerisCorrection(year); + case CorrectionAlgorithm.Year1988to2019: return EphemerisCorrection1988to2019(year); + case CorrectionAlgorithm.Year1900to1987: return EphemerisCorrection1900to1987(year); + case CorrectionAlgorithm.Year1800to1899: return EphemerisCorrection1800to1899(year); + case CorrectionAlgorithm.Year1700to1799: return EphemerisCorrection1700to1799(year); + case CorrectionAlgorithm.Year1620to1699: return EphemerisCorrection1620to1699(year); + } + + break; // break the loop and assert eventually + } + } + + Contract.Assert(false, "Not expected to come here"); + return DefaultEphemerisCorrection(year); + } + + static public double JulianCenturies(double moment) + { + double dynamicalMoment = moment + EphemerisCorrection(moment); + return (dynamicalMoment - Noon2000Jan01) / DaysInUniformLengthCentury; + } + + private static bool IsNegative(double value) + { + return Math.Sign(value) == -1; + } + + private static double CopySign(double value, double sign) + { + return (IsNegative(value) == IsNegative(sign)) ? value : -value; + } + + // equation-of-time; approximate the difference between apparent solar time and mean solar time + // formal definition is EOT = GHA - GMHA + // GHA is the Greenwich Hour Angle of the apparent (actual) Sun + // GMHA is the Greenwich Mean Hour Angle of the mean (fictitious) Sun + // http://www.esrl.noaa.gov/gmd/grad/solcalc/ + // http://en.wikipedia.org/wiki/Equation_of_time + private static double EquationOfTime(double time) + { + double julianCenturies = JulianCenturies(time); + double lambda = PolynomialSum(s_lambdaCoefficients, julianCenturies); + double anomaly = PolynomialSum(s_anomalyCoefficients, julianCenturies); + double eccentricity = PolynomialSum(s_eccentricityCoefficients, julianCenturies); + + double epsilon = Obliquity(julianCenturies); + double tanHalfEpsilon = TanOfDegree(epsilon / 2); + double y = tanHalfEpsilon * tanHalfEpsilon; + + double dividend = ((y * SinOfDegree(2 * lambda)) + - (2 * eccentricity * SinOfDegree(anomaly)) + + (4 * eccentricity * y * SinOfDegree(anomaly) * CosOfDegree(2 * lambda)) + - (0.5 * Math.Pow(y, 2) * SinOfDegree(4 * lambda)) + - (1.25 * Math.Pow(eccentricity, 2) * SinOfDegree(2 * anomaly))); + double divisor = 2 * Math.PI; + double equation = dividend / divisor; + + // approximation of equation of time is not valid for dates that are many millennia in the past or future + // thus limited to a half day + return CopySign(Math.Min(Math.Abs(equation), TwelveHours), equation); + } + + private static double AsLocalTime(double apparentMidday, double longitude) + { + // slightly inaccurate since equation of time takes mean time not apparent time as its argument, but the difference is negligible + double universalTime = apparentMidday - AsDayFraction(longitude); + return apparentMidday - EquationOfTime(universalTime); + } + + // midday + static public double Midday(double date, double longitude) + { + return AsLocalTime(date + TwelveHours, longitude) - AsDayFraction(longitude); + } + + private static double InitLongitude(double longitude) + { + return NormalizeLongitude(longitude + HalfCircleOfArc) - HalfCircleOfArc; + } + + // midday-in-tehran + static public double MiddayAtPersianObservationSite(double date) + { + return Midday(date, InitLongitude(52.5)); // 52.5 degrees east - longitude of UTC+3:30 which defines Iranian Standard Time + } + + private static double PeriodicTerm(double julianCenturies, int x, double y, double z) + { + return x * SinOfDegree(y + z * julianCenturies); + } + + private static double SumLongSequenceOfPeriodicTerms(double julianCenturies) + { + double sum = 0.0; + sum += PeriodicTerm(julianCenturies, 403406, 270.54861, 0.9287892); + sum += PeriodicTerm(julianCenturies, 195207, 340.19128, 35999.1376958); + sum += PeriodicTerm(julianCenturies, 119433, 63.91854, 35999.4089666); + sum += PeriodicTerm(julianCenturies, 112392, 331.2622, 35998.7287385); + sum += PeriodicTerm(julianCenturies, 3891, 317.843, 71998.20261); + sum += PeriodicTerm(julianCenturies, 2819, 86.631, 71998.4403); + sum += PeriodicTerm(julianCenturies, 1721, 240.052, 36000.35726); + sum += PeriodicTerm(julianCenturies, 660, 310.26, 71997.4812); + sum += PeriodicTerm(julianCenturies, 350, 247.23, 32964.4678); + sum += PeriodicTerm(julianCenturies, 334, 260.87, -19.441); + sum += PeriodicTerm(julianCenturies, 314, 297.82, 445267.1117); + sum += PeriodicTerm(julianCenturies, 268, 343.14, 45036.884); + sum += PeriodicTerm(julianCenturies, 242, 166.79, 3.1008); + sum += PeriodicTerm(julianCenturies, 234, 81.53, 22518.4434); + sum += PeriodicTerm(julianCenturies, 158, 3.5, -19.9739); + sum += PeriodicTerm(julianCenturies, 132, 132.75, 65928.9345); + sum += PeriodicTerm(julianCenturies, 129, 182.95, 9038.0293); + sum += PeriodicTerm(julianCenturies, 114, 162.03, 3034.7684); + sum += PeriodicTerm(julianCenturies, 99, 29.8, 33718.148); + sum += PeriodicTerm(julianCenturies, 93, 266.4, 3034.448); + sum += PeriodicTerm(julianCenturies, 86, 249.2, -2280.773); + sum += PeriodicTerm(julianCenturies, 78, 157.6, 29929.992); + sum += PeriodicTerm(julianCenturies, 72, 257.8, 31556.493); + sum += PeriodicTerm(julianCenturies, 68, 185.1, 149.588); + sum += PeriodicTerm(julianCenturies, 64, 69.9, 9037.75); + sum += PeriodicTerm(julianCenturies, 46, 8.0, 107997.405); + sum += PeriodicTerm(julianCenturies, 38, 197.1, -4444.176); + sum += PeriodicTerm(julianCenturies, 37, 250.4, 151.771); + sum += PeriodicTerm(julianCenturies, 32, 65.3, 67555.316); + sum += PeriodicTerm(julianCenturies, 29, 162.7, 31556.08); + sum += PeriodicTerm(julianCenturies, 28, 341.5, -4561.54); + sum += PeriodicTerm(julianCenturies, 27, 291.6, 107996.706); + sum += PeriodicTerm(julianCenturies, 27, 98.5, 1221.655); + sum += PeriodicTerm(julianCenturies, 25, 146.7, 62894.167); + sum += PeriodicTerm(julianCenturies, 24, 110.0, 31437.369); + sum += PeriodicTerm(julianCenturies, 21, 5.2, 14578.298); + sum += PeriodicTerm(julianCenturies, 21, 342.6, -31931.757); + sum += PeriodicTerm(julianCenturies, 20, 230.9, 34777.243); + sum += PeriodicTerm(julianCenturies, 18, 256.1, 1221.999); + sum += PeriodicTerm(julianCenturies, 17, 45.3, 62894.511); + sum += PeriodicTerm(julianCenturies, 14, 242.9, -4442.039); + sum += PeriodicTerm(julianCenturies, 13, 115.2, 107997.909); + sum += PeriodicTerm(julianCenturies, 13, 151.8, 119.066); + sum += PeriodicTerm(julianCenturies, 13, 285.3, 16859.071); + sum += PeriodicTerm(julianCenturies, 12, 53.3, -4.578); + sum += PeriodicTerm(julianCenturies, 10, 126.6, 26895.292); + sum += PeriodicTerm(julianCenturies, 10, 205.7, -39.127); + sum += PeriodicTerm(julianCenturies, 10, 85.9, 12297.536); + sum += PeriodicTerm(julianCenturies, 10, 146.1, 90073.778); + return sum; + } + + private static double Aberration(double julianCenturies) + { + return (0.0000974 * CosOfDegree(177.63 + (35999.01848 * julianCenturies))) - 0.005575; + } + + private static double Nutation(double julianCenturies) + { + double a = PolynomialSum(s_coefficientsA, julianCenturies); + double b = PolynomialSum(s_coefficientsB, julianCenturies); + return (-0.004778 * SinOfDegree(a)) - (0.0003667 * SinOfDegree(b)); + } + + static public double Compute(double time) + { + double julianCenturies = JulianCenturies(time); + double lambda = 282.7771834 + + (36000.76953744 * julianCenturies) + + (0.000005729577951308232 * SumLongSequenceOfPeriodicTerms(julianCenturies)); + + double longitude = lambda + Aberration(julianCenturies) + Nutation(julianCenturies); + return InitLongitude(longitude); + } + + static public double AsSeason(double longitude) + { + return (longitude < 0) ? (longitude + FullCircleOfArc) : longitude; + } + + private static double EstimatePrior(double longitude, double time) + { + double timeSunLastAtLongitude = time - (MeanSpeedOfSun * AsSeason(InitLongitude(Compute(time) - longitude))); + double longitudeErrorDelta = InitLongitude(Compute(timeSunLastAtLongitude) - longitude); + return Math.Min(time, timeSunLastAtLongitude - (MeanSpeedOfSun * longitudeErrorDelta)); + } + + // persian-new-year-on-or-before + // number of days is the absolute date. The absolute date is the number of days from January 1st, 1 A.D. + // 1/1/0001 is absolute date 1. + internal static long PersianNewYearOnOrBefore(long numberOfDays) + { + double date = (double)numberOfDays; + + double approx = EstimatePrior(LongitudeSpring, MiddayAtPersianObservationSite(date)); + long lowerBoundNewYearDay = (long)Math.Floor(approx) - 1; + long upperBoundNewYearDay = lowerBoundNewYearDay + 3; // estimate is generally within a day of the actual occurrance (at the limits, the error expands, since the calculations rely on the mean tropical year which changes...) + long day = lowerBoundNewYearDay; + for (; day != upperBoundNewYearDay; ++day) + { + double midday = MiddayAtPersianObservationSite((double)day); + double l = Compute(midday); + if ((LongitudeSpring <= l) && (l <= TwoDegreesAfterSpring)) + { + break; + } + } + Contract.Assert(day != upperBoundNewYearDay); + + return day - 1; + } + } +} diff --git a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs new file mode 100644 index 0000000000..4cb95fb8f1 --- /dev/null +++ b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs @@ -0,0 +1,339 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////// +// +// +// Purpose: This class implements a set of methods for retrieving +// character type information. Character type information is +// independent of culture and region. +// +// +//////////////////////////////////////////////////////////////////////////// + +using System; +using System.Threading; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Reflection; +using System.Security; +using System.Diagnostics.Contracts; + +namespace System.Globalization +{ + public static partial class CharUnicodeInfo + { + //--------------------------------------------------------------------// + // Internal Information // + //--------------------------------------------------------------------// + + // + // Native methods to access the Unicode category data tables in charinfo.nlp. + // + internal const char HIGH_SURROGATE_START = '\ud800'; + internal const char HIGH_SURROGATE_END = '\udbff'; + internal const char LOW_SURROGATE_START = '\udc00'; + internal const char LOW_SURROGATE_END = '\udfff'; + + internal const int UNICODE_CATEGORY_OFFSET = 0; + internal const int BIDI_CATEGORY_OFFSET = 1; + + + + // The starting codepoint for Unicode plane 1. Plane 1 contains 0x010000 ~ 0x01ffff. + internal const int UNICODE_PLANE01_START = 0x10000; + + + //////////////////////////////////////////////////////////////////////// + // + // Actions: + // Convert the BMP character or surrogate pointed by index to a UTF32 value. + // This is similar to Char.ConvertToUTF32, but the difference is that + // it does not throw exceptions when invalid surrogate characters are passed in. + // + // WARNING: since it doesn't throw an exception it CAN return a value + // in the surrogate range D800-DFFF, which are not legal unicode values. + // + //////////////////////////////////////////////////////////////////////// + + internal static int InternalConvertToUtf32(String s, int index) + { + Contract.Assert(s != null, "s != null"); + Contract.Assert(index >= 0 && index < s.Length, "index < s.Length"); + if (index < s.Length - 1) + { + int temp1 = (int)s[index] - HIGH_SURROGATE_START; + if (temp1 >= 0 && temp1 <= 0x3ff) + { + int temp2 = (int)s[index + 1] - LOW_SURROGATE_START; + if (temp2 >= 0 && temp2 <= 0x3ff) + { + // Convert the surrogate to UTF32 and get the result. + return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START); + } + } + } + return ((int)s[index]); + } + //////////////////////////////////////////////////////////////////////// + // + // Convert a character or a surrogate pair starting at index of string s + // to UTF32 value. + // + // Parameters: + // s The string + // index The starting index. It can point to a BMP character or + // a surrogate pair. + // len The length of the string. + // charLength [out] If the index points to a BMP char, charLength + // will be 1. If the index points to a surrogate pair, + // charLength will be 2. + // + // WARNING: since it doesn't throw an exception it CAN return a value + // in the surrogate range D800-DFFF, which are not legal unicode values. + // + // Returns: + // The UTF32 value + // + //////////////////////////////////////////////////////////////////////// + + internal static int InternalConvertToUtf32(String s, int index, out int charLength) + { + Contract.Assert(s != null, "s != null"); + Contract.Assert(s.Length > 0, "s.Length > 0"); + Contract.Assert(index >= 0 && index < s.Length, "index >= 0 && index < s.Length"); + charLength = 1; + if (index < s.Length - 1) + { + int temp1 = (int)s[index] - HIGH_SURROGATE_START; + if (temp1 >= 0 && temp1 <= 0x3ff) + { + int temp2 = (int)s[index + 1] - LOW_SURROGATE_START; + if (temp2 >= 0 && temp2 <= 0x3ff) + { + // Convert the surrogate to UTF32 and get the result. + charLength++; + return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START); + } + } + } + return ((int)s[index]); + } + + //////////////////////////////////////////////////////////////////////// + // + // IsWhiteSpace + // + // Determines if the given character is a white space character. + // + //////////////////////////////////////////////////////////////////////// + + internal static bool IsWhiteSpace(String s, int index) + { + Contract.Assert(s != null, "s!=null"); + Contract.Assert(index >= 0 && index < s.Length, "index >= 0 && index < s.Length"); + + UnicodeCategory uc = GetUnicodeCategory(s, index); + // In Unicode 3.0, U+2028 is the only character which is under the category "LineSeparator". + // And U+2029 is th eonly character which is under the category "ParagraphSeparator". + switch (uc) + { + case (UnicodeCategory.SpaceSeparator): + case (UnicodeCategory.LineSeparator): + case (UnicodeCategory.ParagraphSeparator): + return (true); + } + return (false); + } + + + internal static bool IsWhiteSpace(char c) + { + UnicodeCategory uc = GetUnicodeCategory(c); + // In Unicode 3.0, U+2028 is the only character which is under the category "LineSeparator". + // And U+2029 is th eonly character which is under the category "ParagraphSeparator". + switch (uc) + { + case (UnicodeCategory.SpaceSeparator): + case (UnicodeCategory.LineSeparator): + case (UnicodeCategory.ParagraphSeparator): + return (true); + } + + return (false); + } + + + // + // This is called by the public char and string, index versions + // + // Note that for ch in the range D800-DFFF we just treat it as any other non-numeric character + // + internal unsafe static double InternalGetNumericValue(int ch) + { + Contract.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range."); + // Get the level 2 item from the highest 12 bit (8 - 19) of ch. + ushort index = s_pNumericLevel1Index[ch >> 8]; + // Get the level 2 WORD offset from the 4 - 7 bit of ch. This provides the base offset of the level 3 table. + // The offset is referred to an float item in m_pNumericFloatData. + // Note that & has the lower precedence than addition, so don't forget the parathesis. + index = s_pNumericLevel1Index[index + ((ch >> 4) & 0x000f)]; + + fixed (ushort* pUshortPtr = &(s_pNumericLevel1Index[index])) + { + byte* pBytePtr = (byte*)pUshortPtr; + fixed (byte* pByteNum = s_pNumericValues) + { + double* pDouble = (double*)pByteNum; + return pDouble[pBytePtr[(ch & 0x000f)]]; + } + } + } + + + //////////////////////////////////////////////////////////////////////// + // + //Returns the numeric value associated with the character c. If the character is a fraction, + // the return value will not be an integer. If the character does not have a numeric value, the return value is -1. + // + //Returns: + // the numeric value for the specified Unicode character. If the character does not have a numeric value, the return value is -1. + //Arguments: + // ch a Unicode character + //Exceptions: + // ArgumentNullException + // ArgumentOutOfRangeException + // + //////////////////////////////////////////////////////////////////////// + + + public static double GetNumericValue(char ch) + { + return (InternalGetNumericValue(ch)); + } + + + public static double GetNumericValue(String s, int index) + { + if (s == null) + { + throw new ArgumentNullException("s"); + } + if (index < 0 || index >= s.Length) + { + throw new ArgumentOutOfRangeException("index", SR.ArgumentOutOfRange_Index); + } + Contract.EndContractBlock(); + return (InternalGetNumericValue(InternalConvertToUtf32(s, index))); + } + + public static UnicodeCategory GetUnicodeCategory(char ch) + { + return (InternalGetUnicodeCategory(ch)); + } + + public static UnicodeCategory GetUnicodeCategory(String s, int index) + { + if (s == null) + throw new ArgumentNullException("s"); + if (((uint)index) >= ((uint)s.Length)) + { + throw new ArgumentOutOfRangeException("index"); + } + Contract.EndContractBlock(); + return InternalGetUnicodeCategory(s, index); + } + + internal unsafe static UnicodeCategory InternalGetUnicodeCategory(int ch) + { + return ((UnicodeCategory)InternalGetCategoryValue(ch, UNICODE_CATEGORY_OFFSET)); + } + + + //////////////////////////////////////////////////////////////////////// + // + //Action: Returns the Unicode Category property for the character c. + //Returns: + // an value in UnicodeCategory enum + //Arguments: + // ch a Unicode character + //Exceptions: + // None + // + //Note that this API will return values for D800-DF00 surrogate halves. + // + //////////////////////////////////////////////////////////////////////// + + internal unsafe static byte InternalGetCategoryValue(int ch, int offset) + { + Contract.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range."); + // Get the level 2 item from the highest 12 bit (8 - 19) of ch. + ushort index = s_pCategoryLevel1Index[ch >> 8]; + // Get the level 2 WORD offset from the 4 - 7 bit of ch. This provides the base offset of the level 3 table. + // Note that & has the lower precedence than addition, so don't forget the parathesis. + index = s_pCategoryLevel1Index[index + ((ch >> 4) & 0x000f)]; + + fixed (ushort* pUshortPtr = &(s_pCategoryLevel1Index[index])) + { + byte* pBytePtr = (byte*)pUshortPtr; + // Get the result from the 0 -3 bit of ch. + byte valueIndex = pBytePtr[(ch & 0x000f)]; + byte uc = s_pCategoriesValue[valueIndex * 2 + offset]; + // + // Make sure that OtherNotAssigned is the last category in UnicodeCategory. + // If that changes, change the following assertion as well. + // + //Contract.Assert(uc >= 0 && uc <= UnicodeCategory.OtherNotAssigned, "Table returns incorrect Unicode category"); + return (uc); + } + } + + //////////////////////////////////////////////////////////////////////// + // + //Action: Returns the Unicode Category property for the character c. + //Returns: + // an value in UnicodeCategory enum + //Arguments: + // value a Unicode String + // index Index for the specified string. + //Exceptions: + // None + // + //////////////////////////////////////////////////////////////////////// + + internal static UnicodeCategory InternalGetUnicodeCategory(String value, int index) + { + Contract.Assert(value != null, "value can not be null"); + Contract.Assert(index < value.Length, "index < value.Length"); + + return (InternalGetUnicodeCategory(InternalConvertToUtf32(value, index))); + } + + //////////////////////////////////////////////////////////////////////// + // + // Get the Unicode category of the character starting at index. If the character is in BMP, charLength will return 1. + // If the character is a valid surrogate pair, charLength will return 2. + // + //////////////////////////////////////////////////////////////////////// + + internal static UnicodeCategory InternalGetUnicodeCategory(String str, int index, out int charLength) + { + Contract.Assert(str != null, "str can not be null"); + Contract.Assert(str.Length > 0, "str.Length > 0"); ; + Contract.Assert(index >= 0 && index < str.Length, "index >= 0 && index < str.Length"); + + return (InternalGetUnicodeCategory(InternalConvertToUtf32(str, index, out charLength))); + } + + internal static bool IsCombiningCategory(UnicodeCategory uc) + { + Contract.Assert(uc >= 0, "uc >= 0"); + return ( + uc == UnicodeCategory.NonSpacingMark || + uc == UnicodeCategory.SpacingCombiningMark || + uc == UnicodeCategory.EnclosingMark + ); + } + } +} diff --git a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs new file mode 100644 index 0000000000..7284cfd3bc --- /dev/null +++ b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs @@ -0,0 +1,1222 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; + +namespace System.Globalization +{ + public static partial class CharUnicodeInfo + { + // THE FOLLOWING DATA IS AUTO GENERATED BY GenUnicodeProp.pl SCRIPT UNDER THE TOOLS FOLDER + // PLEASE DON'T MODIFY BY HAND + + + // 12:4:4 index table of the Unicode cateogry data. + private static ushort[] s_pCategoryLevel1Index = new ushort[] + { + 0x1100, 0x1110, 0x1120, 0x1130, 0x1140, 0x1150, 0x1160, 0x1170, 0x1180, 0x1190, 0x11a0, 0x11b0, 0x11c0, 0x11d0, 0x11e0, 0x11f0, + 0x1200, 0x1210, 0x1220, 0x1230, 0x1240, 0x1210, 0x1250, 0x1260, 0x1270, 0x1280, 0x1290, 0x12a0, 0x12b0, 0x12c0, 0x12d0, 0x12e0, + 0x12f0, 0x1300, 0x1310, 0x1320, 0x1330, 0x1340, 0x1350, 0x1360, 0x1370, 0x1380, 0x1390, 0x13a0, 0x13b0, 0x13c0, 0x13d0, 0x13e0, + 0x13f0, 0x1400, 0x1410, 0x1420, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1430, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1440, + 0x1450, 0x1210, 0x1210, 0x1210, 0x1460, 0x1210, 0x1470, 0x1480, 0x1490, 0x14a0, 0x14b0, 0x14c0, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x14d0, 0x14e0, 0x14e0, 0x14e0, 0x14e0, 0x14e0, 0x14e0, 0x14e0, 0x14e0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x1210, 0x1500, 0x1510, 0x1520, 0x1530, 0x1540, 0x1550, + 0x1560, 0x1570, 0x1580, 0x1590, 0x15a0, 0x15b0, 0x1210, 0x15c0, 0x15d0, 0x15e0, 0x15f0, 0x1600, 0x1610, 0x1620, 0x1630, 0x1620, + 0x1640, 0x1650, 0x1660, 0x1670, 0x1680, 0x1690, 0x16a0, 0x16b0, 0x16c0, 0x1620, 0x16d0, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1210, 0x1210, 0x1210, 0x16e0, 0x16f0, 0x1700, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1710, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1210, 0x1210, 0x1720, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1210, 0x1210, 0x1730, 0x1740, 0x1620, 0x1620, 0x1620, 0x1750, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1760, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1770, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1780, 0x1790, 0x17a0, 0x17b0, 0x17c0, 0x17d0, 0x17e0, 0x17f0, 0x1370, 0x1370, 0x1800, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1810, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1820, 0x1620, + 0x1830, 0x1840, 0x1850, 0x1860, 0x1870, 0x1880, 0x1890, 0x18a0, 0x18b0, 0x18c0, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x18d0, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x18e0, 0x18f0, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, + 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1210, 0x1900, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1210, 0x1210, 0x1910, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1920, 0x1930, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, 0x1620, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x1940, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, + 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x14f0, 0x1940, + 0x1950, 0x1958, 0x1960, 0x1968, 0x1970, 0x1978, 0x1980, 0x1988, 0x1990, 0x1998, 0x19a0, 0x19a8, 0x19b0, 0x19b8, 0x19c0, 0x19c8, + 0x19d0, 0x19d0, 0x19d0, 0x19d8, 0x19e0, 0x19d0, 0x19d0, 0x19e8, 0x19f0, 0x19f8, 0x1a00, 0x1a08, 0x1a10, 0x1a18, 0x19d0, 0x1a20, + 0x19d0, 0x19d0, 0x19d0, 0x1a28, 0x1a30, 0x19c0, 0x19c0, 0x19c0, 0x19c0, 0x1a38, 0x19c0, 0x1a40, 0x1a48, 0x1a50, 0x1a58, 0x1a60, + 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a70, 0x1a78, 0x1a80, 0x1a88, 0x19c0, 0x1a90, 0x1a98, 0x19d0, 0x1aa0, + 0x19b0, 0x19b0, 0x19b0, 0x19c0, 0x19c0, 0x19c0, 0x19d0, 0x19d0, 0x1aa8, 0x19d0, 0x19d0, 0x19d0, 0x1ab0, 0x19d0, 0x19d0, 0x19d0, + 0x19d0, 0x19d0, 0x19d0, 0x1ab8, 0x19b0, 0x1ac0, 0x1ac8, 0x19c0, 0x1ad0, 0x1ad8, 0x1a68, 0x1ae0, 0x1ae8, 0x1af0, 0x1af8, 0x1b00, + 0x1b08, 0x1b10, 0x1b18, 0x1b18, 0x1b20, 0x1a68, 0x1b28, 0x1b30, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b38, 0x1b40, 0x1b48, + 0x1b50, 0x1b58, 0x1b18, 0x1a68, 0x1b60, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b68, 0x1b70, 0x1b78, 0x1af0, 0x1b80, 0x1b88, + 0x1af0, 0x1b90, 0x1b98, 0x1ba0, 0x1af0, 0x1ba8, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1b18, 0x1bb8, 0x1bb0, 0x1bb0, 0x1bc0, 0x1a68, + 0x1bc8, 0x1bd0, 0x1bd0, 0x1bd8, 0x1be0, 0x1be8, 0x1bf0, 0x1bf8, 0x1c00, 0x1c08, 0x1c10, 0x1c18, 0x1c20, 0x1c28, 0x1c30, 0x1c38, + 0x1c40, 0x1c08, 0x1c10, 0x1c48, 0x1c50, 0x1c58, 0x1c60, 0x1c68, 0x1c70, 0x1c78, 0x1c10, 0x1c80, 0x1c88, 0x1c90, 0x1c30, 0x1c98, + 0x1ca0, 0x1c08, 0x1c10, 0x1ca8, 0x1cb0, 0x1cb8, 0x1c30, 0x1cc0, 0x1cc8, 0x1cd0, 0x1cd8, 0x1ce0, 0x1ce8, 0x1cf0, 0x1c60, 0x1cf8, + 0x1d00, 0x1d08, 0x1c10, 0x1d10, 0x1d18, 0x1d20, 0x1c30, 0x1d28, 0x1d30, 0x1d08, 0x1c10, 0x1d38, 0x1d40, 0x1d48, 0x1c30, 0x1d50, + 0x1d30, 0x1d08, 0x1bd0, 0x1d58, 0x1d60, 0x1d68, 0x1c30, 0x1d70, 0x1d78, 0x1d80, 0x1bd0, 0x1d88, 0x1d90, 0x1d98, 0x1c60, 0x1da0, + 0x1da8, 0x1bd0, 0x1bd0, 0x1db0, 0x1db8, 0x1dc0, 0x1bb0, 0x1bb0, 0x1dc8, 0x1dd0, 0x1dd8, 0x1de0, 0x1de8, 0x1df0, 0x1bb0, 0x1bb0, + 0x1df8, 0x1e00, 0x1e08, 0x1e10, 0x1e18, 0x1bd0, 0x1e20, 0x1e28, 0x1e30, 0x1e38, 0x1a68, 0x1e40, 0x1e48, 0x1e50, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1e58, 0x1e60, 0x1e68, 0x1e70, 0x1e78, 0x1e80, 0x1e88, 0x1e90, 0x19b0, 0x19b0, 0x1e98, 0x1bd0, 0x1bd0, 0x1ea0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1ea8, 0x1eb0, 0x1bd0, 0x1bd0, 0x1ea8, 0x1bd0, 0x1bd0, 0x1eb8, 0x1ec0, 0x1ec8, 0x1bd0, 0x1bd0, + 0x1bd0, 0x1ec0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1ed0, 0x1ed8, 0x1ee0, 0x1bd0, 0x1ee8, 0x19b0, 0x19b0, 0x19b0, 0x19b0, 0x19b0, 0x1ef0, + 0x1ef8, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1f00, 0x1bd0, 0x1f08, 0x1f10, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1f18, 0x1f20, + 0x1f28, 0x1f30, 0x1bd0, 0x1f38, 0x1bd0, 0x1f40, 0x1f28, 0x1f48, 0x1bd0, 0x1bd0, 0x1bd0, 0x1f50, 0x1f58, 0x1f60, 0x1f68, 0x1f70, + 0x1f78, 0x1f68, 0x1bd0, 0x1bd0, 0x1f80, 0x1bd0, 0x1bd0, 0x1f88, 0x1bd0, 0x1bd0, 0x1f90, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1f98, + 0x1bd0, 0x1fa0, 0x1fa8, 0x1fb0, 0x1fb8, 0x1bd0, 0x1fc0, 0x1fc8, 0x1bd0, 0x1bd0, 0x1fd0, 0x1bd0, 0x1fd8, 0x1fe0, 0x1fe8, 0x1fe8, + 0x1bd0, 0x1ff0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1ff8, 0x2000, 0x2008, 0x1f68, 0x1f68, 0x2010, 0x2018, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x2020, 0x1bd0, 0x1bd0, 0x2028, 0x2030, 0x1e68, 0x2038, 0x2040, 0x2048, 0x1bd0, 0x2050, 0x2058, 0x1bd0, 0x1bd0, 0x2060, 0x2068, + 0x1bd0, 0x1bd0, 0x2070, 0x2078, 0x2080, 0x2058, 0x1bd0, 0x2088, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x2090, 0x2098, 0x20a0, 0x20a8, + 0x19c0, 0x19c0, 0x20b0, 0x20b8, 0x20b8, 0x20b8, 0x20c0, 0x20c8, 0x19c0, 0x20d0, 0x20b8, 0x20b8, 0x1a68, 0x1a68, 0x1a68, 0x20d8, + 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x20e0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, + 0x20e8, 0x20f0, 0x20e8, 0x20e8, 0x20f0, 0x20f8, 0x20e8, 0x2100, 0x2108, 0x2108, 0x2108, 0x2110, 0x2118, 0x2120, 0x2128, 0x2130, + 0x2138, 0x2140, 0x2148, 0x2150, 0x2158, 0x2160, 0x2168, 0x2170, 0x2178, 0x2180, 0x2188, 0x2190, 0x1bb0, 0x2198, 0x21a0, 0x21a8, + 0x21b0, 0x21b8, 0x21c0, 0x21c8, 0x21d0, 0x21d8, 0x21e0, 0x21e0, 0x21e8, 0x21f0, 0x21f8, 0x1fe8, 0x2200, 0x2208, 0x1fe8, 0x2210, + 0x2218, 0x2220, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, + 0x2228, 0x1fe8, 0x2230, 0x2238, 0x2240, 0x2240, 0x2240, 0x2248, 0x1fe8, 0x2250, 0x2218, 0x2258, 0x1fe8, 0x2260, 0x2268, 0x2270, + 0x1fe8, 0x1fe8, 0x2278, 0x1bb0, 0x2270, 0x1bb0, 0x21d8, 0x21d8, 0x2280, 0x2288, 0x2240, 0x2240, 0x2240, 0x2240, 0x2290, 0x21d8, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x2298, 0x22a0, 0x1fe8, 0x1fe8, 0x22a8, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x22b0, 0x1fe8, 0x1fe8, 0x1fe8, 0x22b8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x22c0, 0x22c8, 0x21d8, 0x22d0, 0x1fe8, 0x1fe8, 0x22d8, 0x2218, 0x22e0, 0x2218, + 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, + 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x22e8, 0x22f0, 0x2218, 0x2218, 0x2218, 0x22f8, 0x2218, 0x2300, + 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, 0x2218, + 0x1fe8, 0x1fe8, 0x1fe8, 0x2218, 0x2308, 0x1fe8, 0x1fe8, 0x2310, 0x1fe8, 0x2318, 0x1fe8, 0x2320, 0x2328, 0x2330, 0x2338, 0x1bb0, + 0x19b0, 0x19b0, 0x2340, 0x19c0, 0x19c0, 0x2348, 0x2350, 0x2358, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x19d0, 0x2360, 0x2368, + 0x19c0, 0x19c0, 0x2370, 0x1bd0, 0x1bd0, 0x1bd0, 0x2378, 0x2380, 0x1bd0, 0x2388, 0x2390, 0x2390, 0x2390, 0x2390, 0x1a68, 0x1a68, + 0x2398, 0x23a0, 0x23a8, 0x23b0, 0x23b8, 0x1bb0, 0x1bb0, 0x1bb0, 0x1fe8, 0x23c0, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x23c8, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x23d0, 0x1bb0, 0x23d8, + 0x23e0, 0x23e8, 0x23f0, 0x23f8, 0x1da8, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x2400, 0x1ef8, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x2408, + 0x2410, 0x1bd0, 0x1fc0, 0x1da8, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1fa0, 0x2418, 0x1bd0, 0x2420, 0x1fe8, 0x1fe8, 0x23c8, 0x1bd0, + 0x2240, 0x2428, 0x2430, 0x2240, 0x2438, 0x2440, 0x2240, 0x2448, 0x2430, 0x2240, 0x2240, 0x2450, 0x2458, 0x2240, 0x2240, 0x2460, + 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2468, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2470, 0x2240, 0x2478, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1f98, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1f98, 0x1bb0, 0x1bb0, + 0x1bd0, 0x2480, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1e20, 0x1fe8, 0x1fe8, 0x1fe8, 0x2278, 0x1bd0, 0x1bd0, 0x2088, + 0x2488, 0x1bd0, 0x2490, 0x1bb0, 0x19d0, 0x19d0, 0x2498, 0x24a0, 0x19d0, 0x24a8, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x24b0, 0x24b8, + 0x1a60, 0x24c0, 0x24c8, 0x24d0, 0x19d0, 0x19d0, 0x19d0, 0x24d8, 0x24e0, 0x24e8, 0x24f0, 0x24f8, 0x1bb0, 0x1bb0, 0x1bb0, 0x2500, + 0x2508, 0x1bd0, 0x2510, 0x2518, 0x1bd0, 0x1bd0, 0x1bd0, 0x2520, 0x2528, 0x1bd0, 0x1bd0, 0x2530, 0x2538, 0x1f68, 0x1a68, 0x2540, + 0x2058, 0x1bd0, 0x2548, 0x1bd0, 0x2550, 0x2558, 0x1bd0, 0x1e20, 0x1bc8, 0x1bd0, 0x1bd0, 0x2560, 0x2568, 0x2570, 0x2578, 0x2580, + 0x1bd0, 0x1bd0, 0x2588, 0x2590, 0x2598, 0x25a0, 0x1bd0, 0x25a8, 0x1bd0, 0x1bd0, 0x1bd0, 0x25b0, 0x25b8, 0x25c0, 0x25c8, 0x25d0, + 0x25d8, 0x25e0, 0x2390, 0x19c0, 0x19c0, 0x25e8, 0x25f0, 0x19c0, 0x19c0, 0x19c0, 0x19c0, 0x19c0, 0x1bd0, 0x1bd0, 0x25f8, 0x1f68, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x2600, 0x1bd0, 0x2608, 0x1bd0, 0x1bd0, 0x1fd0, + 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, 0x2610, + 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1fc0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1fd8, 0x1bb0, 0x1bb0, + 0x2620, 0x2628, 0x2630, 0x2638, 0x2640, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x2648, 0x2650, 0x2658, 0x1b18, 0x1b18, + 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, + 0x1b18, 0x1b18, 0x1b18, 0x2660, 0x1bb0, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x2668, 0x1b18, 0x1b18, 0x2670, 0x1bb0, 0x1bb0, 0x2678, + 0x1a68, 0x2680, 0x1a68, 0x2688, 0x2690, 0x2698, 0x26a0, 0x26a8, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x1b18, 0x26b0, + 0x26b8, 0x1968, 0x1970, 0x1978, 0x1980, 0x26c0, 0x26c8, 0x26d0, 0x1bd0, 0x26d8, 0x1bd0, 0x1fa0, 0x26e0, 0x26e8, 0x26f0, 0x26f8, + 0x2700, 0x1bd0, 0x1ec8, 0x2708, 0x1fc0, 0x1fc0, 0x1bb0, 0x1bb0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x2420, + 0x2710, 0x2718, 0x2718, 0x2720, 0x2728, 0x2728, 0x2728, 0x2730, 0x2738, 0x23d8, 0x2740, 0x1bb0, 0x1bb0, 0x2240, 0x2240, 0x2748, + 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bd0, 0x1e20, 0x1bd0, 0x1bd0, 0x1bd0, 0x1c90, 0x2750, 0x2758, + 0x1bd0, 0x1bd0, 0x2760, 0x1bd0, 0x2768, 0x1bd0, 0x1bd0, 0x2770, 0x1bd0, 0x2778, 0x1bd0, 0x1bd0, 0x2780, 0x2788, 0x1bb0, 0x1bb0, + 0x19b0, 0x19b0, 0x2790, 0x19c0, 0x19c0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1fc0, 0x1f68, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1f88, 0x1bd0, 0x1bd0, 0x1bd0, 0x2798, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x2388, 0x1bd0, 0x1f98, 0x1f88, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x27a0, 0x1af0, 0x1af0, 0x27a8, 0x1af0, 0x27b0, 0x1af0, 0x27b8, 0x1af0, 0x27c0, 0x27c8, 0x1bb0, 0x1bb0, 0x1bb0, 0x1af0, 0x27d0, + 0x1af0, 0x27d8, 0x1af0, 0x27e0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1af0, 0x1af0, 0x1af0, 0x27e8, 0x27f0, 0x27f8, 0x27f0, 0x27f0, + 0x2800, 0x2808, 0x1af0, 0x2810, 0x2818, 0x2820, 0x1af0, 0x2828, 0x1af0, 0x2830, 0x1bb0, 0x1bb0, 0x2838, 0x1af0, 0x2840, 0x2848, + 0x1af0, 0x1af0, 0x1af0, 0x2850, 0x1af0, 0x2858, 0x1af0, 0x2860, 0x1af0, 0x2868, 0x2870, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x2878, 0x1bb0, 0x1bb0, 0x1bb0, 0x2880, 0x2880, 0x2880, 0x2888, 0x2890, 0x2890, 0x2890, 0x2898, + 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x28a0, 0x28a8, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x28b0, 0x1bd0, 0x1bd0, 0x28b8, 0x28c0, 0x28c8, 0x28d0, 0x28d8, 0x2048, 0x1bd0, 0x1bd0, 0x28e0, 0x28e8, 0x1bd0, 0x28f0, 0x1f68, + 0x28f8, 0x1bd0, 0x2900, 0x2908, 0x2910, 0x1bd0, 0x1bd0, 0x2918, 0x2048, 0x1bd0, 0x1bd0, 0x2920, 0x2928, 0x2930, 0x2938, 0x2940, + 0x1bd0, 0x1c78, 0x2948, 0x2950, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x2958, 0x2960, 0x2968, 0x1bd0, 0x1bd0, 0x2970, 0x2978, 0x1f68, + 0x2980, 0x1c08, 0x1c10, 0x1c80, 0x2988, 0x2990, 0x2998, 0x29a0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bd0, 0x1bd0, 0x1bd0, 0x29a8, 0x29b0, 0x1f68, 0x1bb0, 0x1bb0, + 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bd0, 0x1bd0, 0x29b8, 0x29c0, 0x29c8, 0x29d0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x29d8, 0x29e0, 0x1f68, 0x1bb0, 0x1bb0, 0x1bd0, 0x1bd0, 0x29e8, 0x29f0, 0x1f68, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x29f8, 0x2a00, 0x2a08, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x19b0, 0x19b0, 0x19c0, 0x19c0, 0x1e08, 0x2a10, + 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bd0, 0x1bd0, 0x1bd0, 0x28f0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1fd8, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x21e0, 0x21e0, 0x21e0, 0x21e0, 0x21e0, 0x21e0, 0x2a18, 0x2a20, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x2600, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1fa0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x2388, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x28f0, 0x1bd0, 0x1fa0, 0x2570, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bd0, 0x1fc0, 0x2a28, + 0x1bd0, 0x1bd0, 0x1bd0, 0x2a30, 0x2a38, 0x2a40, 0x2a48, 0x2a50, 0x1bd0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1fc8, 0x2a58, 0x2a60, 0x2a68, 0x28d8, 0x2a70, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x2a78, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x2420, 0x1e20, 0x28f0, 0x2a80, 0x2a88, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2240, 0x2a90, + 0x2240, 0x2240, 0x2a98, 0x2240, 0x2240, 0x2240, 0x2aa0, 0x2aa8, 0x2ab0, 0x2240, 0x2ab8, 0x2240, 0x2240, 0x2240, 0x2ac0, 0x1bb0, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x2ac8, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x2278, 0x2718, 0x2ad0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x19b0, 0x2ad8, 0x19c0, 0x2ae0, 0x2ae8, 0x2af0, 0x20e8, 0x19b0, 0x2af8, 0x2b00, 0x2b08, 0x2b10, 0x2b18, 0x19b0, 0x2ad8, 0x19c0, + 0x2b20, 0x2b28, 0x19c0, 0x2b30, 0x2b38, 0x2b40, 0x2b48, 0x19b0, 0x2b50, 0x19c0, 0x19b0, 0x2ad8, 0x19c0, 0x2ae0, 0x2ae8, 0x19c0, + 0x20e8, 0x19b0, 0x2af8, 0x2b48, 0x19b0, 0x2b50, 0x19c0, 0x19b0, 0x2ad8, 0x19c0, 0x2b58, 0x19b0, 0x2b60, 0x2b68, 0x2b70, 0x2b78, + 0x19c0, 0x2b80, 0x19b0, 0x2b88, 0x2b90, 0x2b98, 0x2ba0, 0x19c0, 0x2ba8, 0x19b0, 0x2bb0, 0x19c0, 0x2bb8, 0x2bc0, 0x2bc0, 0x2bc0, + 0x1a68, 0x1a68, 0x1a68, 0x2bc8, 0x1a68, 0x1a68, 0x2bd0, 0x2bd8, 0x2be0, 0x2be8, 0x1ad8, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x1af0, 0x2bf0, 0x2bf8, 0x1bb0, 0x1bb0, + 0x2c00, 0x1b18, 0x2c08, 0x2c10, 0x2c18, 0x2c20, 0x2c28, 0x2c30, 0x2c38, 0x2c40, 0x2c48, 0x2c40, 0x1bb0, 0x1bb0, 0x1bb0, 0x2c50, + 0x1fe8, 0x1fe8, 0x23d8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x23c8, 0x2c58, 0x2c60, 0x2c60, 0x2c60, 0x1fe8, 0x23d0, + 0x2c68, 0x2240, 0x2460, 0x2240, 0x2240, 0x2240, 0x2c70, 0x2240, 0x2240, 0x2c78, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x2c80, 0x2240, + 0x2c88, 0x2240, 0x2240, 0x2c78, 0x2ac0, 0x2c90, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x2c98, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x23c0, 0x1fe8, 0x1fe8, 0x2ca0, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x2740, 0x2ca8, 0x23c8, + 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x23c8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x1fe8, 0x2cb0, 0x1bb0, 0x1bb0, + 0x23d8, 0x1fe8, 0x1fe8, 0x1fe8, 0x2cb8, 0x1ee8, 0x1fe8, 0x1fe8, 0x2cb8, 0x1fe8, 0x2cc0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bb0, 0x2cc8, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x2cb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x2740, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x2388, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1fc8, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, + 0x1bd0, 0x1fc0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, + 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x1bd0, 0x2a78, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1bd0, 0x1fc0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x2cd0, 0x1bb0, 0x2cd8, 0x2cd8, 0x2cd8, 0x2cd8, 0x2cd8, 0x2cd8, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, 0x1bb0, + 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1a68, 0x1bb0, + 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2618, 0x2ce0, + 0x0101, 0x0101, 0x0101, 0x0101, 0x0201, 0x0203, 0x0304, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0303, 0x0203, + 0x0605, 0x0706, 0x0708, 0x0606, 0x0a09, 0x0b06, 0x0d0c, 0x0c0c, 0x0e0e, 0x0e0e, 0x0e0e, 0x0e0e, 0x0e0e, 0x060c, 0x0f0f, 0x060f, + 0x1006, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x0910, 0x0a06, 0x1211, + 0x1311, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x0913, 0x0a0f, 0x010f, + 0x0101, 0x0101, 0x0301, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0614, 0x0808, 0x0808, 0x0615, 0x1511, 0x1716, 0x180f, 0x1115, 0x1a19, 0x1b1b, 0x1311, 0x0606, 0x1b11, 0x1c16, 0x1d1d, 0x061d, + 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x0f10, 0x1010, 0x1010, 0x1010, 0x1310, + 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x0f13, 0x1313, 0x1313, 0x1313, 0x1313, + 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1013, 0x1013, 0x1013, 0x1013, + 0x1013, 0x1013, 0x1013, 0x1013, 0x1313, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1010, 0x1013, 0x1013, 0x1313, + 0x1013, 0x1310, 0x1310, 0x1010, 0x1013, 0x1010, 0x1313, 0x1010, 0x1010, 0x1013, 0x1310, 0x1010, 0x1310, 0x1313, 0x1010, 0x1013, + 0x1310, 0x1310, 0x1310, 0x1010, 0x1013, 0x1313, 0x1310, 0x1010, 0x1013, 0x1010, 0x1013, 0x1013, 0x1310, 0x1613, 0x1310, 0x1313, + 0x1616, 0x1616, 0x1e10, 0x1013, 0x131e, 0x1e10, 0x1013, 0x1013, 0x1013, 0x1013, 0x1013, 0x1013, 0x1013, 0x1013, 0x1313, 0x1310, + 0x1013, 0x131e, 0x1310, 0x1010, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1313, 0x1313, 0x1313, 0x1010, 0x1013, 0x1310, + 0x1013, 0x1013, 0x1010, 0x1310, 0x1310, 0x1310, 0x1310, 0x1310, 0x1313, 0x1313, 0x1316, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, + 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x201f, 0x1f20, 0x1f1f, 0x1f1f, 0x1f1f, 0x1111, 0x1111, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, + 0x1f1f, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1f1f, 0x1f1f, 0x111f, 0x1111, 0x1111, 0x1111, 0x1120, 0x111f, + 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, + 0x1310, 0x1310, 0x1120, 0x1310, 0x0000, 0x131f, 0x1313, 0x1006, 0x0000, 0x0000, 0x1111, 0x0610, 0x1010, 0x0010, 0x0010, 0x1010, + 0x1013, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1000, 0x1010, 0x1010, 0x1010, 0x1010, 0x1313, 0x1313, + 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1013, 0x1313, 0x1010, 0x1310, 0x1313, 0x1310, 0x1310, 0x1310, 0x1310, + 0x1313, 0x1313, 0x1310, 0x100f, 0x1013, 0x1310, 0x1013, 0x1010, 0x1310, 0x2122, 0x2121, 0x2121, 0x2323, 0x1310, 0x1310, 0x1310, + 0x1010, 0x1013, 0x1013, 0x1013, 0x1013, 0x1013, 0x1013, 0x1313, 0x1000, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, + 0x1010, 0x1010, 0x1010, 0x0010, 0x1f00, 0x2424, 0x2424, 0x2424, 0x1300, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, + 0x1313, 0x1313, 0x1313, 0x1313, 0x2400, 0x0025, 0x1500, 0x0815, 0x2100, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, + 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2126, 0x2127, 0x2721, 0x2121, 0x2127, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x0028, 0x0000, 0x0000, + 0x2828, 0x2728, 0x0027, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2929, 0x2929, 0x2929, 0x0f0f, 0x072a, 0x2b07, 0x2c0c, 0x1515, + 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2c21, 0x002d, 0x2c2c, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, + 0x2e2f, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x212e, 0x2121, 0x2121, 0x3030, 0x3030, 0x3030, 0x3030, 0x3030, 0x3107, 0x2c31, 0x2e2e, + 0x2e21, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2c, 0x2121, 0x2121, 0x2121, 0x2921, 0x2115, + 0x2121, 0x2121, 0x2f21, 0x212f, 0x1521, 0x2121, 0x2121, 0x2e2e, 0x0e0e, 0x0e0e, 0x0e0e, 0x0e0e, 0x0e0e, 0x2e2e, 0x322e, 0x2e32, + 0x2c2c, 0x2c2c, 0x2c2c, 0x2c2c, 0x2c2c, 0x2c2c, 0x2c2c, 0x2d00, 0x212e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, + 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x0021, 0x2e00, 0x2e2e, 0x2e2e, 0x2e2e, 0x2e2e, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, + 0x2e21, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x2828, 0x2828, 0x2828, + 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2128, 0x2121, 0x2121, 0x2121, 0x2121, 0x3434, 0x0615, 0x0606, 0x0034, 0x0000, 0x0000, + 0x2828, 0x2828, 0x2828, 0x2121, 0x2121, 0x2134, 0x2121, 0x2121, 0x2121, 0x2121, 0x2134, 0x2121, 0x2134, 0x2121, 0x2121, 0x0000, + 0x2727, 0x2727, 0x2727, 0x2727, 0x2727, 0x2727, 0x2727, 0x0027, 0x2828, 0x2828, 0x2828, 0x2828, 0x2128, 0x2121, 0x0000, 0x0027, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2e2e, 0x2e2e, 0x002e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2100, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x3521, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x3521, 0x1621, 0x3535, + 0x2135, 0x2121, 0x2121, 0x2121, 0x3521, 0x3535, 0x2135, 0x3535, 0x2116, 0x2121, 0x2121, 0x2121, 0x1616, 0x1616, 0x1616, 0x1616, + 0x1616, 0x2121, 0x2424, 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x1f24, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x2116, 0x3535, 0x1600, 0x1616, 0x1616, 0x1616, 0x0016, 0x1600, 0x0016, 0x1600, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x1616, 0x1616, 0x1616, 0x1616, 0x0016, 0x1616, 0x1616, 0x1616, 0x0016, 0x0016, 0x0000, 0x1616, 0x1616, 0x0000, 0x1621, 0x3535, + 0x2135, 0x2121, 0x0021, 0x3500, 0x0035, 0x3500, 0x2135, 0x0016, 0x0000, 0x0000, 0x0000, 0x3500, 0x0000, 0x0000, 0x1616, 0x1600, + 0x1616, 0x2121, 0x0000, 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x1616, 0x0808, 0x3737, 0x3737, 0x3737, 0x0822, 0x0000, 0x0000, + 0x2100, 0x3521, 0x1600, 0x1616, 0x1616, 0x0016, 0x0000, 0x1600, 0x0016, 0x1616, 0x1600, 0x0016, 0x1616, 0x0000, 0x0021, 0x3535, + 0x2135, 0x0021, 0x0000, 0x2100, 0x0021, 0x2100, 0x2121, 0x0000, 0x2100, 0x0000, 0x0000, 0x0000, 0x1600, 0x1616, 0x0016, 0x0016, + 0x0000, 0x0000, 0x0000, 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x2121, 0x1616, 0x2116, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2100, 0x3521, 0x1600, 0x1616, 0x1616, 0x1616, 0x1616, 0x1600, 0x1616, 0x1600, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x0016, 0x1616, 0x1600, 0x1616, 0x1616, 0x0000, 0x1621, 0x3535, 0x2135, 0x2121, 0x2121, 0x2100, 0x3521, 0x3500, 0x2135, 0x0000, + 0x0016, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0824, 0x0000, 0x0000, 0x0000, 0x1600, 0x0000, 0x0000, 0x0000, + 0x2100, 0x3535, 0x1600, 0x1616, 0x1616, 0x1616, 0x0016, 0x1600, 0x0016, 0x1616, 0x1600, 0x1616, 0x1616, 0x0000, 0x1621, 0x2135, + 0x2135, 0x2121, 0x0021, 0x3500, 0x0035, 0x3500, 0x2135, 0x0000, 0x0000, 0x0000, 0x0000, 0x3521, 0x0000, 0x0000, 0x1616, 0x1600, + 0x1622, 0x3737, 0x3737, 0x3737, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1621, 0x1600, 0x1616, 0x1616, 0x0016, 0x0000, 0x1616, + 0x0016, 0x1616, 0x1616, 0x0000, 0x1600, 0x0016, 0x0016, 0x1616, 0x0000, 0x1600, 0x0016, 0x0000, 0x1616, 0x0016, 0x0000, 0x1616, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0000, 0x0000, 0x3535, 0x3521, 0x0035, 0x0000, 0x3535, 0x0035, 0x3535, 0x2135, 0x0000, + 0x0016, 0x0000, 0x0000, 0x3500, 0x0000, 0x0000, 0x0000, 0x0000, 0x3737, 0x1537, 0x1515, 0x1515, 0x0815, 0x0015, 0x0000, 0x0000, + 0x3521, 0x3535, 0x1600, 0x1616, 0x1616, 0x1616, 0x0016, 0x1616, 0x0016, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0000, 0x1600, 0x2121, 0x3521, 0x3535, 0x0035, 0x2121, 0x0021, 0x2121, 0x2121, 0x0000, + 0x0000, 0x0000, 0x2100, 0x0021, 0x1616, 0x0016, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1d1d, 0x1d1d, 0x1d1d, 0x221d, + 0x2100, 0x3535, 0x1600, 0x1616, 0x1616, 0x1616, 0x0016, 0x1616, 0x1616, 0x1616, 0x1600, 0x1616, 0x1616, 0x0000, 0x1621, 0x3835, + 0x3535, 0x3535, 0x0035, 0x3538, 0x0035, 0x3535, 0x2121, 0x0000, 0x0000, 0x0000, 0x3500, 0x0035, 0x0000, 0x0000, 0x0000, 0x0016, + 0x1600, 0x0016, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0016, 0x1600, 0x3535, + 0x2135, 0x2121, 0x0021, 0x3535, 0x0035, 0x3535, 0x2135, 0x0016, 0x0000, 0x0000, 0x0000, 0x3500, 0x0000, 0x0000, 0x0000, 0x1600, + 0x3737, 0x3737, 0x3737, 0x0000, 0x2200, 0x1616, 0x1616, 0x1616, 0x0000, 0x3535, 0x1600, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x1616, 0x1616, 0x1616, 0x0016, 0x0000, 0x1616, 0x1616, 0x1616, 0x1616, 0x1600, 0x1616, 0x1616, 0x1616, 0x1616, 0x1600, 0x0000, + 0x1616, 0x1616, 0x1616, 0x0016, 0x0000, 0x0021, 0x0000, 0x3500, 0x3535, 0x2121, 0x0021, 0x0021, 0x3535, 0x3535, 0x3535, 0x3535, + 0x0000, 0x3535, 0x0024, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1600, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x2116, 0x1616, 0x2121, 0x2121, 0x2121, 0x0021, 0x0000, 0x0800, 0x1616, 0x1616, 0x1616, 0x211f, 0x2121, 0x2121, 0x2121, 0x2421, + 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x2424, 0x0000, 0x0000, 0x1600, 0x0016, 0x0016, 0x1600, 0x0016, 0x0016, 0x1600, 0x0000, + 0x0000, 0x0000, 0x1616, 0x1616, 0x1600, 0x1616, 0x1616, 0x1616, 0x1600, 0x1616, 0x1600, 0x1600, 0x0000, 0x1616, 0x1600, 0x1616, + 0x2116, 0x1616, 0x2121, 0x2121, 0x2121, 0x2100, 0x1621, 0x0000, 0x1616, 0x1616, 0x0016, 0x001f, 0x2121, 0x2121, 0x2121, 0x0000, + 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x0000, 0x1616, 0x1616, 0x2216, 0x2222, 0x2424, 0x2424, 0x2424, 0x2424, 0x2424, 0x2424, + 0x2424, 0x2224, 0x2224, 0x2222, 0x2121, 0x2222, 0x2222, 0x2222, 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x3737, 0x3737, 0x3737, + 0x3737, 0x3737, 0x2122, 0x2122, 0x2122, 0x0a09, 0x0a09, 0x3535, 0x1616, 0x1616, 0x1616, 0x1616, 0x1600, 0x1616, 0x1616, 0x1616, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0016, 0x0000, 0x2100, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x3521, + 0x2121, 0x2121, 0x2421, 0x2121, 0x1616, 0x1616, 0x2116, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2100, 0x2121, 0x2121, 0x2121, + 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x0021, 0x2222, 0x2222, 0x2222, 0x2222, 0x2221, 0x2222, 0x2222, 0x0022, 0x2222, + 0x2424, 0x2424, 0x2224, 0x2222, 0x2422, 0x0024, 0x0000, 0x0000, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x3516, 0x2135, 0x2121, + 0x3521, 0x2121, 0x2121, 0x2121, 0x2135, 0x3521, 0x2135, 0x1621, 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x2424, 0x2424, 0x2424, + 0x1616, 0x1616, 0x1616, 0x3535, 0x2121, 0x1616, 0x1616, 0x2121, 0x1621, 0x3535, 0x1635, 0x3516, 0x3535, 0x3535, 0x3535, 0x1616, + 0x2116, 0x2121, 0x1621, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x3521, 0x2135, 0x3521, 0x3535, 0x3535, 0x2135, 0x3516, + 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x3535, 0x2135, 0x2222, 0x1010, 0x1010, 0x1010, 0x1000, 0x0000, 0x0000, 0x1000, 0x0000, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x2416, 0x161f, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0016, 0x1616, 0x1616, 0x0000, + 0x1616, 0x1616, 0x1616, 0x0016, 0x0016, 0x1616, 0x1616, 0x0000, 0x0016, 0x1616, 0x1616, 0x0000, 0x1616, 0x1616, 0x1616, 0x0016, + 0x0016, 0x1616, 0x1616, 0x0000, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0016, 0x1616, 0x1616, 0x1616, 0x1616, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0016, 0x2100, 0x2121, 0x2424, 0x2424, 0x2424, 0x2424, 0x3724, 0x3737, 0x3737, 0x3737, + 0x3737, 0x3737, 0x3737, 0x3737, 0x3737, 0x3737, 0x0037, 0x0000, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x0000, 0x0000, 0x0000, + 0x1010, 0x1010, 0x1010, 0x0000, 0x1313, 0x1313, 0x1313, 0x0000, 0x1625, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x2416, 0x1624, 0x1605, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0916, 0x000a, 0x0000, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x2416, 0x2424, 0x3939, + 0x1639, 0x1616, 0x1616, 0x1616, 0x0016, 0x0000, 0x0000, 0x0000, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0016, 0x1616, + 0x1616, 0x2121, 0x0021, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1616, 0x2121, 0x2421, 0x0024, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1616, 0x2121, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0016, 0x2121, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1616, 0x1616, 0x2121, 0x2135, 0x2121, 0x2121, 0x2121, 0x3535, 0x3535, 0x3535, 0x3535, 0x3521, 0x2135, 0x2121, 0x2121, 0x2121, + 0x2121, 0x2121, 0x2424, 0x1f24, 0x2424, 0x0824, 0x2116, 0x0000, 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x0000, 0x0000, 0x0000, + 0x1d1d, 0x1d1d, 0x1d1d, 0x1d1d, 0x1d1d, 0x0000, 0x0000, 0x0000, 0x0606, 0x0606, 0x0606, 0x0625, 0x0606, 0x2106, 0x2121, 0x0018, + 0x1616, 0x1f16, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1616, 0x1616, 0x1616, 0x1616, 0x2116, 0x0016, 0x0000, 0x0000, 0x1616, 0x1616, 0x1616, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0016, 0x2121, 0x3521, 0x3535, 0x2135, 0x3521, 0x3535, 0x0000, 0x0000, + 0x3535, 0x3521, 0x3535, 0x3535, 0x2135, 0x2121, 0x0000, 0x0000, 0x0015, 0x0000, 0x0606, 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0000, 0x1616, 0x1616, 0x0016, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0000, 0x0000, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x0000, 0x0000, 0x0000, + 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x0037, 0x0000, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, + 0x1616, 0x1616, 0x1616, 0x2116, 0x3521, 0x2135, 0x0000, 0x2424, 0x1616, 0x1616, 0x3516, 0x3521, 0x2121, 0x2121, 0x2121, 0x0021, + 0x3521, 0x3521, 0x2135, 0x2121, 0x2121, 0x2121, 0x3521, 0x3535, 0x3535, 0x2135, 0x2121, 0x2121, 0x2121, 0x2121, 0x0021, 0x2100, + 0x2424, 0x2424, 0x2424, 0x1f24, 0x2424, 0x2424, 0x2424, 0x0000, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x0023, + 0x2121, 0x2121, 0x1635, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x3521, 0x2121, 0x2121, 0x3521, 0x3521, 0x3535, + 0x3535, 0x3521, 0x1635, 0x1616, 0x1616, 0x1616, 0x0000, 0x0000, 0x2224, 0x2222, 0x2222, 0x2222, 0x2222, 0x2122, 0x2121, 0x2121, + 0x2121, 0x2121, 0x2222, 0x2222, 0x2222, 0x2222, 0x0022, 0x0000, 0x2121, 0x1635, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, + 0x3516, 0x2121, 0x2121, 0x3535, 0x2121, 0x2135, 0x2121, 0x1616, 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x1616, 0x1616, 0x1616, + 0x1616, 0x1616, 0x1616, 0x3521, 0x2121, 0x3535, 0x2135, 0x2135, 0x2121, 0x3535, 0x0000, 0x0000, 0x0000, 0x0000, 0x2424, 0x2424, + 0x1616, 0x1616, 0x3535, 0x3535, 0x3535, 0x3535, 0x2121, 0x2121, 0x2121, 0x2121, 0x3535, 0x2121, 0x0000, 0x2400, 0x2424, 0x2424, + 0x3636, 0x3636, 0x3636, 0x3636, 0x3636, 0x0000, 0x1600, 0x1616, 0x1616, 0x1616, 0x1616, 0x1616, 0x1f1f, 0x1f1f, 0x1f1f, 0x2424, + 0x2424, 0x2424, 0x2424, 0x2424, 0x0000, 0x0000, 0x0000, 0x0000, 0x2121, 0x2421, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, + 0x3521, 0x2121, 0x2121, 0x2121, 0x1621, 0x1616, 0x2116, 0x1616, 0x1616, 0x3535, 0x1621, 0x0016, 0x2121, 0x0000, 0x0000, 0x0000, + 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, + 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x131f, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x131f, 0x1313, 0x1313, 0x1313, + 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1f13, 0x1f1f, 0x1f1f, 0x2121, 0x2121, 0x2121, 0x0000, 0x0000, 0x0000, 0x2121, 0x2121, + 0x1310, 0x1310, 0x1310, 0x1313, 0x1313, 0x1313, 0x1313, 0x1310, 0x1313, 0x1313, 0x1313, 0x1313, 0x1010, 0x1010, 0x1010, 0x1010, + 0x1313, 0x1313, 0x1313, 0x0000, 0x1010, 0x1010, 0x1010, 0x0000, 0x1313, 0x1313, 0x1313, 0x1313, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x1313, 0x0000, 0x1313, 0x1313, 0x1313, 0x1313, 0x1e1e, 0x1e1e, 0x1e1e, 0x1e1e, + 0x1313, 0x1313, 0x0013, 0x1313, 0x1010, 0x1010, 0x111e, 0x1113, 0x1111, 0x1313, 0x0013, 0x1313, 0x1010, 0x1010, 0x111e, 0x1111, + 0x1313, 0x1313, 0x0000, 0x1313, 0x1010, 0x1010, 0x1100, 0x1111, 0x1313, 0x1313, 0x1313, 0x1313, 0x1010, 0x1010, 0x1110, 0x1111, + 0x0000, 0x1313, 0x0013, 0x1313, 0x1010, 0x1010, 0x111e, 0x0011, 0x0505, 0x0505, 0x0505, 0x0505, 0x0505, 0x1805, 0x1818, 0x3b3a, + 0x2525, 0x2525, 0x2525, 0x0606, 0x1c17, 0x1709, 0x1c17, 0x1709, 0x0606, 0x0606, 0x0606, 0x0606, 0x3d3c, 0x3f3e, 0x4140, 0x1442, + 0x0707, 0x0707, 0x0607, 0x0606, 0x1706, 0x061c, 0x0606, 0x1206, 0x0612, 0x0606, 0x0943, 0x060a, 0x0606, 0x0606, 0x0606, 0x0606, + 0x0606, 0x060f, 0x0612, 0x0606, 0x0606, 0x0606, 0x0606, 0x0506, 0x1818, 0x1818, 0x0018, 0x4544, 0x4746, 0x1818, 0x1818, 0x1818, + 0x1f1b, 0x0000, 0x1b1b, 0x1b1b, 0x1b1b, 0x0b0b, 0x090f, 0x1f0a, 0x1b1b, 0x1b1b, 0x1b1b, 0x1b1b, 0x1b1b, 0x0b0b, 0x090f, 0x000a, + 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x001f, 0x0000, 0x0808, 0x0808, 0x0808, 0x0808, 0x0808, 0x0808, 0x0808, 0x0808, + 0x0808, 0x0808, 0x0808, 0x0808, 0x0808, 0x0808, 0x0808, 0x0008, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x2321, 0x2323, + 0x2123, 0x2323, 0x2123, 0x2121, 0x2121, 0x2121, 0x2121, 0x2121, 0x0021, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1515, 0x1510, 0x1515, 0x1015, 0x1515, 0x1013, 0x1010, 0x1313, 0x1010, 0x1310, 0x1015, 0x1515, 0x100f, 0x1010, 0x1010, 0x1515, + 0x1515, 0x1515, 0x1510, 0x1510, 0x1510, 0x1010, 0x1010, 0x1319, 0x1010, 0x1010, 0x1613, 0x1616, 0x1316, 0x1515, 0x1313, 0x1010, + 0x0f0f, 0x0f0f, 0x100f, 0x1313, 0x1313, 0x0f15, 0x1515, 0x2213, 0x1d1d, 0x1d1d, 0x1d1d, 0x1d1d, 0x1d1d, 0x1d1d, 0x1d1d, 0x1d1d, + 0x3939, 0x3939, 0x3939, 0x3939, 0x3939, 0x3939, 0x3939, 0x3939, 0x3939, 0x1039, 0x3913, 0x3939, 0x1d39, 0x1515, 0x0000, 0x0000, + 0x0f0f, 0x0f0f, 0x150f, 0x1515, 0x1515, 0x0f0f, 0x1515, 0x1515, 0x150f, 0x0f15, 0x1515, 0x150f, 0x1515, 0x1515, 0x1515, 0x150f, + 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x0f0f, 0x1515, 0x150f, 0x150f, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, + 0x1515, 0x1515, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, + 0x0f0f, 0x1a0b, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x1515, 0x1515, 0x1515, 0x1515, 0x0a09, 0x0a09, 0x1515, 0x1515, + 0x0f0f, 0x1515, 0x1515, 0x1515, 0x0915, 0x150a, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x1522, 0x150f, 0x1515, + 0x1515, 0x1515, 0x2215, 0x1515, 0x1515, 0x0f15, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, + 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x0f0f, 0x0f0f, 0x0f0f, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, + 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x0015, 0x0000, 0x0000, 0x1515, 0x1515, 0x1515, 0x0015, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1d1d, 0x1d1d, 0x1d1d, 0x1d1d, 0x1b1b, 0x1b1b, 0x1b1b, 0x1b1b, 0x1b1b, 0x1b1b, 0x1b1b, 0x1b1b, 0x1b1b, 0x1b1b, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x1d1d, 0x1d1d, 0x1d1d, 0x1515, 0x1515, 0x1515, 0x0f15, 0x1515, 0x1515, 0x1515, 0x1515, + 0x0f15, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, + 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x0f15, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1515, 0x1522, 0x1515, |