using System.Text;
namespace Renci.SshNet.Common
{
    /// 
    /// Implementation of ASCII Encoding
    /// 
    public class ASCIIEncoding : Encoding
    {
        private readonly char _fallbackChar;
        private static readonly char[] _byteToChar;
        static ASCIIEncoding()
        {
            if (_byteToChar == null)
            {
                _byteToChar = new char[128];
                var ch = '\0';
                for (byte i = 0; i < 128; i++)
                {
                    _byteToChar[i] = ch++;
                }
            }
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        public ASCIIEncoding()
        {
            this._fallbackChar = '?';
        }
        /// 
        /// Calculates the number of bytes produced by encoding a set of characters from the specified character array.
        /// 
        /// The character array containing the set of characters to encode.
        /// The index of the first character to encode.
        /// The number of characters to encode.
        /// 
        /// The number of bytes produced by encoding the specified characters.
        /// 
        /// 
        ///    is null. 
        ///   
        /// 
        ///    or  is less than zero.-or-  and  do not denote a valid range in . 
        ///   
        /// A fallback occurred (see Understanding Encodings for complete explanation)-and- is set to .
        public override int GetByteCount(char[] chars, int index, int count)
        {
            return count;
        }
        /// 
        /// Encodes a set of characters from the specified character array into the specified byte array.
        /// 
        /// The character array containing the set of characters to encode.
        /// The index of the first character to encode.
        /// The number of characters to encode.
        /// The byte array to contain the resulting sequence of bytes.
        /// The index at which to start writing the resulting sequence of bytes.
        /// 
        /// The actual number of bytes written into .
        /// 
        /// 
        ///    is null.-or-  is null. 
        ///   
        /// 
        ///    or  or  is less than zero.-or-  and  do not denote a valid range in .-or-  is not a valid index in . 
        ///   
        /// 
        ///    does not have enough capacity from  to the end of the array to accommodate the resulting bytes. 
        ///   
        /// A fallback occurred (see Understanding Encodings for complete explanation)-and- is set to .
        public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
        {
            for (int i = 0; i < charCount && i < chars.Length; i++)
            {
                var b = (byte)chars[i + charIndex];
                if (b > 127)
                    b = (byte)this._fallbackChar;
                bytes[i + byteIndex] = b;
            }
            return charCount;
        }
        /// 
        /// Calculates the number of characters produced by decoding a sequence of bytes from the specified byte array.
        /// 
        /// The byte array containing the sequence of bytes to decode.
        /// The index of the first byte to decode.
        /// The number of bytes to decode.
        /// 
        /// The number of characters produced by decoding the specified sequence of bytes.
        /// 
        /// 
        ///    is null. 
        ///   
        /// 
        ///    or  is less than zero.-or-  and  do not denote a valid range in . 
        ///   
        /// A fallback occurred (see Understanding Encodings for complete explanation)-and- is set to .
        public override int GetCharCount(byte[] bytes, int index, int count)
        {
            return count;
        }
        /// 
        /// Decodes a sequence of bytes from the specified byte array into the specified character array.
        /// 
        /// The byte array containing the sequence of bytes to decode.
        /// The index of the first byte to decode.
        /// The number of bytes to decode.
        /// The character array to contain the resulting set of characters.
        /// The index at which to start writing the resulting set of characters.
        /// 
        /// The actual number of characters written into .
        /// 
        /// 
        ///    is null.-or-  is null. 
        ///   
        /// 
        ///    or  or  is less than zero.-or-  and  do not denote a valid range in .-or-  is not a valid index in . 
        ///   
        /// 
        ///    does not have enough capacity from  to the end of the array to accommodate the resulting characters. 
        ///   
        /// A fallback occurred (see Understanding Encodings for complete explanation)-and- is set to .
        public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
        {
            for (int i = 0; i < byteCount; i++)
            {
                var b = bytes[i + byteIndex];
                char ch;
                if (b > 127)
                {
                    ch = this._fallbackChar;
                }
                else 
                {
                    ch = _byteToChar[b];
                }
                chars[i + charIndex] = ch;
            }
            return byteCount;
        }
        /// 
        /// Calculates the maximum number of bytes produced by encoding the specified number of characters.
        /// 
        /// The number of characters to encode.
        /// 
        /// The maximum number of bytes produced by encoding the specified number of characters.
        /// 
        /// 
        ///    is less than zero. 
        ///   
        /// A fallback occurred (see Understanding Encodings for complete explanation)-and- is set to .
        public override int GetMaxByteCount(int charCount)
        {
            return charCount;
        }
        /// 
        /// Calculates the maximum number of characters produced by decoding the specified number of bytes.
        /// 
        /// The number of bytes to decode.
        /// 
        /// The maximum number of characters produced by decoding the specified number of bytes.
        /// 
        /// 
        ///    is less than zero. 
        ///   
        /// A fallback occurred (see Understanding Encodings for complete explanation)-and- is set to .
        public override int GetMaxCharCount(int byteCount)
        {
            return byteCount;
        }
    }
}