/** * Copies the character from this text builder into the destination character array. * * @param srcBegin this text start index. * @param srcEnd this text end index (not included). * @param dst the destination array to copy the data into. * @param dstBegin the offset into the destination array. * @throws IndexOutOfBoundsException if <code>(srcBegin < 0) || * (dstBegin < 0) || (srcBegin > srcEnd) || (srcEnd > this.length()) * || ((dstBegin + srcEnd - srcBegin) > dst.length)</code> */ public final void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { if ((srcBegin < 0) || (srcBegin > srcEnd) || (srcEnd > this._length)) throw new IndexOutOfBoundsException(); for (int i = srcBegin, j = dstBegin; i < srcEnd; ) { char[] chars0 = _high[i >> B1]; int i0 = i & M1; int length = MathLib.min(C1 - i0, srcEnd - i); System.arraycopy(chars0, i0, dst, j, length); i += length; j += length; } }
/** * Appends the decimal representation of the specified <code>long</code> argument. * * @param l the <code>long</code> to format. * @return <code>this</code> */ public final TextBuilder append(long l) { if (l <= 0) { if (l == 0) return append("0"); if (l == Long.MIN_VALUE) // Negation would overflow. return append("-9223372036854775808"); append('-'); l = -l; } if (l <= Integer.MAX_VALUE) return append((int) l); append(l / 1000000000); int i = (int) (l % 1000000000); int digits = MathLib.digitLength(i); append("000000000", 0, 9 - digits); return append(i); }
/** * Appends the decimal representation of the specified <code>int</code> argument. * * @param i the <code>int</code> to format. * @return <code>this</code> */ public final TextBuilder append(int i) { if (i <= 0) { if (i == 0) return append("0"); if (i == Integer.MIN_VALUE) // Negation would overflow. return append("-2147483648"); append('-'); i = -i; } int digits = MathLib.digitLength(i); if (_capacity < _length + digits) increaseCapacity(); _length += digits; for (int index = _length - 1; ; index--) { int j = i / 10; _high[index >> B1][index & M1] = (char) ('0' + i - (j * 10)); if (j == 0) return this; i = j; } }
/** * Appends the characters from a subarray of the char array argument. * * @param chars the character array source. * @param offset the index of the first character to append. * @param length the number of character to append. * @return <code>this</code> * @throws IndexOutOfBoundsException if <code>(offset < 0) || * (length < 0) || ((offset + length) > chars.length)</code> */ public final TextBuilder append(char chars[], int offset, int length) { final int end = offset + length; if ((offset < 0) || (length < 0) || (end > chars.length)) throw new IndexOutOfBoundsException(); int newLength = _length + length; while (_capacity < newLength) { increaseCapacity(); } for (int i = offset, j = _length; i < end; ) { char[] dstChars = _high[j >> B1]; int dstBegin = j & M1; int inc = MathLib.min(C1 - dstBegin, end - i); System.arraycopy(chars, i, dstChars, dstBegin, inc); i += inc; j += inc; } _length = newLength; return this; }
/** * Appends a subsequence of the specified text. If the specified character sequence is <code>null * </code> this method is equivalent to <code>append("null")</code>. * * @param txt the text to append or <code>null</code>. * @param start the index of the first character to append. * @param end the index after the last character to append. * @return <code>this</code> * @throws IndexOutOfBoundsException if <code>(start < 0) || (end < 0) * || (start > end) || (end > txt.length())</code> */ public final TextBuilder append(Text txt, int start, int end) { if (txt == null) return append("null"); if ((start < 0) || (end < 0) || (start > end) || (end > txt.length())) throw new IndexOutOfBoundsException(); int newLength = _length + end - start; while (_capacity < newLength) { increaseCapacity(); } for (int i = start, j = _length; i < end; ) { char[] chars = _high[j >> B1]; int dstBegin = j & M1; int inc = MathLib.min(C1 - dstBegin, end - i); txt.getChars(i, (i += inc), chars, dstBegin); j += inc; } _length = newLength; return this; }
private final void appendFraction(long l, int digits, boolean showZero) { append('.'); if (l == 0) if (showZero) for (int i = 0; i < digits; i++) { append('0'); } else append('0'); else { // l is different from zero. int length = MathLib.digitLength(l); for (int j = length; j < digits; j++) { append('0'); // Add leading zeros. } if (!showZero) while (l % 10 == 0) { l /= 10; // Remove trailing zeros. } append(l); } }
/** * Prints out this text builder to the specified writer. * * @param writer the destination writer. */ public void print(Writer writer) throws IOException { for (int i = 0; i < _length; i += C1) { char[] chars = _high[i >> B1]; writer.write(chars, 0, MathLib.min(C1, _length - i)); } }
/** * Appends the textual representation of the specified <code>double</code> according to the * specified formatting arguments. * * @param d the <code>double</code> value. * @param digits the number of significative digits (excludes exponent) or <code>-1</code> to * mimic the standard library (16 or 17 digits). * @param scientific <code>true</code> to forces the use of the scientific notation (e.g. <code> * 1.23E3</code>); <code>false</code> otherwise. * @param showZero <code>true</code> if trailing fractional zeros are represented; <code>false * </code> otherwise. * @return <code>TypeFormat.format(d, digits, scientific, showZero, this)</code> * @throws IllegalArgumentException if <code>(digits > 19)</code>) */ public final TextBuilder append(double d, int digits, boolean scientific, boolean showZero) { if (digits > 19) throw new IllegalArgumentException("digits: " + digits); if (d != d) // NaN return append("NaN"); if (d == Double.POSITIVE_INFINITY) return append("Infinity"); if (d == Double.NEGATIVE_INFINITY) return append("-Infinity"); if (d == 0.0) { // Zero. if (digits < 0) return append("0.0"); append('0'); if (showZero) { append('.'); for (int j = 1; j < digits; j++) { append('0'); } } return this; } if (d < 0) { // Work with positive number. d = -d; append('-'); } // Find the exponent e such as: value == x.xxx * 10^e int e = MathLib.floorLog10(d); long m; if (digits < 0) { // Use 16 or 17 digits. // Try 17 digits. long m17 = MathLib.toLongPow10(d, (17 - 1) - e); // Check if we can use 16 digits. long m16 = m17 / 10; double dd = MathLib.toDoublePow10(m16, e - 16 + 1); if (dd == d) { // 16 digits is enough. digits = 16; m = m16; } else { // We cannot remove the last digit. digits = 17; m = m17; } } else // Use the specified number of digits. m = MathLib.toLongPow10(d, (digits - 1) - e); // Formats. if (scientific || (e >= digits)) { // Scientific notation has to be used ("x.xxxEyy"). long pow10 = POW10_LONG[digits - 1]; int k = (int) (m / pow10); // Single digit. append((char) ('0' + k)); m = m - pow10 * k; appendFraction(m, digits - 1, showZero); append('E'); append(e); } else { // Dot within the string ("xxxx.xxxxx"). int exp = digits - e - 1; if (exp < POW10_LONG.length) { long pow10 = POW10_LONG[exp]; long l = m / pow10; append(l); m = m - pow10 * l; } else append('0'); // Result of the division by a power of 10 larger than any long. appendFraction(m, exp, showZero); } return this; }
/** * Appends the textual representation of the specified <code>double</code>; the number of digits * is 17 or 16 when the 16 digits representation can be parsed back to the same <code>double * </code> (mimic the standard library formatting). * * @param d the <code>double</code> to format. * @return <code>append(d, -1, (MathLib.abs(d) >= 1E7) || * (MathLib.abs(d) < 0.001), false)</code> */ public final TextBuilder append(double d) { return append(d, -1, (MathLib.abs(d) >= 1E7) || (MathLib.abs(d) < 0.001), false); }
/** * Appends the textual representation of the specified <code>float</code>. * * @param f the <code>float</code> to format. * @return <code>append(f, 10, (abs(f) >= 1E7) || (abs(f) < 0.001), false)</code> */ public final TextBuilder append(float f) { return append(f, 10, (MathLib.abs(f) >= 1E7) || (MathLib.abs(f) < 0.001), false); }