| /******************************************************************************* |
| * Copyright (c) 2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.equinox.p2.internal.repository.comparator.java; |
| |
| public final class CharOperation { |
| public static final char[] This = "this".toCharArray(); //$NON-NLS-1$ |
| |
| public static final char[] JAVA_LANG_ANNOTATION_DOCUMENTED = "Ljava/lang/annotation/Documented;".toCharArray(); //$NON-NLS-1$ |
| public static final char[] JAVA_LANG_ANNOTATION_ELEMENTTYPE = "Ljava/lang/annotation/ElementType;".toCharArray(); //$NON-NLS-1$ |
| public static final char[] JAVA_LANG_ANNOTATION_RETENTION = "Ljava/lang/annotation/Retention;".toCharArray(); //$NON-NLS-1$ |
| public static final char[] JAVA_LANG_ANNOTATION_RETENTIONPOLICY = "Ljava/lang/annotation/RetentionPolicy;".toCharArray(); //$NON-NLS-1$ |
| public static final char[] JAVA_LANG_ANNOTATION_TARGET = "Ljava/lang/annotation/Target;".toCharArray(); //$NON-NLS-1$ |
| public static final char[] JAVA_LANG_DEPRECATED = "Ljava/lang/Deprecated;".toCharArray(); //$NON-NLS-1$ |
| public static final char[] JAVA_LANG_ANNOTATION_INHERITED = "Ljava/lang/annotation/Inherited;".toCharArray(); //$NON-NLS-1$ |
| /** |
| * Constant for an empty char array |
| */ |
| public static final char[] NO_CHAR = new char[0]; |
| |
| /** |
| * Constant for an empty char array with two dimensions. |
| */ |
| public static final char[][] NO_CHAR_CHAR = new char[0][]; |
| |
| /** |
| * Answers a hashcode for the array |
| * |
| * @param array the array for which a hashcode is required |
| * @return the hashcode |
| * @throws NullPointerException if array is null |
| */ |
| public static final int hashCode(char[] array) { |
| int length = array.length; |
| int hash = length == 0 ? 31 : array[0]; |
| if (length < 8) { |
| for (int i = length; --i > 0;) |
| hash = (hash * 31) + array[i]; |
| } else { |
| // 8 characters is enough to compute a decent hash code, don't waste time examining every character |
| for (int i = length - 1, last = i > 16 ? i - 16 : 0; i > last; i -= 2) |
| hash = (hash * 31) + array[i]; |
| } |
| return hash & 0x7FFFFFFF; |
| } |
| |
| /** |
| * Answers the last index in the array for which the corresponding character is |
| * equal to toBeFound starting from the end of the array. |
| * Answers -1 if no occurrence of this character is found. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * toBeFound = 'c' |
| * array = { ' a', 'b', 'c', 'd' , 'c', 'e' } |
| * result => 4 |
| * </pre> |
| * </li> |
| * <li><pre> |
| * toBeFound = 'e' |
| * array = { ' a', 'b', 'c', 'd' } |
| * result => -1 |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param toBeFound the character to search |
| * @param array the array to be searched |
| * @return the last index in the array for which the corresponding character is |
| * equal to toBeFound starting from the end of the array, -1 otherwise |
| * @throws NullPointerException if array is null |
| */ |
| public static final int lastIndexOf(char toBeFound, char[] array) { |
| for (int i = array.length; --i >= 0;) |
| if (toBeFound == array[i]) |
| return i; |
| return -1; |
| } |
| |
| /** |
| * Return a new array which is the split of the given array using the given divider. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * divider = 'b' |
| * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } |
| * result => { { 'a' }, { }, { 'a' }, { 'a' } } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * divider = 'c' |
| * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } |
| * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * divider = 'c' |
| * array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' } |
| * result => { { ' ', 'a', 'b', 'b', 'a', 'b', 'a', ' ' } } |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param divider the given divider |
| * @param array the given array |
| * @return a new array which is the split of the given array using the given divider |
| */ |
| public static final char[][] splitOn(char divider, char[] array) { |
| int length = array == null ? 0 : array.length; |
| if (length == 0) |
| return NO_CHAR_CHAR; |
| |
| int wordCount = 1; |
| for (int i = 0; i < length; i++) |
| if (array[i] == divider) |
| wordCount++; |
| char[][] split = new char[wordCount][]; |
| int last = 0, currentWord = 0; |
| for (int i = 0; i < length; i++) { |
| if (array[i] == divider) { |
| split[currentWord] = new char[i - last]; |
| System.arraycopy(array, last, split[currentWord++], 0, i - last); |
| last = i + 1; |
| } |
| } |
| split[currentWord] = new char[length - last]; |
| System.arraycopy(array, last, split[currentWord], 0, length - last); |
| return split; |
| } |
| |
| /** |
| * Answers the first index in the array for which the corresponding character is |
| * equal to toBeFound starting the search at index start. |
| * Answers -1 if no occurrence of this character is found. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * toBeFound = 'c' |
| * array = { ' a', 'b', 'c', 'd' } |
| * start = 2 |
| * result => 2 |
| * </pre> |
| * </li> |
| * <li><pre> |
| * toBeFound = 'c' |
| * array = { ' a', 'b', 'c', 'd' } |
| * start = 3 |
| * result => -1 |
| * </pre> |
| * </li> |
| * <li><pre> |
| * toBeFound = 'e' |
| * array = { ' a', 'b', 'c', 'd' } |
| * start = 1 |
| * result => -1 |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param toBeFound the character to search |
| * @param array the array to be searched |
| * @param start the starting index |
| * @return the first index in the array for which the corresponding character is |
| * equal to toBeFound, -1 otherwise |
| * @throws NullPointerException if array is null |
| * @throws ArrayIndexOutOfBoundsException if start is lower than 0 |
| */ |
| public static final int indexOf(char toBeFound, char[] array, int start) { |
| for (int i = start; i < array.length; i++) |
| if (toBeFound == array[i]) |
| return i; |
| return -1; |
| } |
| |
| /** |
| * Answers a new array with prepending the prefix character and appending the suffix |
| * character at the end of the array. If array is null, it answers a new array containing the |
| * prefix and the suffix characters. |
| * <br> |
| * <br> |
| * For example:<br> |
| * <ol> |
| * <li><pre> |
| * prefix = 'a' |
| * array = { 'b' } |
| * suffix = 'c' |
| * => result = { 'a', 'b' , 'c' } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * prefix = 'a' |
| * array = null |
| * suffix = 'c' |
| * => result = { 'a', 'c' } |
| * </pre></li> |
| * </ol> |
| * |
| * @param prefix the prefix character |
| * @param array the array that is concatenated with the prefix and suffix characters |
| * @param suffix the suffix character |
| * @return the new array |
| */ |
| public static final char[] concat(char prefix, char[] array, char suffix) { |
| if (array == null) |
| return new char[] {prefix, suffix}; |
| |
| int length = array.length; |
| char[] result = new char[length + 2]; |
| result[0] = prefix; |
| System.arraycopy(array, 0, result, 1, length); |
| result[length + 1] = suffix; |
| return result; |
| } |
| |
| /** |
| * Answers the concatenation of the three arrays. It answers null if the three arrays are null. |
| * If first is null, it answers the concatenation of second and third. |
| * If second is null, it answers the concatenation of first and third. |
| * If third is null, it answers the concatenation of first and second. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * first = null |
| * second = { 'a' } |
| * third = { 'b' } |
| * => result = { ' a', 'b' } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * first = { 'a' } |
| * second = null |
| * third = { 'b' } |
| * => result = { ' a', 'b' } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * first = { 'a' } |
| * second = { 'b' } |
| * third = null |
| * => result = { ' a', 'b' } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * first = null |
| * second = null |
| * third = null |
| * => result = null |
| * </pre> |
| * </li> |
| * <li><pre> |
| * first = { 'a' } |
| * second = { 'b' } |
| * third = { 'c' } |
| * => result = { 'a', 'b', 'c' } |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param first the first array to concatenate |
| * @param second the second array to concatenate |
| * @param third the third array to concatenate |
| * |
| * @return the concatenation of the three arrays, or null if the three arrays are null. |
| */ |
| public static final char[] concat(char[] first, char[] second, char[] third) { |
| if (first == null) |
| return concat(second, third); |
| if (second == null) |
| return concat(first, third); |
| if (third == null) |
| return concat(first, second); |
| |
| int length1 = first.length; |
| int length2 = second.length; |
| int length3 = third.length; |
| char[] result = new char[length1 + length2 + length3]; |
| System.arraycopy(first, 0, result, 0, length1); |
| System.arraycopy(second, 0, result, length1, length2); |
| System.arraycopy(third, 0, result, length1 + length2, length3); |
| return result; |
| } |
| |
| /** |
| * Answers the concatenation of the two arrays. It answers null if the two arrays are null. |
| * If the first array is null, then the second array is returned. |
| * If the second array is null, then the first array is returned. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * first = null |
| * second = { 'a' } |
| * => result = { ' a' } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * first = { ' a' } |
| * second = null |
| * => result = { ' a' } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * first = { ' a' } |
| * second = { ' b' } |
| * => result = { ' a' , ' b' } |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param first the first array to concatenate |
| * @param second the second array to concatenate |
| * @return the concatenation of the two arrays, or null if the two arrays are null. |
| */ |
| public static final char[] concat(char[] first, char[] second) { |
| if (first == null) |
| return second; |
| if (second == null) |
| return first; |
| |
| int length1 = first.length; |
| int length2 = second.length; |
| char[] result = new char[length1 + length2]; |
| System.arraycopy(first, 0, result, 0, length1); |
| System.arraycopy(second, 0, result, length1, length2); |
| return result; |
| } |
| |
| /** |
| * Replace all occurrence of the character to be replaced with the replacement character in the |
| * given array. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } |
| * toBeReplaced = 'b' |
| * replacementChar = 'a' |
| * result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a' } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } |
| * toBeReplaced = 'c' |
| * replacementChar = 'a' |
| * result => No returned value, but array is now equals to { 'a' , 'b', 'b', 'a', 'b', 'a' } |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param array the given array |
| * @param toBeReplaced the character to be replaced |
| * @param replacementChar the replacement character |
| * @throws NullPointerException if the given array is null |
| */ |
| public static final void replace(char[] array, char toBeReplaced, char replacementChar) { |
| if (toBeReplaced != replacementChar) { |
| for (int i = 0, max = array.length; i < max; i++) { |
| if (array[i] == toBeReplaced) |
| array[i] = replacementChar; |
| } |
| } |
| } |
| |
| /** |
| * Replace all occurrence of the character to be replaced with the replacement character |
| * in a copy of the given array. Returns the given array if no occurrences of the character |
| * to be replaced are found. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } |
| * toBeReplaced = 'b' |
| * replacementChar = 'a' |
| * result => A new array that is equals to { 'a' , 'a', 'a', 'a', 'a', 'a' } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } |
| * toBeReplaced = 'c' |
| * replacementChar = 'a' |
| * result => The original array that remains unchanged. |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param array the given array |
| * @param toBeReplaced the character to be replaced |
| * @param replacementChar the replacement character |
| * @throws NullPointerException if the given array is null |
| * @since 3.1 |
| */ |
| public static final char[] replaceOnCopy(char[] array, char toBeReplaced, char replacementChar) { |
| |
| char[] result = null; |
| for (int i = 0, length = array.length; i < length; i++) { |
| char c = array[i]; |
| if (c == toBeReplaced) { |
| if (result == null) { |
| result = new char[length]; |
| System.arraycopy(array, 0, result, 0, i); |
| } |
| result[i] = replacementChar; |
| } else if (result != null) { |
| result[i] = c; |
| } |
| } |
| if (result == null) |
| return array; |
| return result; |
| } |
| |
| /** |
| * Answers the first index in the array for which the corresponding character is |
| * equal to toBeFound. Answers -1 if no occurrence of this character is found. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * toBeFound = 'c' |
| * array = { ' a', 'b', 'c', 'd' } |
| * result => 2 |
| * </pre> |
| * </li> |
| * <li><pre> |
| * toBeFound = 'e' |
| * array = { ' a', 'b', 'c', 'd' } |
| * result => -1 |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param toBeFound the character to search |
| * @param array the array to be searched |
| * @return the first index in the array for which the corresponding character is |
| * equal to toBeFound, -1 otherwise |
| * @throws NullPointerException if array is null |
| */ |
| public static final int indexOf(char toBeFound, char[] array) { |
| return indexOf(toBeFound, array, 0); |
| } |
| |
| /** |
| * Answers a new array which is a copy of the given array starting at the given start and |
| * ending at the given end. The given start is inclusive and the given end is exclusive. |
| * Answers null if start is greater than end, if start is lower than 0 or if end is greater |
| * than the length of the given array. If end equals -1, it is converted to the array length. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * array = { 'a' , 'b' } |
| * start = 0 |
| * end = 1 |
| * result => { 'a' } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * array = { 'a', 'b' } |
| * start = 0 |
| * end = -1 |
| * result => { 'a' , 'b' } |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param array the given array |
| * @param start the given starting index |
| * @param end the given ending index |
| * @return a new array which is a copy of the given array starting at the given start and |
| * ending at the given end |
| * @throws NullPointerException if the given array is null |
| */ |
| public static final char[] subarray(char[] array, int start, int end) { |
| if (end == -1) |
| end = array.length; |
| if (start > end) |
| return null; |
| if (start < 0) |
| return null; |
| if (end > array.length) |
| return null; |
| |
| char[] result = new char[end - start]; |
| System.arraycopy(array, start, result, 0, end - start); |
| return result; |
| } |
| |
| /** |
| * Answers a new array which is a copy of the given array starting at the given start and |
| * ending at the given end. The given start is inclusive and the given end is exclusive. |
| * Answers null if start is greater than end, if start is lower than 0 or if end is greater |
| * than the length of the given array. If end equals -1, it is converted to the array length. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * array = { { 'a' } , { 'b' } } |
| * start = 0 |
| * end = 1 |
| * result => { { 'a' } } |
| * </pre> |
| * </li> |
| * <li><pre> |
| * array = { { 'a' } , { 'b' } } |
| * start = 0 |
| * end = -1 |
| * result => { { 'a' }, { 'b' } } |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param array the given array |
| * @param start the given starting index |
| * @param end the given ending index |
| * @return a new array which is a copy of the given array starting at the given start and |
| * ending at the given end |
| * @throws NullPointerException if the given array is null |
| */ |
| public static final char[][] subarray(char[][] array, int start, int end) { |
| if (end == -1) |
| end = array.length; |
| if (start > end) |
| return null; |
| if (start < 0) |
| return null; |
| if (end > array.length) |
| return null; |
| |
| char[][] result = new char[end - start][]; |
| System.arraycopy(array, start, result, 0, end - start); |
| return result; |
| } |
| |
| /** |
| * Return a new array which is the split of the given array using the given divider. The given end |
| * is exclusive and the given start is inclusive. |
| * <br> |
| * <br> |
| * For example: |
| * <ol> |
| * <li><pre> |
| * divider = 'b' |
| * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } |
| * start = 2 |
| * end = 5 |
| * result => { { }, { 'a' }, { } } |
| * </pre> |
| * </li> |
| * </ol> |
| * |
| * @param divider the given divider |
| * @param array the given array |
| * @param start the given starting index |
| * @param end the given ending index |
| * @return a new array which is the split of the given array using the given divider |
| * @throws ArrayIndexOutOfBoundsException if start is lower than 0 or end is greater than the array length |
| */ |
| public static final char[][] splitOn(char divider, char[] array, int start, int end) { |
| int length = array == null ? 0 : array.length; |
| if (length == 0 || start > end) |
| return NO_CHAR_CHAR; |
| |
| int wordCount = 1; |
| for (int i = start; i < end; i++) |
| if (array[i] == divider) |
| wordCount++; |
| char[][] split = new char[wordCount][]; |
| int last = start, currentWord = 0; |
| for (int i = start; i < end; i++) { |
| if (array[i] == divider) { |
| split[currentWord] = new char[i - last]; |
| System.arraycopy(array, last, split[currentWord++], 0, i - last); |
| last = i + 1; |
| } |
| } |
| split[currentWord] = new char[end - last]; |
| System.arraycopy(array, last, split[currentWord], 0, end - last); |
| return split; |
| } |
| } |