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

org.grails.charsequences.CharSequences Maven / Gradle / Ivy

/*
 * Copyright 2014-2023 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.grails.charsequences;

import java.io.IOException;
import java.io.Writer;

/**
 * Utility functions for handling java.lang.CharSequence instances
 *
 *
 * @author Lari Hotari
 * @since 2.3.10
 *
 */
public final class CharSequences {

    private CharSequences() {
    }

    public static CharSequence createCharSequence(char[] chars) {
        return new CharArrayCharSequence(chars, 0, chars.length);
    }

    public static CharSequence createCharSequence(char[] chars, int start, int count) {
        return new CharArrayCharSequence(chars, start, count);
    }

    public static CharSequence createCharSequence(CharSequence str, int start, int count) {
        if (canUseOriginalForSubSequence(str, start, count)) {
            return str;
        }
        else {
            return new SubCharSequence(str, start, count);
        }
    }

    /**
     * Checks if start == 0 and count == length of CharSequence
     * It does this check only for String, StringBuilder and StringBuffer classes which have a fast way to check length
     *
     * Calculating length on GStringImpl requires building the result which is costly.
     * This helper method is to avoid calling length on other that String, StringBuilder and StringBuffer classes
     * when checking if the input CharSequence instance is already the same as the requested sub sequence
     *
     * @param str CharSequence input
     * @param start start index
     * @param count length on sub sequence
     * @return true if input is String, StringBuilder or StringBuffer class, start is 0 and count is length of input sequence
     */
    public static boolean canUseOriginalForSubSequence(CharSequence str, int start, int count) {
        if (start != 0) {
            return false;
        }
        Class csqClass = str.getClass();
        return (csqClass == String.class || csqClass == StringBuilder.class || csqClass == StringBuffer.class) && count == str.length();
    }

    public static CharSequence createSingleCharSequence(int c) {
        return new SingleCharCharSequence(c);
    }

    public static CharSequence createSingleCharSequence(char ch) {
        return new SingleCharCharSequence(ch);
    }

    /**
     * Writes a CharSequence instance in the most optimal way to the target writer
     *
     *
     * @param target writer
     * @param csq source CharSequence instance
     * @param start start/offset index
     * @param end end index + 1
     * @throws IOException
     */
    public static void writeCharSequence(Writer target, CharSequence csq, int start, int end) throws IOException {
        Class csqClass = csq.getClass();
        if (csqClass == String.class) {
            target.write((String) csq, start, end - start);
        }
        else if (csqClass == StringBuffer.class) {
            char[] buf = new char[end - start];
            ((StringBuffer) csq).getChars(start, end, buf, 0);
            target.write(buf);
        }
        else if (csqClass == StringBuilder.class) {
            char[] buf = new char[end - start];
            ((StringBuilder) csq).getChars(start, end, buf, 0);
            target.write(buf);
        }
        else if (csq instanceof CharArrayAccessible) {
            char[] buf = new char[end - start];
            ((CharArrayAccessible) csq).getChars(start, end, buf, 0);
            target.write(buf);
        }
        else {
            String str = csq.subSequence(start, end).toString();
            target.write(str, 0, str.length());
        }
    }

    public static void writeCharSequence(Writer target, CharSequence csq) throws IOException {
        writeCharSequence(target, csq, 0, csq.length());
    }

    /**
     * Provides an optimized way to copy CharSequence content to target array.
     * Uses getChars method available on String, StringBuilder and StringBuffer classes.
     *
     * Characters are copied from the source sequence csq into the
     * destination character array dst. The first character to
     * be copied is at index srcBegin; the last character to
     * be copied is at index srcEnd-1. The total number of
     * characters to be copied is srcEnd-srcBegin. The
     * characters are copied into the subarray of dst starting
     * at index dstBegin and ending at index:
     * 

     * dstbegin + (srcEnd-srcBegin) - 1
     * 
* * @param csq the source CharSequence instance. * @param srcBegin start copying at this offset. * @param srcEnd stop copying at this offset. * @param dst the array to copy the data into. * @param dstBegin offset into dst. * @throws NullPointerException if dst is * null. * @throws IndexOutOfBoundsException if any of the following is true: *
    *
  • srcBegin is negative *
  • dstBegin is negative *
  • the srcBegin argument is greater than * the srcEnd argument. *
  • srcEnd is greater than * this.length(). *
  • dstBegin+srcEnd-srcBegin is greater than * dst.length *
*/ public static void getChars(CharSequence csq, int srcBegin, int srcEnd, char[] dst, int dstBegin) { Class csqClass = csq.getClass(); if (csqClass == String.class) { ((String) csq).getChars(srcBegin, srcEnd, dst, dstBegin); } else if (csqClass == StringBuffer.class) { ((StringBuffer) csq).getChars(srcBegin, srcEnd, dst, dstBegin); } else if (csqClass == StringBuilder.class) { ((StringBuilder) csq).getChars(srcBegin, srcEnd, dst, dstBegin); } else if (csq instanceof CharArrayAccessible) { ((CharArrayAccessible) csq).getChars(srcBegin, srcEnd, dst, dstBegin); } else { String str = csq.subSequence(srcBegin, srcEnd).toString(); str.getChars(0, str.length(), dst, dstBegin); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy