The Labs \ Source Viewer \ SSCLI \ System.Text \ DecoderNLS

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System.Text
  16. {
  17.     using System.Runtime.Serialization;
  18.     using System.Security.Permissions;
  19.     using System.Text;
  20.     using System;
  21.     // A Decoder is used to decode a sequence of blocks of bytes into a
  22.     // sequence of blocks of characters. Following instantiation of a decoder,
  23.     // sequential blocks of bytes are converted into blocks of characters through
  24.     // calls to the GetChars method. The decoder maintains state between the
  25.     // conversions, allowing it to correctly decode byte sequences that span
  26.     // adjacent blocks.
  27.     //
  28.     // Instances of specific implementations of the Decoder abstract base
  29.     // class are typically obtained through calls to the GetDecoder method
  30.     // of Encoding objects.
  31.     //
  32.    
  33.     [Serializable()]
  34.     internal class DecoderNLS : Decoder, ISerializable
  35.     {
  36.         // Remember our encoding
  37.         protected Encoding m_encoding;
  38.         [NonSerialized()]
  39.         protected bool m_mustFlush;
  40.         [NonSerialized()]
  41.         internal bool m_throwOnOverflow;
  42.         [NonSerialized()]
  43.         internal int m_bytesUsed;
  44.        
  45.         #region Serialization
  46.        
  47.         // Constructor called by serialization. called during deserialization.
  48.         internal DecoderNLS(SerializationInfo info, StreamingContext context)
  49.         {
  50.             throw new NotSupportedException(String.Format(System.Globalization.CultureInfo.CurrentCulture, Environment.GetResourceString("NotSupported_TypeCannotDeserialized"), this.GetType()));
  51.         }
  52.        
  53.         // ISerializable implementation. called during serialization.
  54.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
  55.         void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
  56.         {
  57.             SerializeDecoder(info);
  58.             info.AddValue("encoding", this.m_encoding);
  59.             info.SetType(typeof(Encoding.DefaultDecoder));
  60.         }
  61.        
  62.         #endregion Serialization
  63.        
  64.         internal DecoderNLS(Encoding encoding)
  65.         {
  66.             this.m_encoding = encoding;
  67.             this.m_fallback = this.m_encoding.DecoderFallback;
  68.             this.Reset();
  69.         }
  70.        
  71.         // This is used by our child deserializers
  72.         internal DecoderNLS()
  73.         {
  74.             this.m_encoding = null;
  75.             this.Reset();
  76.         }
  77.        
  78.         public override void Reset()
  79.         {
  80.             if (m_fallbackBuffer != null)
  81.                 m_fallbackBuffer.Reset();
  82.         }
  83.        
  84.         unsafe public override int GetCharCount(byte[] bytes, int index, int count)
  85.         {
  86.             return GetCharCount(bytes, index, count, false);
  87.         }
  88.        
  89.         unsafe public override int GetCharCount(byte[] bytes, int index, int count, bool flush)
  90.         {
  91.             // Validate Parameters
  92.             if (bytes == null)
  93.                 throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
  94.            
  95.             if (index < 0 || count < 0)
  96.                 throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  97.            
  98.             if (bytes.Length - index < count)
  99.                 throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
  100.            
  101.            
  102.             // Avoid null fixed problem
  103.             if (bytes.Length == 0)
  104.                 bytes = new byte[1];
  105.            
  106.             // Just call pointer version
  107.             fixed (byte* pBytes = bytes)
  108.                 return GetCharCount(pBytes + index, count, flush);
  109.         }
  110.        
  111.         unsafe public override int GetCharCount(byte* bytes, int count, bool flush)
  112.         {
  113.             // Validate parameters
  114.             if (bytes == null)
  115.                 throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
  116.            
  117.             if (count < 0)
  118.                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  119.            
  120.             // Remember the flush
  121.             this.m_mustFlush = flush;
  122.             this.m_throwOnOverflow = true;
  123.            
  124.             // By default just call the encoding version, no flush by default
  125.             return m_encoding.GetCharCount(bytes, count, this);
  126.         }
  127.        
  128.         unsafe public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
  129.         {
  130.             return GetChars(bytes, byteIndex, byteCount, chars, charIndex, false);
  131.         }
  132.        
  133.         unsafe public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, bool flush)
  134.         {
  135.             // Validate Parameters
  136.             if (bytes == null || chars == null)
  137.                 throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
  138.            
  139.             if (byteIndex < 0 || byteCount < 0)
  140.                 throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  141.            
  142.             if (bytes.Length - byteIndex < byteCount)
  143.                 throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
  144.            
  145.             if (charIndex < 0 || charIndex > chars.Length)
  146.                 throw new ArgumentOutOfRangeException("charIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
  147.            
  148.            
  149.             // Avoid empty input fixed problem
  150.             if (bytes.Length == 0)
  151.                 bytes = new byte[1];
  152.            
  153.             int charCount = chars.Length - charIndex;
  154.             if (chars.Length == 0)
  155.                 chars = new char[1];
  156.            
  157.             // Just call pointer version
  158.             fixed (byte* pBytes = bytes)
  159.                 fixed (char* pChars = chars)
  160.                 // Remember that charCount is # to decode, not size of array
  161.                     return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, flush);
  162.         }
  163.        
  164.         unsafe public override int GetChars(byte* bytes, int byteCount, char* chars, int charCount, bool flush)
  165.         {
  166.             // Validate parameters
  167.             if (chars == null || bytes == null)
  168.                 throw new ArgumentNullException((chars == null ? "chars" : "bytes"), Environment.GetResourceString("ArgumentNull_Array"));
  169.            
  170.             if (byteCount < 0 || charCount < 0)
  171.                 throw new ArgumentOutOfRangeException((byteCount < 0 ? "byteCount" : "charCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  172.            
  173.             // Remember our flush
  174.             m_mustFlush = flush;
  175.             m_throwOnOverflow = true;
  176.            
  177.             // By default just call the encoding's version
  178.             return m_encoding.GetChars(bytes, byteCount, chars, charCount, this);
  179.         }
  180.        
  181.         // This method is used when the output buffer might not be big enough.
  182.         // Just call the pointer version. (This gets chars)
  183.         unsafe public override void Convert(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed
  184.         )
  185.         {
  186.             // Validate parameters
  187.             if (bytes == null || chars == null)
  188.                 throw new ArgumentNullException((bytes == null ? "bytes" : "chars"), Environment.GetResourceString("ArgumentNull_Array"));
  189.            
  190.             if (byteIndex < 0 || byteCount < 0)
  191.                 throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  192.            
  193.             if (charIndex < 0 || charCount < 0)
  194.                 throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  195.            
  196.             if (bytes.Length - byteIndex < byteCount)
  197.                 throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
  198.            
  199.             if (chars.Length - charIndex < charCount)
  200.                 throw new ArgumentOutOfRangeException("chars", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
  201.            
  202.            
  203.             // Avoid empty input problem
  204.             if (bytes.Length == 0)
  205.                 bytes = new byte[1];
  206.             if (chars.Length == 0)
  207.                 chars = new char[1];
  208.            
  209.             // Just call the pointer version (public overrides can't do this)
  210.             fixed (byte* pBytes = bytes) {
  211.                 fixed (char* pChars = chars) {
  212.                     Convert(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, flush, out bytesUsed, out charsUsed, out completed);
  213.                 }
  214.             }
  215.         }
  216.        
  217.         // This is the version that used pointers. We call the base encoding worker function
  218.         // after setting our appropriate internal variables. This is getting chars
  219.         unsafe public override void Convert(byte* bytes, int byteCount, char* chars, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed)
  220.         {
  221.             // Validate input parameters
  222.             if (chars == null || bytes == null)
  223.                 throw new ArgumentNullException(chars == null ? "chars" : "bytes", Environment.GetResourceString("ArgumentNull_Array"));
  224.            
  225.             if (byteCount < 0 || charCount < 0)
  226.                 throw new ArgumentOutOfRangeException((byteCount < 0 ? "byteCount" : "charCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  227.            
  228.             // We don't want to throw
  229.             this.m_mustFlush = flush;
  230.             this.m_throwOnOverflow = false;
  231.             this.m_bytesUsed = 0;
  232.            
  233.             // Do conversion
  234.             charsUsed = this.m_encoding.GetChars(bytes, byteCount, chars, charCount, this);
  235.             bytesUsed = this.m_bytesUsed;
  236.            
  237.             // Its completed if they've used what they wanted AND if they didn't want flush or if we are flushed
  238.             completed = (bytesUsed == byteCount) && (!flush || !this.HasState) && (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0);
  239.            
  240.             // Our data thingys are now full, we can return
  241.         }
  242.        
  243.         public bool MustFlush {
  244.             get { return m_mustFlush; }
  245.         }
  246.        
  247.         // Anything left in our decoder?
  248.         internal virtual bool HasState {
  249.             get { return false; }
  250.         }
  251.        
  252.         // Allow encoding to clear our must flush instead of throwing (in ThrowCharsOverflow)
  253.         internal void ClearMustFlush()
  254.         {
  255.             m_mustFlush = false;
  256.         }
  257.     }
  258. }

Developer Fusion