/// <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; }
/// <exception cref="System.IO.IOException"/> public override int readBinaryValue(com.fasterxml.jackson.core.Base64Variant b64variant , Sharpen.OutputStream @out) { // if we have already read the token, just use whatever we may have if (!_tokenIncomplete || _currToken != com.fasterxml.jackson.core.JsonToken.VALUE_STRING) { byte[] b = getBinaryValue(b64variant); @out.write(b); return b.Length; } // otherwise do "real" incremental parsing... byte[] buf = _ioContext.allocBase64Buffer(); try { return _readBinary(b64variant, @out, buf); } finally { _ioContext.releaseBase64Buffer(buf); } }
/* /********************************************************** /* Overrides for life-cycle /********************************************************** */ /// <exception cref="System.IO.IOException"/> public override int releaseBuffered(Sharpen.OutputStream @out) { int count = _inputEnd - _inputPtr; if (count < 1) { return 0; } // let's just advance ptr to end int origPtr = _inputPtr; @out.write(_inputBuffer, origPtr, count); return count; }
/// <exception cref="System.IO.IOException"/> public virtual int writeUnquotedUTF8(Sharpen.OutputStream @out) { byte[] result = _unquotedUTF8Ref; if (result == null) { result = com.fasterxml.jackson.core.io.JsonStringEncoder.getInstance().encodeAsUTF8 (_value); _unquotedUTF8Ref = result; } int length = result.Length; @out.write(result, 0, length); return length; }