FastCharBuffer(from jodd)


import jodd.util.CharArraySequence;

import java.util.Arrays;

/**
 * Faster {@code char} buffer.
 */
public class FastCharBuffer implements CharSequence, Appendable {

    private char[] buffer;
    private int offset;

    /**
     * Creates a new {@code char} buffer. The buffer capacity is
     * initially 64 chars, though its size increases if necessary.
     */
    public FastCharBuffer() {
        this.buffer = new char[64];
    }

    /**
     * Creates a new {@code char} buffer, with a buffer capacity of
     * the specified size, in chars.
     *
     * @param size the initial size.
     * @throws IllegalArgumentException if size is negative.
     */
    public FastCharBuffer(final int size) {
        this.buffer = new char[size];
    }

    /**
     * Grows the buffer.
     */
    private void grow(final int minCapacity) {
        final int oldCapacity = buffer.length;
        int newCapacity = oldCapacity << 1;
        if (newCapacity - minCapacity < 0) {
            // special case, min capacity is larger then a grow
            newCapacity = minCapacity + 512;
        }
        buffer = Arrays.copyOf(buffer, newCapacity);
    }

    /**
     * Appends single {@code char} to buffer.
     */
    @Override
    public FastCharBuffer append(final char element) {
        if (offset - buffer.length >= 0) {
            grow(offset);
        }

        buffer[offset++] = element;
        return this;
    }

    /**
     * Appends {@code char} array to buffer.
     */
    public FastCharBuffer append(final char[] array, final int off, final int len) {
        if (offset + len - buffer.length > 0) {
            grow(offset + len);
        }

        System.arraycopy(array, off, buffer, offset, len);
        offset += len;
        return this;
    }

    /**
     * Appends {@code char} array to buffer.
     */
    public FastCharBuffer append(final char[] array) {
        return append(array, 0, array.length);
    }

    /**
     * Appends another fast buffer to this one.
     */
    public FastCharBuffer append(final FastCharBuffer buff) {
        if (buff.offset == 0) {
            return this;
        }
        append(buff.buffer, 0, buff.offset);
        return this;
    }

    /**
     * Returns buffer size.
     */
    public int size() {
        return offset;
    }

    @Override
    public int length() {
        return offset;
    }

    /**
     * Tests if this buffer has no elements.
     */
    public boolean isEmpty() {
        return offset == 0;
    }

    /**
     * Resets the buffer content.
     */
    public void clear() {
        offset = 0;
    }

    /**
     * Creates {@code char} array from buffered content.
     */
    public char[] toArray() {
        return Arrays.copyOf(buffer, offset);
    }

    /**
     * Creates {@code char} subarray from buffered content.
     */
    public char[] toArray(final int start, final int len) {
        final char[] array = new char[len];

        if (len == 0) {
            return array;
        }

        System.arraycopy(buffer, start, array, 0, len);

        return array;
    }

    /**
     * Returns {@code char} element at given index.
     */
    public char get(final int index) {
        if (index >= offset) {
            throw new IndexOutOfBoundsException();
        }
        return buffer[index];
    }

    /**
     * Appends character sequence to buffer.
     */
    @Override
    public FastCharBuffer append(final CharSequence csq) {
        append(csq, 0, csq.length());
        return this;
    }

    /**
     * Appends character sequence to buffer.
     */
    @Override
    public FastCharBuffer append(final CharSequence csq, final int start, final int end) {
        for (int i = start; i < end; i++) {
            append(csq.charAt(i));
        }
        return this;
    }
    @Override
    public char charAt(final int index) {
        return get(index);
    }

    @Override
    public CharSequence subSequence(final int start, final int end) {
        return new CharArraySequence(buffer, start, end - start);
    }

    /**
     * Returns a String of the char buffer.
     * Please use {@code StringBuilder} instead, it is faster.
     */
    @Override
    public String toString() {
        return new String(toArray());
    }
}



import jodd.util.RandomString;
import org.junit.jupiter.api.Test;

import java.util.Random;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

class FastCharBufferTest extends FastBufferTestBase {

    @Test
    void testAppendString() {
        FastCharBuffer fcb = new FastCharBuffer(10);

        fcb.append("12345678");
        fcb.append("ABCDEFGH");

        assertEquals("12345678ABCDEFGH", fcb.toString());
    }

    @Test
    void testRandomAppends() {
        StringBuilder sb = new StringBuilder(10);
        FastCharBuffer fcb = new FastCharBuffer(10);

        Random rnd = new Random();

        int loop = 100;
        while (loop-- > 0) {
            String s = RandomString.get().randomAlphaNumeric(rnd.nextInt(20));

            sb.append(s);
            fcb.append(s);
        }

        assertEquals(sb.toString(), fcb.toString());
    }


    @Test
    void testAppend() {
        FastCharBuffer buff = new FastCharBuffer(3);

        buff.append(buff);
        buff.append((char)173);
        buff.append(array((char)8,(char)98));

        assertArrayEquals(array((char)173, (char)8, (char)98), buff.toArray());

        buff.append(buff);

        assertArrayEquals(array((char)173, (char)8, (char)98, (char)173, (char)8, (char)98), buff.toArray());

        buff.append(array((char)173, (char)5, (char)3), 1, 1);

        assertArrayEquals(array((char)173, (char)8, (char)98, (char)173, (char)8, (char)98, (char)5), buff.toArray());

        FastCharBuffer buff2 = new FastCharBuffer(3);
        buff2.append(buff);

        assertEquals(7, buff2.toArray().length);
    }

    @Test
    void testClear() {
        FastCharBuffer buff = new FastCharBuffer();

        assertTrue(buff.isEmpty());

        buff.append((char)1);

        assertFalse(buff.isEmpty());

        buff.clear();

        assertTrue(buff.isEmpty());

        try {
            buff.get(0);
            fail("error");
        } catch (IndexOutOfBoundsException ignore) {
        }

        char[] arr = buff.toArray();

        assertEquals(0, arr.length);
    }

    @Test
    void testToArray() {
        FastCharBuffer buff = new FastCharBuffer();

        int sum = 0;

        for (int j = 0; j < COUNT; j++) {
            for (int i = 1; i <= SIZE; i++) {
                buff.append((char)i);
                sum += i;
            }
        }

        buff.append((char)173);
        sum += 173;

        char[] array = buff.toArray();
        int sum2 = 0;
        for (char l : array) {
            sum2 += l;
        }

        assertEquals(sum, sum2);


        array = buff.toArray(1, buff.size() - 2);
        sum2 = 0;
        for (char l : array) {
            sum2 += l;
        }

        assertEquals(sum - 1 - 173, sum2);
    }

    @Test
    void testToSubArray() {
        FastCharBuffer buff = new FastCharBuffer();

        int total = SIZE + (SIZE/2);

        for (int i = 1; i <= total; i++) {
            buff.append((char)i);
        }

        char[] array = buff.toArray(SIZE + 1, total - SIZE  - 1);

        assertEquals(total - SIZE - 1, array.length);
        assertEquals(SIZE + 2, array[0]);
    }


    protected char[] array(char... arr) {
        return arr;
    }


}


你可能感兴趣的:(FastCharBuffer(from jodd))