Search in sources :

Example 71 with CharBuffer

use of java.nio.CharBuffer in project Openfire by igniterealtime.

the class XMLLightweightParser method read.

/*
    * Main reading method
    */
public void read(IoBuffer byteBuffer) throws Exception {
    if (buffer == null) {
        // exception was thrown before, avoid duplicate exception(s)
        // "read" and discard remaining data
        byteBuffer.position(byteBuffer.limit());
        return;
    }
    invalidateBuffer();
    // we will abort parsing when 1 Mega of queued chars was found.
    if (buffer.length() > maxBufferSize) {
        // purge the local buffer / free memory
        buffer = null;
        // processing the exception takes quite long
        final ProtocolDecoderException ex = new ProtocolDecoderException("Stopped parsing never ending stanza");
        ex.setHexdump("(redacted hex dump of never ending stanza)");
        throw ex;
    }
    CharBuffer charBuffer = CharBuffer.allocate(byteBuffer.capacity());
    encoder.reset();
    encoder.decode(byteBuffer.buf(), charBuffer, false);
    char[] buf = new char[charBuffer.position()];
    charBuffer.flip();
    charBuffer.get(buf);
    int readChar = buf.length;
    // Just return if nothing was read
    if (readChar == 0) {
        return;
    }
    buffer.append(buf);
    // Robot.
    char ch;
    boolean isHighSurrogate = false;
    for (int i = 0; i < readChar; i++) {
        ch = buf[i];
        if (ch < 0x20 && ch != 0x9 && ch != 0xA && ch != 0xD && ch != 0x0) {
            //Unicode characters in the range 0x0000-0x001F other than 9, A, and D are not allowed in XML
            //We need to allow the NULL character, however, for Flash XMLSocket clients to work.
            buffer = null;
            throw new XMLNotWellFormedException("Character is invalid in: " + ch);
        }
        if (isHighSurrogate) {
            if (Character.isLowSurrogate(ch)) {
                // Everything is fine. Clean up traces for surrogates
                isHighSurrogate = false;
            } else {
                // Trigger error. Found high surrogate not followed by low surrogate
                buffer = null;
                throw new Exception("Found high surrogate not followed by low surrogate");
            }
        } else if (Character.isHighSurrogate(ch)) {
            isHighSurrogate = true;
        } else if (Character.isLowSurrogate(ch)) {
            // Trigger error. Found low surrogate char without a preceding high surrogate
            buffer = null;
            throw new Exception("Found low surrogate char without a preceding high surrogate");
        }
        if (status == XMLLightweightParser.TAIL) {
            // Looking for the close tag
            if (depth < 1 && ch == head.charAt(tailCount)) {
                tailCount++;
                if (tailCount == head.length()) {
                    // Close stanza found!
                    // Calculate the correct start,end position of the message into the buffer
                    int end = buffer.length() - readChar + (i + 1);
                    String msg = buffer.substring(startLastMsg, end);
                    // Add message to the list
                    foundMsg(msg);
                    startLastMsg = end;
                }
            } else {
                tailCount = 0;
                status = XMLLightweightParser.INSIDE;
            }
        } else if (status == XMLLightweightParser.PRETAIL) {
            if (ch == XMLLightweightParser.CDATA_START[cdataOffset]) {
                cdataOffset++;
                if (cdataOffset == XMLLightweightParser.CDATA_START.length) {
                    status = XMLLightweightParser.INSIDE_CDATA;
                    cdataOffset = 0;
                    continue;
                }
            } else {
                cdataOffset = 0;
                status = XMLLightweightParser.INSIDE;
            }
            if (ch == '/') {
                status = XMLLightweightParser.TAIL;
                depth--;
            } else if (ch == '!') {
                // This is a <! (comment) so ignore it
                status = XMLLightweightParser.INSIDE;
            } else {
                depth++;
            }
        } else if (status == XMLLightweightParser.VERIFY_CLOSE_TAG) {
            if (ch == '>') {
                depth--;
                status = XMLLightweightParser.OUTSIDE;
                if (depth < 1) {
                    // Found a tag in the form <tag />
                    int end = buffer.length() - readChar + (i + 1);
                    String msg = buffer.substring(startLastMsg, end);
                    // Add message to the list
                    foundMsg(msg);
                    startLastMsg = end;
                }
            } else if (ch == '<') {
                status = XMLLightweightParser.PRETAIL;
                insideChildrenTag = true;
            } else {
                status = XMLLightweightParser.INSIDE;
            }
        } else if (status == XMLLightweightParser.INSIDE_PARAM_VALUE) {
            if (ch == '"') {
                status = XMLLightweightParser.INSIDE;
            }
        } else if (status == XMLLightweightParser.INSIDE_CDATA) {
            if (ch == XMLLightweightParser.CDATA_END[cdataOffset]) {
                cdataOffset++;
                if (cdataOffset == XMLLightweightParser.CDATA_END.length) {
                    status = XMLLightweightParser.OUTSIDE;
                    cdataOffset = 0;
                }
            } else if (cdataOffset == XMLLightweightParser.CDATA_END.length - 1 && ch == XMLLightweightParser.CDATA_END[cdataOffset - 1]) {
            // if we are looking for the last CDATA_END char, and we instead found an extra ']' 
            // char, leave cdataOffset as is and proceed to the next char. This could be a case 
            // where the XML character data ends with multiple square braces. For Example ]]]>
            } else {
                cdataOffset = 0;
            }
        } else if (status == XMLLightweightParser.INSIDE) {
            if (ch == XMLLightweightParser.CDATA_START[cdataOffset]) {
                cdataOffset++;
                if (cdataOffset == XMLLightweightParser.CDATA_START.length) {
                    status = XMLLightweightParser.INSIDE_CDATA;
                    cdataOffset = 0;
                    continue;
                }
            } else {
                cdataOffset = 0;
                status = XMLLightweightParser.INSIDE;
            }
            if (ch == '"') {
                status = XMLLightweightParser.INSIDE_PARAM_VALUE;
            } else if (ch == '>') {
                status = XMLLightweightParser.OUTSIDE;
                if (insideRootTag && ("stream:stream>".equals(head.toString()) || ("?xml>".equals(head.toString())) || ("flash:stream>".equals(head.toString())))) {
                    // Found closing stream:stream
                    int end = buffer.length() - readChar + (i + 1);
                    // Skip LF, CR and other "weird" characters that could appear
                    while (startLastMsg < end && '<' != buffer.charAt(startLastMsg)) {
                        startLastMsg++;
                    }
                    String msg = buffer.substring(startLastMsg, end);
                    foundMsg(msg);
                    startLastMsg = end;
                }
                insideRootTag = false;
            } else if (ch == '/') {
                status = XMLLightweightParser.VERIFY_CLOSE_TAG;
            }
        } else if (status == XMLLightweightParser.HEAD) {
            if (ch == ' ' || ch == '>') {
                // Append > to head to allow searching </tag>
                head.append('>');
                if (ch == '>')
                    status = XMLLightweightParser.OUTSIDE;
                else
                    status = XMLLightweightParser.INSIDE;
                insideRootTag = true;
                insideChildrenTag = false;
                continue;
            } else if (ch == '/' && head.length() > 0) {
                status = XMLLightweightParser.VERIFY_CLOSE_TAG;
                depth--;
            }
            head.append(ch);
        } else if (status == XMLLightweightParser.INIT) {
            if (ch == '<') {
                status = XMLLightweightParser.HEAD;
                depth = 1;
            } else {
                startLastMsg++;
            }
        } else if (status == XMLLightweightParser.OUTSIDE) {
            if (ch == '<') {
                status = XMLLightweightParser.PRETAIL;
                cdataOffset = 1;
                insideChildrenTag = true;
            }
        }
    }
    if (head.length() > 0 && ("/stream:stream>".equals(head.toString()) || ("/flash:stream>".equals(head.toString())))) {
        // Found closing stream:stream
        foundMsg("</stream:stream>");
    }
}
Also used : ProtocolDecoderException(org.apache.mina.filter.codec.ProtocolDecoderException) CharBuffer(java.nio.CharBuffer) ProtocolDecoderException(org.apache.mina.filter.codec.ProtocolDecoderException)

