/* * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/** * A codec helping representing arrays in a string form. * * Encoding can be done in a controllable fashion (allowing the user to encode two * or more arrays in a time) or as a single operation.
*/ publicclass ArrayCodec<E> { privatestaticfinal String ELLIPSIS = "...";
/** * Creates a codec for a char array * * @param array source array * @return an ArrayCodec for the provided array
*/ publicstatic ArrayCodec<Character> of(char[] array) { var source = new ArrayList<Character>(array.length); for (char value: array) {
source.add(value);
} returnnew ArrayCodec<>(source);
}
/** * Creates a codec for a byte array * * @param array source array * @return an ArrayCodec for the provided array
*/ publicstatic ArrayCodec<Byte> of(byte[] array) { var source = new ArrayList<Byte>(array.length); for (byte value: array) {
source.add(value);
} returnnew ArrayCodec<>(source);
}
/** * Creates a codec for an int array * * @param array source array * @return an ArrayCodec for the provided array
*/ publicstatic ArrayCodec<Integer> of(int[] array) { var source = new ArrayList<Integer>(array.length); for (int value: array) {
source.add(value);
} returnnew ArrayCodec<>(source);
}
/** * Creates a codec for a long array * * @param array source array * @return an ArrayCodec for the provided array
*/ publicstatic ArrayCodec<Long> of(long[] array) { var source = new ArrayList<Long>(array.length); for (long value: array) {
source.add(value);
} returnnew ArrayCodec<>(source);
}
/** * Creates a codec for a String array * * @param array source array * @return an ArrayCodec for the provided array
*/ publicstatic ArrayCodec<String> of(String[] array) { var source = new ArrayList<String>(array.length); for (String value: array) {
source.add(value);
} returnnew ArrayCodec<>(source);
}
/** * Creates a codec for a generic Object array * * @param array source array * @return an ArrayCodec for the provided array
*/ publicstatic ArrayCodec<Object> of(Object[] array) { var source = new ArrayList<Object>(array.length); for (Object value: array) {
source.add(value);
} returnnew ArrayCodec<Object>(source);
}
/** * Creates a codec for a generic array, trying to recognize its component type * * @param array source array * @throws IllegalArgumentException if {@code array}'s component type is not supported * @return an ArrayCodec for the provided array
*/ publicstatic ArrayCodec<?> of(Object array) { var type = array.getClass().getComponentType(); if (type == byte.class) { return ArrayCodec.of((byte[])array);
} elseif (type == int.class) { return ArrayCodec.of((int[])array);
} elseif (type == long.class) { return ArrayCodec.of((long[])array);
} elseif (type == char.class) { return ArrayCodec.of((char[])array);
} elseif (type == String.class) { return ArrayCodec.of((String[])array);
} elseif (!type.isPrimitive() && !type.isArray()) { return ArrayCodec.of((Object[])array);
}
/** * Formats an array at-once. * The array is enclosed in brackets, its elements are separated with * commas. String elements are additionally surrounded by double quotes. * Unprintable symbols are C-stye escaped. * * <p>Sample outputs: * * <pre> * [0, 1, 2, 3, 4] * ["one", "first", "tree"] * [object1, object2, object3] * [a, b, \n, \u0002/, c] * </pre> * * @throws IllegalArgumentException if {@code array}'s component type is not supported * @return an ArrayCodec for the provided array
*/ publicstatic String format(Object array) { var codec = ArrayCodec.of(array);
codec.startFormatting(0, -1); while (!codec.isExhausted()) {
codec.formatNext();
codec.appendFormatted();
} return codec.getEncoded();
}
/** * Starts formatting with the given parameters. * * @param startIdx first element's index to start formattig with * @param maxWidth maximum allowed formatting width (in characters). * @return an ArrayCodec for the provided array
*/ publicvoid startFormatting(int startIdx, int maxWidth) {
encoded = new StringBuilder(startIdx == 0 ? "[" : ELLIPSIS);
exhausted = false; this.maxWidth = maxWidth;
bounded = (maxWidth > 0);
idx = startIdx;
}
/** * Format next element, store it in the internal element storage.
*/ publicvoid formatNext() { int limit = source.size();
/** * Append formatted element to internal StringBuilder. * * The formatted-so-far string can be accessed via {@link #getEncoded} * no elements in array left the method silently does nothing.
*/ publicvoid appendFormatted() { if (exhausted) { return;
}
/** * Aligns the element by another codec. * * If another codec's last encoded element string is longer than this * codec's, widens this codec's encoded element with spaces so the * two strings have the same length; * * @param another Another codec to compare encoded element width with
*/ publicvoid alignBy(ArrayCodec<E> another) { if (!element.equals("") && !element.equals("]")) { int delta = another.element.length() - element.length(); if (delta > 0) {
element = Format.paddingForWidth(delta) + element;
}
}
}
/** * Indicates if there are no elements left in the source array * * @return {@code true} if there are no elements left, {@code false} otherwise
*/ publicboolean isExhausted() { return exhausted;
}
/** * Returns the string encoded-so-far * * @return the string encoded-so-far
*/ public String getEncoded() { return encoded.toString();
}
/** * Returns the length of the string encoded-so-far * * @return the length of the string encoded-so-far
*/ publicint getEncodedLength() { return encoded.length();
}
/** * Returns the length of the last encoded element * * @return the length of the last encoded element
*/ publicint getElementLength() { return element.length();
}
/** * Finds and returns the first mismatch index in another codec * * @param another a codec mismatch with whom is to be found * @return the first mismatched element's index or -1 if arrays are identical
*/ publicint findMismatchIndex(ArrayCodec<E> another) { int result = 0; while ((source.size() > result) && (another.source.size() > result)) {
Object first = source.get(result);
Object second = another.source.get(result);
if (first == null || second == null) { if (first == null && second == null) { continue; // Both elements are null (i.e. equal)
} else { return result; // Only one element is null, here's the failure index
}
}
if (!first.equals(second)) { return result;
}
result++;
}
return source.size() != another.source.size()
? result // Lengths are different, but the shorter arrays is a preffix to the longer array.
: -1; // Arrays are identical, there's no mismatch index
}
/** * Indicates whether source array for another codec is equal to this codec's array * * @return {@code true} if source arrays are equal, {@code false} otherwise
*/ publicboolean equals(ArrayCodec<E> another) { return source.equals(another.source);
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.