/// <summary>
        /// Binary data in the new hex format (>= 9.0), quoted.
        /// </summary>
        private static byte[] ByteArrayToByteaTextHexFormat(byte[] nativeData, StringEncodingInfo encodingInfo)
        {
            int i = 0;

            byte[] ret = new byte[
                (encodingInfo.UseEPrefix ? 1 : 0) + // E prefix
                (encodingInfo.Quote != 0 ? 2 : 0) + // quotes
                encodingInfo.ByteaEscape.Length +   // backslash[es]
                1 +                                 // x
                (nativeData.Length * 2)             // data
                         ];

            if (encodingInfo.Quote != 0)
            {
                if (encodingInfo.UseEPrefix)
                {
                    ret[i++] = (byte)ASCIIBytes.E;
                }

                ret[i++] = encodingInfo.Quote;
            }

            foreach (byte bs in encodingInfo.ByteaEscape)
            {
                ret[i++] = bs;
            }

            ret[i++] = (byte)ASCIIBytes.x;

            foreach (byte b in nativeData)
            {
                ret[i++] = hexEncodingByteMap[(b >> 4) & 0x0F];
                ret[i++] = hexEncodingByteMap[b & 0x0F];
            }

            if (encodingInfo.Quote != 0)
            {
                ret[i++] = encodingInfo.Quote;
            }

            return(ret);
        }
        static BasicNativeToBackendTypeConverter()
        {
            stringEncodingInfoTable = new StringEncodingInfo[16];

            // Hash value args: forExtendedQuery, UseConformantStrings, Supports_E_StringPrefix, arrayElement
            // Note that a combination of UseConformantStrings == true and Supports_E_StringPrefix == false is not possible,
            // so those combinations are left out of the table.
            stringEncodingInfoTable[StringEncodingInfoHash(true, true, true, false)]    = new StringEncodingInfo(0, "", "", "", true, false, backslashSingle);
            stringEncodingInfoTable[StringEncodingInfoHash(true, true, true, true)]     = new StringEncodingInfo((byte)ASCIIBytes.DoubleQuote, "", @"\", @"\", true, false, backslashDouble);
            stringEncodingInfoTable[StringEncodingInfoHash(true, false, false, false)]  = new StringEncodingInfo(0, "", "", "", false, false, backslashSingle);
            stringEncodingInfoTable[StringEncodingInfoHash(true, false, false, true)]   = new StringEncodingInfo((byte)ASCIIBytes.DoubleQuote, "", @"\", @"\", false, false, backslashDouble);
            stringEncodingInfoTable[StringEncodingInfoHash(true, false, true, false)]   = new StringEncodingInfo(0, "", "", "", false, false, backslashSingle);
            stringEncodingInfoTable[StringEncodingInfoHash(true, false, true, true)]    = new StringEncodingInfo((byte)ASCIIBytes.DoubleQuote, "", @"\", @"\", false, false, backslashDouble);
            stringEncodingInfoTable[StringEncodingInfoHash(false, true, true, false)]   = new StringEncodingInfo((byte)ASCIIBytes.SingleQuote, "'", "", "", true, false, backslashSingle);
            stringEncodingInfoTable[StringEncodingInfoHash(false, true, true, true)]    = new StringEncodingInfo((byte)ASCIIBytes.DoubleQuote, "'", @"\", @"\", true, false, backslashDouble);
            stringEncodingInfoTable[StringEncodingInfoHash(false, false, false, false)] = new StringEncodingInfo((byte)ASCIIBytes.SingleQuote, "'", "", @"\", false, false, backslashDouble);
            stringEncodingInfoTable[StringEncodingInfoHash(false, false, false, true)]  = new StringEncodingInfo((byte)ASCIIBytes.DoubleQuote, "'", @"\\", @"\\\", false, false, backslashQuad);
            stringEncodingInfoTable[StringEncodingInfoHash(false, false, true, false)]  = new StringEncodingInfo((byte)ASCIIBytes.SingleQuote, "'", "", @"\", false, true, backslashDouble);
            stringEncodingInfoTable[StringEncodingInfoHash(false, false, true, true)]   = new StringEncodingInfo((byte)ASCIIBytes.DoubleQuote, "'", @"\\", @"\\\", false, false, backslashQuad);
        }
        /// <summary>
        /// Binary data with possible older style octal escapes, quoted.
        /// </summary>
        private static byte[] ByteArrayToByteaTextEscaped(byte[] nativeData, StringEncodingInfo encodingInfo)
        {
            // Minimum length for output is input bytes + e-prefix + two quotes.
            MemoryStream ret = new MemoryStream(nativeData.Length + (encodingInfo.UseEPrefix ? 1 : 0) + (encodingInfo.Quote != 0 ? 2 : 0));

            if (encodingInfo.Quote != 0)
            {
                if (encodingInfo.UseEPrefix)
                {
                    ret.WriteByte((byte)ASCIIBytes.E);
                }

                ret.WriteByte(encodingInfo.Quote);
            }

            foreach (byte b in nativeData)
            {
                if (b >= 0x20 && b < 0x7F && b != 0x22 && b != 0x27 && b != 0x5C)
                {
                    ret.WriteByte(b);
                }
                else
                {
                    ret
                    .WriteBytes(encodingInfo.ByteaEscape)
                    .WriteBytes(escapeEncodingByteMap[7 & (b >> 6)])
                    .WriteBytes(escapeEncodingByteMap[7 & (b >> 3)])
                    .WriteBytes(escapeEncodingByteMap[7 & b]);
                }
            }

            if (encodingInfo.Quote != 0)
            {
                ret.WriteByte(encodingInfo.Quote);
            }

            return(ret.ToArray());
        }