Example 72 with CharBuffer

use of java.nio.CharBuffer in project hs4j by killme2008.

the class AbstractIoBuffer method getString.

/**
     * {@inheritDoc}
     */
@Override
public String getString(int fieldSize, CharsetDecoder decoder) throws CharacterCodingException {
    checkFieldSize(fieldSize);
    if (fieldSize == 0) {
        return "";
    }
    if (!hasRemaining()) {
        return "";
    }
    boolean utf16 = decoder.charset().name().startsWith("UTF-16");
    if (utf16 && (fieldSize & 1) != 0) {
        throw new IllegalArgumentException("fieldSize is not even.");
    }
    int oldPos = position();
    int oldLimit = limit();
    int end = oldPos + fieldSize;
    if (oldLimit < end) {
        throw new BufferUnderflowException();
    }
    int i;
    if (!utf16) {
        for (i = oldPos; i < end; i++) {
            if (get(i) == 0) {
                break;
            }
        }
        if (i == end) {
            limit(end);
        } else {
            limit(i);
        }
    } else {
        for (i = oldPos; i < end; i += 2) {
            if (get(i) == 0 && get(i + 1) == 0) {
                break;
            }
        }
        if (i == end) {
            limit(end);
        } else {
            limit(i);
        }
    }
    if (!hasRemaining()) {
        limit(oldLimit);
        position(end);
        return "";
    }
    decoder.reset();
    int expectedLength = (int) (remaining() * decoder.averageCharsPerByte()) + 1;
    CharBuffer out = CharBuffer.allocate(expectedLength);
    for (; ; ) {
        CoderResult cr;
        if (hasRemaining()) {
            cr = decoder.decode(buf(), out, true);
        } else {
            cr = decoder.flush(out);
        }
        if (cr.isUnderflow()) {
            break;
        }
        if (cr.isOverflow()) {
            CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength);
            out.flip();
            o.put(out);
            out = o;
            continue;
        }
        if (cr.isError()) {
            // Revert the buffer back to the previous state.
            limit(oldLimit);
            position(oldPos);
            cr.throwException();
        }
    }
    limit(oldLimit);
    position(end);
    return out.flip().toString();
}
Also used : CharBuffer(java.nio.CharBuffer) BufferUnderflowException(java.nio.BufferUnderflowException) CoderResult(java.nio.charset.CoderResult)

