Convert

public static class Convert
{

    public static String ToBase64String(byte[] inArray)
    {
        if (inArray == null)
        {
            throw new ArgumentNullException("inArray");
        }
        Contract.Ensures(Contract.Result<string>() != null);
        Contract.EndContractBlock();
        return ToBase64String(inArray, 0, inArray.Length, Base64FormattingOptions.None);
    }

    [System.Runtime.InteropServices.ComVisible(false)]
    public static String ToBase64String(byte[] inArray, Base64FormattingOptions options)
    {
        if (inArray == null)
        {
            throw new ArgumentNullException("inArray");
        }
        Contract.Ensures(Contract.Result<string>() != null);
        Contract.EndContractBlock();
        return ToBase64String(inArray, 0, inArray.Length, options);
    }

    public static String ToBase64String(byte[] inArray, int offset, int length)
    {
        return ToBase64String(inArray, offset, length, Base64FormattingOptions.None);
    }

    [System.Security.SecuritySafeCritical]  // auto-generated
    [System.Runtime.InteropServices.ComVisible(false)]
    public static unsafe String ToBase64String(byte[] inArray, int offset, int length, Base64FormattingOptions options)
    {
        //Do data verfication
        if (inArray == null)
            throw new ArgumentNullException("inArray");
        if (length < 0)
            throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
        if (offset < 0)
            throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
        if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
            throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options));
        Contract.Ensures(Contract.Result<string>() != null);
        Contract.EndContractBlock();

        int inArrayLength;
        int stringLength;

        inArrayLength = inArray.Length;
        if (offset > (inArrayLength - length))
            throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));

        if (inArrayLength == 0)
            return String.Empty;

        bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
        //Create the new string.  This is the maximally required length.
        stringLength = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);

        string returnString = string.FastAllocateString(stringLength);
        fixed (char* outChars = returnString)
        {
            fixed (byte* inData = inArray)
            {
                int j = ConvertToBase64Array(outChars, inData, offset, length, insertLineBreaks);
                BCLDebug.Assert(returnString.Length == j, "returnString.Length == j");
                return returnString;
            }
        }
    }

    public static int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut)
    {
        Contract.Ensures(Contract.Result<int>() >= 0);
        Contract.Ensures(Contract.Result<int>() <= outArray.Length);
        Contract.EndContractBlock();

        return ToBase64CharArray(inArray, offsetIn, length, outArray, offsetOut, Base64FormattingOptions.None);
    }

    [System.Security.SecuritySafeCritical]  // auto-generated
    [System.Runtime.InteropServices.ComVisible(false)]
    public static unsafe int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut, Base64FormattingOptions options)
    {
        //Do data verfication
        if (inArray == null)
            throw new ArgumentNullException("inArray");
        if (outArray == null)
            throw new ArgumentNullException("outArray");
        if (length < 0)
            throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
        if (offsetIn < 0)
            throw new ArgumentOutOfRangeException("offsetIn", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
        if (offsetOut < 0)
            throw new ArgumentOutOfRangeException("offsetOut", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));

        if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
        {
            throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options));
        }
        Contract.Ensures(Contract.Result<int>() >= 0);
        Contract.Ensures(Contract.Result<int>() <= outArray.Length);
        Contract.EndContractBlock();


        int retVal;

        int inArrayLength;
        int outArrayLength;
        int numElementsToCopy;

        inArrayLength = inArray.Length;

        if (offsetIn > (int)(inArrayLength - length))
            throw new ArgumentOutOfRangeException("offsetIn", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));

        if (inArrayLength == 0)
            return 0;

        bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
        //This is the maximally required length that must be available in the char array
        outArrayLength = outArray.Length;

        // Length of the char buffer required
        numElementsToCopy = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);

        if (offsetOut > (int)(outArrayLength - numElementsToCopy))
            throw new ArgumentOutOfRangeException("offsetOut", Environment.GetResourceString("ArgumentOutOfRange_OffsetOut"));

        fixed (char* outChars = &outArray[offsetOut])
        {
            fixed (byte* inData = inArray)
            {
                retVal = ConvertToBase64Array(outChars, inData, offsetIn, length, insertLineBreaks);
            }
        }

        return retVal;
    }



    [System.Security.SecurityCritical]  // auto-generated
    private static unsafe int ConvertToBase64Array(char* outChars, byte* inData, int offset, int length, bool insertLineBreaks)
    {
        int lengthmod3 = length % 3;
        int calcLength = offset + (length - lengthmod3);
        int j = 0;
        int charcount = 0;
        //Convert three bytes at a time to base64 notation.  This will consume 4 chars.
        int i;

        // get a pointer to the base64Table to avoid unnecessary range checking
        fixed (char* base64 = base64Table)
        {
            for (i = offset; i < calcLength; i += 3)
            {
                if (insertLineBreaks)
                {
                    if (charcount == base64LineBreakPosition)
                    {
                        outChars[j++] = '\r';
                        outChars[j++] = '\n';
                        charcount = 0;
                    }
                    charcount += 4;
                }
                outChars[j] = base64[(inData[i] & 0xfc) >> 2];
                outChars[j + 1] = base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
                outChars[j + 2] = base64[((inData[i + 1] & 0x0f) << 2) | ((inData[i + 2] & 0xc0) >> 6)];
                outChars[j + 3] = base64[(inData[i + 2] & 0x3f)];
                j += 4;
            }

            //Where we left off before
            i = calcLength;

            if (insertLineBreaks && (lengthmod3 != 0) && (charcount == base64LineBreakPosition))
            {
                outChars[j++] = '\r';
                outChars[j++] = '\n';
            }

            switch (lengthmod3)
            {
                case 2: //One character padding needed
                    outChars[j] = base64[(inData[i] & 0xfc) >> 2];
                    outChars[j + 1] = base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
                    outChars[j + 2] = base64[(inData[i + 1] & 0x0f) << 2];
                    outChars[j + 3] = base64[64]; //Pad
                    j += 4;
                    break;
                case 1: // Two character padding needed
                    outChars[j] = base64[(inData[i] & 0xfc) >> 2];
                    outChars[j + 1] = base64[(inData[i] & 0x03) << 4];
                    outChars[j + 2] = base64[64]; //Pad
                    outChars[j + 3] = base64[64]; //Pad
                    j += 4;
                    break;
            }
        }

        return j;
    }

    private static int ToBase64_CalculateAndValidateOutputLength(int inputLength, bool insertLineBreaks)
    {
        long outlen = ((long)inputLength) / 3 * 4;          // the base length - we want integer division here. 
        outlen += ((inputLength % 3) != 0) ? 4 : 0;         // at most 4 more chars for the remainder

        if (outlen == 0)
            return 0;

        if (insertLineBreaks)
        {
            long newLines = outlen / base64LineBreakPosition;
            if ((outlen % base64LineBreakPosition) == 0)
            {
                --newLines;
            }
            outlen += newLines * 2;              // the number of line break chars we'll add, "\r\n"
        }

        if (outlen > int.MaxValue)
            throw new OutOfMemoryException();

        return (int)outlen;
    }



    [SecuritySafeCritical]
    public static Byte[] FromBase64String(String s)
    {
        if (s == null)
            throw new ArgumentNullException("s");

        Contract.EndContractBlock();

        unsafe
        {
            fixed (Char* sPtr = s)
            {

                return FromBase64CharPtr(sPtr, s.Length);
            }
        }
    }

    [SecuritySafeCritical]
    public static Byte[] FromBase64CharArray(Char[] inArray, Int32 offset, Int32 length)
    {

        if (inArray == null)
            throw new ArgumentNullException("inArray");

#if FEATURE_LEGACYNETCF
    Contract.EndContractBlock();
 
    // throw FormatException, to ensure compatibility with Mango Apps.
    if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {
        if(inArray.Length == 0) {
                throw new FormatException();
        }
    }
#endif

        if (length < 0)
            throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));

        if (offset < 0)
            throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));

        if (offset > inArray.Length - length)
            throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));

