/// <exception cref="System.IO.IOException"/>
 protected internal virtual int _readBinary(com.fasterxml.jackson.core.Base64Variant
     b64variant, Sharpen.OutputStream @out, byte[] buffer)
 {
     int outputPtr = 0;
     int outputEnd = buffer.Length - 3;
     int outputCount = 0;
     while (true)
     {
         // first, we'll skip preceding white space, if any
         int ch;
         do
         {
             if (_inputPtr >= _inputEnd)
             {
                 loadMoreGuaranteed();
             }
             ch = (int)_inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
         }
         while (ch <= INT_SPACE);
         int bits = b64variant.decodeBase64Char(ch);
         if (bits < 0)
         {
             // reached the end, fair and square?
             if (ch == INT_QUOTE)
             {
                 break;
             }
             bits = _decodeBase64Escape(b64variant, ch, 0);
             if (bits < 0)
             {
                 // white space to skip
                 continue;
             }
         }
         // enough room? If not, flush
         if (outputPtr > outputEnd)
         {
             outputCount += outputPtr;
             @out.write(buffer, 0, outputPtr);
             outputPtr = 0;
         }
         int decodedData = bits;
         // then second base64 char; can't get padding yet, nor ws
         if (_inputPtr >= _inputEnd)
         {
             loadMoreGuaranteed();
         }
         ch = _inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
         bits = b64variant.decodeBase64Char(ch);
         if (bits < 0)
         {
             bits = _decodeBase64Escape(b64variant, ch, 1);
         }
         decodedData = (decodedData << 6) | bits;
         // third base64 char; can be padding, but not ws
         if (_inputPtr >= _inputEnd)
         {
             loadMoreGuaranteed();
         }
         ch = _inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
         bits = b64variant.decodeBase64Char(ch);
         // First branch: can get padding (-> 1 byte)
         if (bits < 0)
         {
             if (bits != com.fasterxml.jackson.core.Base64Variant.BASE64_VALUE_PADDING)
             {
                 // as per [JACKSON-631], could also just be 'missing'  padding
                 if (ch == '"' && !b64variant.usesPadding())
                 {
                     decodedData >>= 4;
                     buffer[outputPtr++] = unchecked((byte)decodedData);
                     break;
                 }
                 bits = _decodeBase64Escape(b64variant, ch, 2);
             }
             if (bits == com.fasterxml.jackson.core.Base64Variant.BASE64_VALUE_PADDING)
             {
                 // Ok, must get padding
                 if (_inputPtr >= _inputEnd)
                 {
                     loadMoreGuaranteed();
                 }
                 ch = _inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
                 if (!b64variant.usesPaddingChar(ch))
                 {
                     throw reportInvalidBase64Char(b64variant, ch, 3, "expected padding character '" +
                          b64variant.getPaddingChar() + "'");
                 }
                 // Got 12 bits, only need 8, need to shift
                 decodedData >>= 4;
                 buffer[outputPtr++] = unchecked((byte)decodedData);
                 continue;
             }
         }
         // Nope, 2 or 3 bytes
         decodedData = (decodedData << 6) | bits;
         // fourth and last base64 char; can be padding, but not ws
         if (_inputPtr >= _inputEnd)
         {
             loadMoreGuaranteed();
         }
         ch = _inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
         bits = b64variant.decodeBase64Char(ch);
         if (bits < 0)
         {
             if (bits != com.fasterxml.jackson.core.Base64Variant.BASE64_VALUE_PADDING)
             {
                 // as per [JACKSON-631], could also just be 'missing'  padding
                 if (ch == '"' && !b64variant.usesPadding())
                 {
                     decodedData >>= 2;
                     buffer[outputPtr++] = unchecked((byte)(decodedData >> 8));
                     buffer[outputPtr++] = unchecked((byte)decodedData);
                     break;
                 }
                 bits = _decodeBase64Escape(b64variant, ch, 3);
             }
             if (bits == com.fasterxml.jackson.core.Base64Variant.BASE64_VALUE_PADDING)
             {
                 /* With padding we only get 2 bytes; but we have
                 * to shift it a bit so it is identical to triplet
                 * case with partial output.
                 * 3 chars gives 3x6 == 18 bits, of which 2 are
                 * dummies, need to discard:
                 */
                 decodedData >>= 2;
                 buffer[outputPtr++] = unchecked((byte)(decodedData >> 8));
                 buffer[outputPtr++] = unchecked((byte)decodedData);
                 continue;
             }
         }
         // otherwise, our triplet is now complete
         decodedData = (decodedData << 6) | bits;
         buffer[outputPtr++] = unchecked((byte)(decodedData >> 16));
         buffer[outputPtr++] = unchecked((byte)(decodedData >> 8));
         buffer[outputPtr++] = unchecked((byte)decodedData);
     }
     _tokenIncomplete = false;
     if (outputPtr > 0)
     {
         outputCount += outputPtr;
         @out.write(buffer, 0, outputPtr);
     }
     return outputCount;
 }
 /*
 /**********************************************************
 /* Internal methods, binary access
 /**********************************************************
 */
 /// <summary>
 /// Efficient handling for incremental parsing of base64-encoded
 /// textual content.
 /// </summary>
 /// <exception cref="System.IO.IOException"/>
 protected internal byte[] _decodeBase64(com.fasterxml.jackson.core.Base64Variant 
     b64variant)
 {
     com.fasterxml.jackson.core.util.ByteArrayBuilder builder = _getByteArrayBuilder();
     //main_loop:
     while (true)
     {
         // first, we'll skip preceding white space, if any
         int ch;
         do
         {
             if (_inputPtr >= _inputEnd)
             {
                 loadMoreGuaranteed();
             }
             ch = (int)_inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
         }
         while (ch <= INT_SPACE);
         int bits = b64variant.decodeBase64Char(ch);
         if (bits < 0)
         {
             // reached the end, fair and square?
             if (ch == INT_QUOTE)
             {
                 return builder.toByteArray();
             }
             bits = _decodeBase64Escape(b64variant, ch, 0);
             if (bits < 0)
             {
                 // white space to skip
                 continue;
             }
         }
         int decodedData = bits;
         // then second base64 char; can't get padding yet, nor ws
         if (_inputPtr >= _inputEnd)
         {
             loadMoreGuaranteed();
         }
         ch = _inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
         bits = b64variant.decodeBase64Char(ch);
         if (bits < 0)
         {
             bits = _decodeBase64Escape(b64variant, ch, 1);
         }
         decodedData = (decodedData << 6) | bits;
         // third base64 char; can be padding, but not ws
         if (_inputPtr >= _inputEnd)
         {
             loadMoreGuaranteed();
         }
         ch = _inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
         bits = b64variant.decodeBase64Char(ch);
         // First branch: can get padding (-> 1 byte)
         if (bits < 0)
         {
             if (bits != com.fasterxml.jackson.core.Base64Variant.BASE64_VALUE_PADDING)
             {
                 // as per [JACKSON-631], could also just be 'missing'  padding
                 if (ch == '"' && !b64variant.usesPadding())
                 {
                     decodedData >>= 4;
                     builder.append(decodedData);
                     return builder.toByteArray();
                 }
                 bits = _decodeBase64Escape(b64variant, ch, 2);
             }
             if (bits == com.fasterxml.jackson.core.Base64Variant.BASE64_VALUE_PADDING)
             {
                 // Ok, must get padding
                 if (_inputPtr >= _inputEnd)
                 {
                     loadMoreGuaranteed();
                 }
                 ch = _inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
                 if (!b64variant.usesPaddingChar(ch))
                 {
                     throw reportInvalidBase64Char(b64variant, ch, 3, "expected padding character '" +
                          b64variant.getPaddingChar() + "'");
                 }
                 // Got 12 bits, only need 8, need to shift
                 decodedData >>= 4;
                 builder.append(decodedData);
                 continue;
             }
         }
         // Nope, 2 or 3 bytes
         decodedData = (decodedData << 6) | bits;
         // fourth and last base64 char; can be padding, but not ws
         if (_inputPtr >= _inputEnd)
         {
             loadMoreGuaranteed();
         }
         ch = _inputBuffer[_inputPtr++] & unchecked((int)(0xFF));
         bits = b64variant.decodeBase64Char(ch);
         if (bits < 0)
         {
             if (bits != com.fasterxml.jackson.core.Base64Variant.BASE64_VALUE_PADDING)
             {
                 // as per [JACKSON-631], could also just be 'missing'  padding
                 if (ch == '"' && !b64variant.usesPadding())
                 {
                     decodedData >>= 2;
                     builder.appendTwoBytes(decodedData);
                     return builder.toByteArray();
                 }
                 bits = _decodeBase64Escape(b64variant, ch, 3);
             }
             if (bits == com.fasterxml.jackson.core.Base64Variant.BASE64_VALUE_PADDING)
             {
                 /* With padding we only get 2 bytes; but we have
                 * to shift it a bit so it is identical to triplet
                 * case with partial output.
                 * 3 chars gives 3x6 == 18 bits, of which 2 are
                 * dummies, need to discard:
                 */
                 decodedData >>= 2;
                 builder.appendTwoBytes(decodedData);
                 continue;
             }
         }
         // otherwise, our triplet is now complete
         decodedData = (decodedData << 6) | bits;
         builder.appendThreeBytes(decodedData);
     }
 }