Example 73 with CharBuffer

use of java.nio.CharBuffer in project hs4j by killme2008.

the class AbstractIoBuffer method putString.

/**
     * {@inheritDoc}
     */
@Override
public IoBuffer putString(CharSequence val, int fieldSize, CharsetEncoder encoder) throws CharacterCodingException {
    checkFieldSize(fieldSize);
    if (fieldSize == 0) {
        return this;
    }
    autoExpand(fieldSize);
    boolean utf16 = encoder.charset().name().startsWith("UTF-16");
    if (utf16 && (fieldSize & 1) != 0) {
        throw new IllegalArgumentException("fieldSize is not even.");
    }
    int oldLimit = limit();
    int end = position() + fieldSize;
    if (oldLimit < end) {
        throw new BufferOverflowException();
    }
    if (val.length() == 0) {
        if (!utf16) {
            put((byte) 0x00);
        } else {
            put((byte) 0x00);
            put((byte) 0x00);
        }
        position(end);
        return this;
    }
    CharBuffer in = CharBuffer.wrap(val);
    limit(end);
    encoder.reset();
    for (; ; ) {
        CoderResult cr;
        if (in.hasRemaining()) {
            cr = encoder.encode(in, buf(), true);
        } else {
            cr = encoder.flush(buf());
        }
        if (cr.isUnderflow() || cr.isOverflow()) {
            break;
        }
        cr.throwException();
    }
    limit(oldLimit);
    if (position() < end) {
        if (!utf16) {
            put((byte) 0x00);
        } else {
            put((byte) 0x00);
            put((byte) 0x00);
        }
    }
    position(end);
    return this;
}
Also used : CharBuffer(java.nio.CharBuffer) BufferOverflowException(java.nio.BufferOverflowException) CoderResult(java.nio.charset.CoderResult)

Example 74 with CharBuffer

use of java.nio.CharBuffer in project hs4j by killme2008.

the class AbstractIoBuffer method putPrefixedString.

/**
     * {@inheritDoc}
     */
@Override
public IoBuffer putPrefixedString(CharSequence val, int prefixLength, int padding, byte padValue, CharsetEncoder encoder) throws CharacterCodingException {
    int maxLength;
    switch(prefixLength) {
        case 1:
            maxLength = 255;
            break;
        case 2:
            maxLength = 65535;
            break;
        case 4:
            maxLength = Integer.MAX_VALUE;
            break;
        default:
            throw new IllegalArgumentException("prefixLength: " + prefixLength);
    }
    if (val.length() > maxLength) {
        throw new IllegalArgumentException("The specified string is too long.");
    }
    if (val.length() == 0) {
        switch(prefixLength) {
            case 1:
                put((byte) 0);
                break;
            case 2:
                putShort((short) 0);
                break;
            case 4:
                putInt(0);
                break;
        }
        return this;
    }
    int padMask;
    switch(padding) {
        case 0:
        case 1:
            padMask = 0;
            break;
        case 2:
            padMask = 1;
            break;
        case 4:
            padMask = 3;
            break;
        default:
            throw new IllegalArgumentException("padding: " + padding);
    }
    CharBuffer in = CharBuffer.wrap(val);
    // make a room for the length field
    skip(prefixLength);
    int oldPos = position();
    encoder.reset();
    int expandedState = 0;
    for (; ; ) {
        CoderResult cr;
        if (in.hasRemaining()) {
            cr = encoder.encode(in, buf(), true);
        } else {
            cr = encoder.flush(buf());
        }
        if (position() - oldPos > maxLength) {
            throw new IllegalArgumentException("The specified string is too long.");
        }
        if (cr.isUnderflow()) {
            break;
        }
        if (cr.isOverflow()) {
            if (isAutoExpand()) {
                switch(expandedState) {
                    case 0:
                        autoExpand((int) Math.ceil(in.remaining() * encoder.averageBytesPerChar()));
                        expandedState++;
                        break;
                    case 1:
                        autoExpand((int) Math.ceil(in.remaining() * encoder.maxBytesPerChar()));
                        expandedState++;
                        break;
                    default:
                        throw new RuntimeException("Expanded by " + (int) Math.ceil(in.remaining() * encoder.maxBytesPerChar()) + " but that wasn't enough for '" + val + "'");
                }
                continue;
            }
        } else {
            expandedState = 0;
        }
        cr.throwException();
    }
    // Write the length field
    fill(padValue, padding - (position() - oldPos & padMask));
    int length = position() - oldPos;
    switch(prefixLength) {
        case 1:
            put(oldPos - 1, (byte) length);
            break;
        case 2:
            putShort(oldPos - 2, (short) length);
            break;
        case 4:
            putInt(oldPos - 4, length);
            break;
    }
    return this;
}
Also used : CharBuffer(java.nio.CharBuffer) CoderResult(java.nio.charset.CoderResult)