#if !FEATURE_LEGACYNETCF  // Our compat hack above breaks CCRewrite's rules on valid contracts.
        Contract.EndContractBlock();
#endif

        unsafe
        {
            fixed (Char* inArrayPtr = inArray)
            {

                return FromBase64CharPtr(inArrayPtr + offset, length);
            }
        }
    }


    [SecurityCritical]
    private static unsafe Byte[] FromBase64CharPtr(Char* inputPtr, Int32 inputLength)
    {
        Contract.Assert(0 <= inputLength);

        while (inputLength > 0)
        {
            Int32 lastChar = inputPtr[inputLength - 1];
            if (lastChar != (Int32)' ' && lastChar != (Int32)'\n' && lastChar != (Int32)'\r' && lastChar != (Int32)'\t')
                break;
            inputLength--;
        }

        // Compute the output length:
        Int32 resultLength = FromBase64_ComputeResultLength(inputPtr, inputLength);

        Contract.Assert(0 <= resultLength);

        Byte[] decodedBytes = new Byte[resultLength];

        // Convert Base64 chars into bytes:
        Int32 actualResultLength;
        fixed (Byte* decodedBytesPtr = decodedBytes)
            actualResultLength = FromBase64_Decode(inputPtr, inputLength, decodedBytesPtr, resultLength);

        return decodedBytes;
    }

}

 

posted @ 2016-11-29 23:21  茗::流  阅读(269)  评论(0)    收藏  举报
如有雷同,纯属参考。如有侵犯你的版权,请联系我。