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

  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.    
  18.     using System;
  19.     using System.Collections;
  20.     using System.Runtime.Remoting;
  21.     using System.Globalization;
  22.     using System.Threading;
  23.     using Win32Native = Microsoft.Win32.Win32Native;
  24.    
  25.     // This class overrides Encoding with the things we need for our NLS Encodings
  26.     //
  27.     // All of the GetBytes/Chars GetByte/CharCount methods are just wrappers for the pointer
  28.     // plus decoder/encoder method that is our real workhorse. Note that this is an internal
  29.     // class, so our public classes cannot derive from this class. Because of this, all of the
  30.     // GetBytes/Chars GetByte/CharCount wrapper methods are duplicated in all of our public
  31.     // encodings, which currently include:
  32.     //
  33.     // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, & UnicodeEncoding
  34.     //
  35.     // So if you change the wrappers in this class, you must change the wrappers in the other classes
  36.     // as well because they should have the same behavior.
  37.     //
  38.     [System.Runtime.InteropServices.ComVisible(true)]
  39.     [Serializable()]
  40.     internal abstract class EncodingNLS : Encoding
  41.     {
  42.         protected EncodingNLS(int codePage) : base(codePage)
  43.         {
  44.         }
  45.        
  46.         // Returns the number of bytes required to encode a range of characters in
  47.         // a character array.
  48.         //
  49.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  50.         // So if you fix this, fix the others. Currently those include:
  51.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  52.         // parent method is safe
  53.         unsafe public override int GetByteCount(char[] chars, int index, int count)
  54.         {
  55.             // Validate input parameters
  56.             if (chars == null)
  57.                 throw new ArgumentNullException("chars", Environment.GetResourceString("ArgumentNull_Array"));
  58.            
  59.             if (index < 0 || count < 0)
  60.                 throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  61.            
  62.             if (chars.Length - index < count)
  63.                 throw new ArgumentOutOfRangeException("chars", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
  64.            
  65.             // If no input, return 0, avoid fixed empty array problem
  66.             if (chars.Length == 0)
  67.                 return 0;
  68.            
  69.             // Just call the pointer version
  70.             fixed (char* pChars = chars)
  71.                 return GetByteCount(pChars + index, count, null);
  72.         }
  73.        
  74.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  75.         // So if you fix this, fix the others. Currently those include:
  76.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  77.         // parent method is safe
  78.         unsafe public override int GetByteCount(string s)
  79.         {
  80.             // Validate input
  81.             if (s == null)
  82.                 throw new ArgumentNullException("s");
  83.            
  84.             fixed (char* pChars = s)
  85.                 return GetByteCount(pChars, s.Length, null);
  86.         }
  87.        
  88.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  89.         // So if you fix this, fix the others. Currently those include:
  90.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  91.         unsafe public override int GetByteCount(char* chars, int count)
  92.         {
  93.             // Validate Parameters
  94.             if (chars == null)
  95.                 throw new ArgumentNullException("chars", Environment.GetResourceString("ArgumentNull_Array"));
  96.            
  97.             if (count < 0)
  98.                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  99.            
  100.             // Call it with empty encoder
  101.             return GetByteCount(chars, count, null);
  102.         }
  103.        
  104.         // Parent method is safe.
  105.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  106.         // So if you fix this, fix the others. Currently those include:
  107.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  108.         unsafe public override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex)
  109.         {
  110.             if (s == null || bytes == null)
  111.                 throw new ArgumentNullException((s == null ? "s" : "bytes"), Environment.GetResourceString("ArgumentNull_Array"));
  112.            
  113.             if (charIndex < 0 || charCount < 0)
  114.                 throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  115.            
  116.             if (s.Length - charIndex < charCount)
  117.                 throw new ArgumentOutOfRangeException("s", Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
  118.            
  119.             if (byteIndex < 0 || byteIndex > bytes.Length)
  120.                 throw new ArgumentOutOfRangeException("byteIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
  121.            
  122.             int byteCount = bytes.Length - byteIndex;
  123.            
  124.             // Fixed doesn't like empty arrays
  125.             if (bytes.Length == 0)
  126.                 bytes = new byte[1];
  127.            
  128.             fixed (char* pChars = s)
  129.                 fixed (byte* pBytes = bytes)
  130.                     return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
  131.         }
  132.        
  133.         // Encodes a range of characters in a character array into a range of bytes
  134.         // in a byte array. An exception occurs if the byte array is not large
  135.         // enough to hold the complete encoding of the characters. The
  136.         // GetByteCount method can be used to determine the exact number of
  137.         // bytes that will be produced for a given range of characters.
  138.         // Alternatively, the GetMaxByteCount method can be used to
  139.         // determine the maximum number of bytes that will be produced for a given
  140.         // number of characters, regardless of the actual character values.
  141.         //
  142.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  143.         // So if you fix this, fix the others. Currently those include:
  144.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  145.         // parent method is safe
  146.         unsafe public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
  147.         {
  148.             // Validate parameters
  149.             if (chars == null || bytes == null)
  150.                 throw new ArgumentNullException((chars == null ? "chars" : "bytes"), Environment.GetResourceString("ArgumentNull_Array"));
  151.            
  152.             if (charIndex < 0 || charCount < 0)
  153.                 throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  154.            
  155.             if (chars.Length - charIndex < charCount)
  156.                 throw new ArgumentOutOfRangeException("chars", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
  157.            
  158.             if (byteIndex < 0 || byteIndex > bytes.Length)
  159.                 throw new ArgumentOutOfRangeException("byteIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
  160.            
  161.             // If nothing to encode return 0, avoid fixed problem
  162.             if (chars.Length == 0)
  163.                 return 0;
  164.            
  165.             // Just call pointer version
  166.             int byteCount = bytes.Length - byteIndex;
  167.            
  168.             // Fixed doesn't like empty arrays
  169.             if (bytes.Length == 0)
  170.                 bytes = new byte[1];
  171.            
  172.             fixed (char* pChars = chars)
  173.                 fixed (byte* pBytes = bytes)
  174.                 // Remember that byteCount is # to decode, not size of array.
  175.                     return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
  176.         }
  177.        
  178.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  179.         // So if you fix this, fix the others. Currently those include:
  180.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  181.         unsafe public override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
  182.         {
  183.             // Validate Parameters
  184.             if (bytes == null || chars == null)
  185.                 throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
  186.            
  187.             if (charCount < 0 || byteCount < 0)
  188.                 throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  189.            
  190.             return GetBytes(chars, charCount, bytes, byteCount, null);
  191.         }
  192.        
  193.         // Returns the number of characters produced by decoding a range of bytes
  194.         // in a byte array.
  195.         //
  196.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  197.         // So if you fix this, fix the others. Currently those include:
  198.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  199.         // parent method is safe
  200.         unsafe public override int GetCharCount(byte[] bytes, int index, int count)
  201.         {
  202.             // Validate Parameters
  203.             if (bytes == null)
  204.                 throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
  205.            
  206.             if (index < 0 || count < 0)
  207.                 throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  208.            
  209.             if (bytes.Length - index < count)
  210.                 throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
  211.            
  212.             // If no input just return 0, fixed doesn't like 0 length arrays
  213.             if (bytes.Length == 0)
  214.                 return 0;
  215.            
  216.             // Just call pointer version
  217.             fixed (byte* pBytes = bytes)
  218.                 return GetCharCount(pBytes + index, count, null);
  219.         }
  220.        
  221.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  222.         // So if you fix this, fix the others. Currently those include:
  223.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  224.         unsafe public override int GetCharCount(byte* bytes, int count)
  225.         {
  226.             // Validate Parameters
  227.             if (bytes == null)
  228.                 throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
  229.            
  230.             if (count < 0)
  231.                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  232.            
  233.             return GetCharCount(bytes, count, null);
  234.         }
  235.        
  236.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  237.         // So if you fix this, fix the others. Currently those include:
  238.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  239.         // parent method is safe
  240.         unsafe public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
  241.         {
  242.             // Validate Parameters
  243.             if (bytes == null || chars == null)
  244.                 throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
  245.            
  246.             if (byteIndex < 0 || byteCount < 0)
  247.                 throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  248.            
  249.             if (bytes.Length - byteIndex < byteCount)
  250.                 throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
  251.            
  252.             if (charIndex < 0 || charIndex > chars.Length)
  253.                 throw new ArgumentOutOfRangeException("charIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
  254.            
  255.             // If no input, return 0 & avoid fixed problem
  256.             if (bytes.Length == 0)
  257.                 return 0;
  258.            
  259.             // Just call pointer version
  260.             int charCount = chars.Length - charIndex;
  261.            
  262.             // Fixed doesn't like empty arrays
  263.             if (chars.Length == 0)
  264.                 chars = new char[1];
  265.            
  266.             fixed (byte* pBytes = bytes)
  267.                 fixed (char* pChars = chars)
  268.                 // Remember that charCount is # to decode, not size of array
  269.                     return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
  270.         }
  271.        
  272.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  273.         // So if you fix this, fix the others. Currently those include:
  274.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  275.         unsafe public override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
  276.         {
  277.             // Validate Parameters
  278.             if (bytes == null || chars == null)
  279.                 throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
  280.            
  281.             if (charCount < 0 || byteCount < 0)
  282.                 throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  283.            
  284.             return GetChars(bytes, byteCount, chars, charCount, null);
  285.         }
  286.        
  287.         // Returns a string containing the decoded representation of a range of
  288.         // bytes in a byte array.
  289.         //
  290.         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
  291.         // So if you fix this, fix the others. Currently those include:
  292.         // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
  293.         // parent method is safe
  294.         unsafe public override string GetString(byte[] bytes, int index, int count)
  295.         {
  296.             // Validate Parameters
  297.             if (bytes == null)
  298.                 throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
  299.            
  300.             if (index < 0 || count < 0)
  301.                 throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  302.            
  303.             if (bytes.Length - index < count)
  304.                 throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
  305.            
  306.             // Avoid problems with empty input buffer
  307.             if (bytes.Length == 0)
  308.                 return String.Empty;
  309.            
  310.             fixed (byte* pBytes = bytes)
  311.                 return String.CreateStringFromEncoding(pBytes + index, count, this);
  312.         }
  313.        
  314.         public override Decoder GetDecoder()
  315.         {
  316.             return new DecoderNLS(this);
  317.         }
  318.        
  319.         public override Encoder GetEncoder()
  320.         {
  321.             return new EncoderNLS(this);
  322.         }
  323.     }
  324. }

Developer Fusion