Example 75 with CharBuffer

use of java.nio.CharBuffer in project hs4j by killme2008.

the class AbstractIoBuffer method getPrefixedString.

/**
     * Reads a string which has a length field before the actual encoded string,
     * using the specified <code>decoder</code> and returns it.
     * 
     * @param prefixLength
     *            the length of the length field (1, 2, or 4)
     * @param decoder
     *            the decoder to use for decoding the string
     * @return the prefixed string
     * @throws CharacterCodingException
     *             when decoding fails
     * @throws BufferUnderflowException
     *             when there is not enough data available
     */
@Override
public String getPrefixedString(int prefixLength, CharsetDecoder decoder) throws CharacterCodingException {
    if (!prefixedDataAvailable(prefixLength)) {
        throw new BufferUnderflowException();
    }
    int fieldSize = 0;
    switch(prefixLength) {
        case 1:
            fieldSize = getUnsigned();
            break;
        case 2:
            fieldSize = getUnsignedShort();
            break;
        case 4:
            fieldSize = getInt();
            break;
    }
    if (fieldSize == 0) {
        return "";
    }
    boolean utf16 = decoder.charset().name().startsWith("UTF-16");
    if (utf16 && (fieldSize & 1) != 0) {
        throw new BufferDataException("fieldSize is not even for a UTF-16 string.");
    }
    int oldLimit = limit();
    int end = position() + fieldSize;
    if (oldLimit < end) {
        throw new BufferUnderflowException();
    }
    limit(end);
    decoder.reset();
    int expectedLength = (int) (remaining() * decoder.averageCharsPerByte()) + 1;
    CharBuffer out = CharBuffer.allocate(expectedLength);
    for (; ; ) {
        CoderResult cr;
        if (hasRemaining()) {
            cr = decoder.decode(buf(), out, true);
        } else {
            cr = decoder.flush(out);
        }
        if (cr.isUnderflow()) {
            break;
        }
        if (cr.isOverflow()) {
            CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength);
            out.flip();
            o.put(out);
            out = o;
            continue;
        }
        cr.throwException();
    }
    limit(oldLimit);
    position(end);
    return out.flip().toString();
}
Also used : CharBuffer(java.nio.CharBuffer) BufferUnderflowException(java.nio.BufferUnderflowException) CoderResult(java.nio.charset.CoderResult)

Aggregations

CharBuffer (java.nio.CharBuffer)401 ByteBuffer (java.nio.ByteBuffer)152 CoderResult (java.nio.charset.CoderResult)83 CharsetDecoder (java.nio.charset.CharsetDecoder)47 IOException (java.io.IOException)45 Charset (java.nio.charset.Charset)33 Test (org.junit.Test)23 CharacterCodingException (java.nio.charset.CharacterCodingException)15 CharsetEncoder (java.nio.charset.CharsetEncoder)15 FileInputStream (java.io.FileInputStream)11 IntBuffer (java.nio.IntBuffer)10 Reader (java.io.Reader)9 BufferOverflowException (java.nio.BufferOverflowException)9 DoubleBuffer (java.nio.DoubleBuffer)9 FloatBuffer (java.nio.FloatBuffer)9 LongBuffer (java.nio.LongBuffer)9 ShortBuffer (java.nio.ShortBuffer)9 BufferUnderflowException (java.nio.BufferUnderflowException)7 ValueWrapper (org.apache.geode.internal.memcached.ValueWrapper)7 InputStream (java.io.InputStream)6