All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.couchbase.client.core.endpoint.util.ByteBufJsonHelper Maven / Gradle / Ivy

There is a newer version: 3.7.2
Show newest version
/*
 * Copyright (c) 2015 Couchbase, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
 * IN THE SOFTWARE.
 */

package com.couchbase.client.core.endpoint.util;

import com.couchbase.client.deps.io.netty.buffer.ByteBuf;

/**
 * An helper class providing utility methods to deal with parsing of structured
 * data (like JSON) inside a {@link ByteBuf} buffer.
 *
 * @author Simon Baslé
 * @since 1.1
 */
public class ByteBufJsonHelper {


    /**
     * Shorthand for {@link ByteBuf#bytesBefore(byte)} with a simple char c,
     * finds the number of bytes until next occurrence of
     * the character c from the current readerIndex() in buf.
     *
     * @param buf the {@link ByteBuf buffer} to look into.
     * @param c the character to search for.
     * @return the number of bytes before the character or -1 if not found.
     * @see ByteBuf#bytesBefore(byte)
     */
    public static final int findNextChar(ByteBuf buf, char c) {
        return buf.bytesBefore((byte) c);
    }

    /**
     * Find the number of bytes until next occurrence of the character c
     * from the current {@link ByteBuf#readerIndex() readerIndex} in buf,
     * with the twist that if this occurrence is prefixed by the prefix
     * character, we try to find another occurrence.
     *
     * @param buf the {@link ByteBuf buffer} to look into.
     * @param c the character to search for.
     * @param prefix the character to trigger a retry.
     * @return the position of the first occurrence of c that is not prefixed by prefix
     * or -1 if none found.
     */
    public static final int findNextCharNotPrefixedBy(ByteBuf buf, char c, char prefix) {
        int found =  buf.bytesBefore((byte) c);
        if (found < 1) {
            return found;
        } else {
            int from;
            while (found > -1 && (char) buf.getByte(
                    buf.readerIndex() + found - 1) == prefix) {
                //advance from
                from = buf.readerIndex() + found + 1;
                //search again
                int next = buf.bytesBefore(from, buf.readableBytes() - from, (byte) c);
                if (next == -1) {
                    return -1;
                } else {
                    found += next + 1;
                }
            }
            return found;
        }
    }

    /**
     * Finds the position of the correct closing character, taking into account the fact that before the correct one,
     * other sub section with same opening and closing characters can be encountered.
     *
     * This implementation starts for the current {@link ByteBuf#readerIndex() readerIndex}.
     *
     * @param buf the {@link ByteBuf} where to search for the end of a section enclosed in openingChar and closingChar.
     * @param openingChar the section opening char, used to detect a sub-section.
     * @param closingChar the section closing char, used to detect the end of a sub-section / this section.
     * @return the section closing position or -1 if not found.
     */
    public static int findSectionClosingPosition(ByteBuf buf, char openingChar, char closingChar) {
        return buf.forEachByte(new ClosingPositionBufProcessor(openingChar, closingChar, true));
    }

    /**
     * Finds the position of the correct closing character, taking into account the fact that before the correct one,
     * other sub section with same opening and closing characters can be encountered.
     *
     * This implementation starts for the current {@link ByteBuf#readerIndex() readerIndex} + startOffset.
     *
     * @param buf the {@link ByteBuf} where to search for the end of a section enclosed in openingChar and closingChar.
     * @param startOffset the offset at which to start reading (from buffer's readerIndex).
     * @param openingChar the section opening char, used to detect a sub-section.
     * @param closingChar the section closing char, used to detect the end of a sub-section / this section.
     * @return the section closing position or -1 if not found.
     */
    public static int findSectionClosingPosition(ByteBuf buf, int startOffset, char openingChar, char closingChar) {
        int from = buf.readerIndex() + startOffset;
        int length = buf.writerIndex() - from;
        if (length < 0) {
            throw new IllegalArgumentException("startOffset must not go beyond the readable byte length of the buffer");
        }

        return buf.forEachByte(from, length,
                new ClosingPositionBufProcessor(openingChar, closingChar, true));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy