Example usage for com.fasterxml.jackson.core.util ByteArrayBuilder appendThreeBytes

List of usage examples for com.fasterxml.jackson.core.util ByteArrayBuilder appendThreeBytes

Introduction

In this page you can find the example usage for com.fasterxml.jackson.core.util ByteArrayBuilder appendThreeBytes.

Prototype

public void appendThreeBytes(int b24) 

Source Link

Usage

From source file:com.bazaarvoice.jackson.rison.RisonParser.java

/**
 * Efficient handling for incremental parsing of base64-encoded
 * textual content./*from   w  w  w  .j a v  a  2s  . c o  m*/
 */
protected byte[] _decodeBase64(Base64Variant b64variant) throws IOException, JsonParseException {
    ByteArrayBuilder builder = _getByteArrayBuilder();

    //main_loop:
    while (true) {
        // first, we'll skip preceding white space, if any
        char ch;
        do {
            if (_inputPtr >= _inputEnd) {
                loadMoreGuaranteed();
            }
            ch = _inputBuffer[_inputPtr++];
        } while (ch <= INT_SPACE);
        int bits = b64variant.decodeBase64Char(ch);
        if (bits < 0) {
            if (ch == INT_APOSTROPHE) { // reached the end, fair and square?
                return builder.toByteArray();
            }
            bits = _decodeBase64Escape2(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++];
        bits = b64variant.decodeBase64Char(ch);
        if (bits < 0) {
            bits = _decodeBase64Escape2(b64variant, ch, 1);
        }
        decodedData = (decodedData << 6) | bits;

        // third base64 char; can be padding, but not ws
        if (_inputPtr >= _inputEnd) {
            loadMoreGuaranteed();
        }
        ch = _inputBuffer[_inputPtr++];
        bits = b64variant.decodeBase64Char(ch);

        // First branch: can get padding (-> 1 byte)
        if (bits < 0) {
            if (bits != Base64Variant.BASE64_VALUE_PADDING) {
                // as per [JACKSON-631], could also just be 'missing'  padding
                if (ch == INT_APOSTROPHE && !b64variant.usesPadding()) {
                    decodedData >>= 4;
                    builder.append(decodedData);
                    return builder.toByteArray();
                }
                bits = _decodeBase64Escape2(b64variant, ch, 2);
            }
            if (bits == Base64Variant.BASE64_VALUE_PADDING) {
                // Ok, must get more padding chars, then
                if (_inputPtr >= _inputEnd) {
                    loadMoreGuaranteed();
                }
                ch = _inputBuffer[_inputPtr++];
                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;
            }
            // otherwise we got escaped other char, to be processed below
        }
        // 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++];
        bits = b64variant.decodeBase64Char(ch);
        if (bits < 0) {
            if (bits != Base64Variant.BASE64_VALUE_PADDING) {
                // as per [JACKSON-631], could also just be 'missing'  padding
                if (ch == INT_APOSTROPHE && !b64variant.usesPadding()) {
                    decodedData >>= 2;
                    builder.appendTwoBytes(decodedData);
                    return builder.toByteArray();
                }
                bits = _decodeBase64Escape2(b64variant, ch, 3);
            }
            if (bits == 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 we got escaped other char, to be processed below
        }
        // otherwise, our triplet is now complete
        decodedData = (decodedData << 6) | bits;
        builder.appendThreeBytes(decodedData);
    }
}