1 /*
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
2790 private void printDateTime(Object arg, Locale l) throws IOException {
2791 if (arg == null) {
2792 print("null");
2793 return;
2794 }
2795 Calendar cal = null;
2796
2797 // Instead of Calendar.setLenient(true), perhaps we should
2798 // wrap the IllegalArgumentException that might be thrown?
2799 if (arg instanceof Long) {
2800 // Note that the following method uses an instance of the
2801 // default time zone (TimeZone.getDefaultRef().
2802 cal = Calendar.getInstance(l == null ? Locale.US : l);
2803 cal.setTimeInMillis((Long)arg);
2804 } else if (arg instanceof Date) {
2805 // Note that the following method uses an instance of the
2806 // default time zone (TimeZone.getDefaultRef().
2807 cal = Calendar.getInstance(l == null ? Locale.US : l);
2808 cal.setTime((Date)arg);
2809 } else if (arg instanceof Calendar) {
2810 cal = (Calendar) ((Calendar)arg).clone();
2811 cal.setLenient(true);
2812 } else if (arg instanceof TemporalAccessor) {
2813 print((TemporalAccessor)arg, c, l);
2814 return;
2815 } else {
2816 failConversion(c, arg);
2817 }
2818 // Use the provided locale so that invocations of
2819 // localizedMagnitude() use optimizations for null.
2820 print(cal, c, l);
2821 }
2822
2823 private void printCharacter(Object arg) throws IOException {
2824 if (arg == null) {
2825 print("null");
2826 return;
2827 }
2828 String s = null;
2829 if (arg instanceof Character) {
2830 s = ((Character)arg).toString();
2831 } else if (arg instanceof Byte) {
2832 byte i = ((Byte)arg).byteValue();
2833 if (Character.isValidCodePoint(i))
3225 trailingSign(sb, neg);
3226 } else {
3227 sb.append(f.contains(Flags.UPPERCASE) ? "NAN" : "NaN");
3228 }
3229
3230 // justify based on width
3231 a.append(justify(sb.toString()));
3232 }
3233
3234 // !Double.isInfinite(value) && !Double.isNaN(value)
3235 private void print(StringBuilder sb, double value, Locale l,
3236 Flags f, char c, int precision, boolean neg)
3237 throws IOException
3238 {
3239 if (c == Conversion.SCIENTIFIC) {
3240 // Create a new FormattedFloatingDecimal with the desired
3241 // precision.
3242 int prec = (precision == -1 ? 6 : precision);
3243
3244 FormattedFloatingDecimal fd
3245 = new FormattedFloatingDecimal(value, prec,
3246 FormattedFloatingDecimal.Form.SCIENTIFIC);
3247
3248 char[] v = new char[MAX_FD_CHARS];
3249 int len = fd.getChars(v);
3250
3251 char[] mant = addZeros(mantissa(v, len), prec);
3252
3253 // If the precision is zero and the '#' flag is set, add the
3254 // requested decimal point.
3255 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3256 mant = addDot(mant);
3257
3258 char[] exp = (value == 0.0)
3259 ? new char[] {'+','0','0'} : exponent(v, len);
3260
3261 int newW = width;
3262 if (width != -1)
3263 newW = adjustWidth(width - exp.length - 1, f, neg);
3264 localizedMagnitude(sb, mant, f, newW, l);
3265
3266 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3267
3268 Flags flags = f.dup().remove(Flags.GROUP);
3269 char sign = exp[0];
3270 assert(sign == '+' || sign == '-');
3271 sb.append(sign);
3272
3273 char[] tmp = new char[exp.length - 1];
3274 System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3275 sb.append(localizedMagnitude(null, tmp, flags, -1, l));
3276 } else if (c == Conversion.DECIMAL_FLOAT) {
3277 // Create a new FormattedFloatingDecimal with the desired
3278 // precision.
3279 int prec = (precision == -1 ? 6 : precision);
3280
3281 FormattedFloatingDecimal fd
3282 = new FormattedFloatingDecimal(value, prec,
3283 FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
3284
3285 // MAX_FD_CHARS + 1 (round?)
3286 char[] v = new char[MAX_FD_CHARS + 1
3287 + Math.abs(fd.getExponent())];
3288 int len = fd.getChars(v);
3289
3290 char[] mant = addZeros(mantissa(v, len), prec);
3291
3292 // If the precision is zero and the '#' flag is set, add the
3293 // requested decimal point.
3294 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3295 mant = addDot(mant);
3296
3297 int newW = width;
3298 if (width != -1)
3299 newW = adjustWidth(width, f, neg);
3300 localizedMagnitude(sb, mant, f, newW, l);
3301 } else if (c == Conversion.GENERAL) {
3302 int prec = precision;
3303 if (precision == -1)
3304 prec = 6;
3305 else if (precision == 0)
3306 prec = 1;
3307
3308 FormattedFloatingDecimal fd
3309 = new FormattedFloatingDecimal(value, prec,
3310 FormattedFloatingDecimal.Form.GENERAL);
3311
3312 // MAX_FD_CHARS + 1 (round?)
3313 char[] v = new char[MAX_FD_CHARS + 1
3314 + Math.abs(fd.getExponent())];
3315 int len = fd.getChars(v);
3316
3317 char[] exp = exponent(v, len);
3318 if (exp != null) {
3319 prec -= 1;
3320 } else {
3321 prec = prec - (value == 0 ? 0 : fd.getExponentRounded()) - 1;
3322 }
3323
3324 char[] mant = addZeros(mantissa(v, len), prec);
3325 // If the precision is zero and the '#' flag is set, add the
3326 // requested decimal point.
3327 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3328 mant = addDot(mant);
3329
3330 int newW = width;
3331 if (width != -1) {
3332 if (exp != null)
3333 newW = adjustWidth(width - exp.length - 1, f, neg);
3334 else
3335 newW = adjustWidth(width, f, neg);
3336 }
3337 localizedMagnitude(sb, mant, f, newW, l);
3338
3339 if (exp != null) {
3340 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3341
3342 Flags flags = f.dup().remove(Flags.GROUP);
3343 char sign = exp[0];
3344 assert(sign == '+' || sign == '-');
3363 sb.append(upper ? "0X" : "0x");
3364
3365 if (f.contains(Flags.ZERO_PAD))
3366 for (int i = 0; i < width - s.length() - 2; i++)
3367 sb.append('0');
3368
3369 int idx = s.indexOf('p');
3370 va = s.substring(0, idx).toCharArray();
3371 if (upper) {
3372 String tmp = new String(va);
3373 // don't localize hex
3374 tmp = tmp.toUpperCase(Locale.US);
3375 va = tmp.toCharArray();
3376 }
3377 sb.append(prec != 0 ? addZeros(va, prec) : va);
3378 sb.append(upper ? 'P' : 'p');
3379 sb.append(s.substring(idx+1));
3380 }
3381 }
3382
3383 private char[] mantissa(char[] v, int len) {
3384 int i;
3385 for (i = 0; i < len; i++) {
3386 if (v[i] == 'e')
3387 break;
3388 }
3389 char[] tmp = new char[i];
3390 System.arraycopy(v, 0, tmp, 0, i);
3391 return tmp;
3392 }
3393
3394 private char[] exponent(char[] v, int len) {
3395 int i;
3396 for (i = len - 1; i >= 0; i--) {
3397 if (v[i] == 'e')
3398 break;
3399 }
3400 if (i == -1)
3401 return null;
3402 char[] tmp = new char[len - i - 1];
3403 System.arraycopy(v, i + 1, tmp, 0, len - i - 1);
3404 return tmp;
3405 }
3406
3407 // Add zeros to the requested precision.
3408 private char[] addZeros(char[] v, int prec) {
3409 // Look for the dot. If we don't find one, the we'll need to add
3410 // it before we add the zeros.
3411 int i;
3412 for (i = 0; i < v.length; i++) {
3413 if (v[i] == '.')
3414 break;
3415 }
3416 boolean needDot = false;
3417 if (i == v.length) {
3418 needDot = true;
3419 }
3420
3421 // Determine existing precision.
3422 int outPrec = v.length - i - (needDot ? 0 : 1);
3423 assert (outPrec <= prec);
3424 if (outPrec == prec)
3425 return v;
3426
|
1 /*
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
2790 private void printDateTime(Object arg, Locale l) throws IOException {
2791 if (arg == null) {
2792 print("null");
2793 return;
2794 }
2795 Calendar cal = null;
2796
2797 // Instead of Calendar.setLenient(true), perhaps we should
2798 // wrap the IllegalArgumentException that might be thrown?
2799 if (arg instanceof Long) {
2800 // Note that the following method uses an instance of the
2801 // default time zone (TimeZone.getDefaultRef().
2802 cal = Calendar.getInstance(l == null ? Locale.US : l);
2803 cal.setTimeInMillis((Long)arg);
2804 } else if (arg instanceof Date) {
2805 // Note that the following method uses an instance of the
2806 // default time zone (TimeZone.getDefaultRef().
2807 cal = Calendar.getInstance(l == null ? Locale.US : l);
2808 cal.setTime((Date)arg);
2809 } else if (arg instanceof Calendar) {
2810 cal = (Calendar) ((Calendar) arg).clone();
2811 cal.setLenient(true);
2812 } else if (arg instanceof TemporalAccessor) {
2813 print((TemporalAccessor) arg, c, l);
2814 return;
2815 } else {
2816 failConversion(c, arg);
2817 }
2818 // Use the provided locale so that invocations of
2819 // localizedMagnitude() use optimizations for null.
2820 print(cal, c, l);
2821 }
2822
2823 private void printCharacter(Object arg) throws IOException {
2824 if (arg == null) {
2825 print("null");
2826 return;
2827 }
2828 String s = null;
2829 if (arg instanceof Character) {
2830 s = ((Character)arg).toString();
2831 } else if (arg instanceof Byte) {
2832 byte i = ((Byte)arg).byteValue();
2833 if (Character.isValidCodePoint(i))
3225 trailingSign(sb, neg);
3226 } else {
3227 sb.append(f.contains(Flags.UPPERCASE) ? "NAN" : "NaN");
3228 }
3229
3230 // justify based on width
3231 a.append(justify(sb.toString()));
3232 }
3233
3234 // !Double.isInfinite(value) && !Double.isNaN(value)
3235 private void print(StringBuilder sb, double value, Locale l,
3236 Flags f, char c, int precision, boolean neg)
3237 throws IOException
3238 {
3239 if (c == Conversion.SCIENTIFIC) {
3240 // Create a new FormattedFloatingDecimal with the desired
3241 // precision.
3242 int prec = (precision == -1 ? 6 : precision);
3243
3244 FormattedFloatingDecimal fd
3245 = FormattedFloatingDecimal.valueOf(value, prec,
3246 FormattedFloatingDecimal.Form.SCIENTIFIC);
3247
3248 char[] mant = addZeros(fd.getMantissa(), prec);
3249
3250 // If the precision is zero and the '#' flag is set, add the
3251 // requested decimal point.
3252 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3253 mant = addDot(mant);
3254
3255 char[] exp = (value == 0.0)
3256 ? new char[] {'+','0','0'} : fd.getExponent();
3257
3258 int newW = width;
3259 if (width != -1)
3260 newW = adjustWidth(width - exp.length - 1, f, neg);
3261 localizedMagnitude(sb, mant, f, newW, l);
3262
3263 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3264
3265 Flags flags = f.dup().remove(Flags.GROUP);
3266 char sign = exp[0];
3267 assert(sign == '+' || sign == '-');
3268 sb.append(sign);
3269
3270 char[] tmp = new char[exp.length - 1];
3271 System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3272 sb.append(localizedMagnitude(null, tmp, flags, -1, l));
3273 } else if (c == Conversion.DECIMAL_FLOAT) {
3274 // Create a new FormattedFloatingDecimal with the desired
3275 // precision.
3276 int prec = (precision == -1 ? 6 : precision);
3277
3278 FormattedFloatingDecimal fd
3279 = FormattedFloatingDecimal.valueOf(value, prec,
3280 FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
3281
3282 char[] mant = addZeros(fd.getMantissa(), prec);
3283
3284 // If the precision is zero and the '#' flag is set, add the
3285 // requested decimal point.
3286 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3287 mant = addDot(mant);
3288
3289 int newW = width;
3290 if (width != -1)
3291 newW = adjustWidth(width, f, neg);
3292 localizedMagnitude(sb, mant, f, newW, l);
3293 } else if (c == Conversion.GENERAL) {
3294 int prec = precision;
3295 if (precision == -1)
3296 prec = 6;
3297 else if (precision == 0)
3298 prec = 1;
3299
3300 FormattedFloatingDecimal fd
3301 = FormattedFloatingDecimal.valueOf(value, prec,
3302 FormattedFloatingDecimal.Form.GENERAL);
3303
3304 char[] exp = fd.getExponent();
3305 if (exp != null) {
3306 prec -= 1;
3307 } else {
3308 prec = prec - (value == 0 ? 0 : fd.getExponentRounded()) - 1;
3309 }
3310
3311 char[] mant = addZeros(fd.getMantissa(), prec);
3312 // If the precision is zero and the '#' flag is set, add the
3313 // requested decimal point.
3314 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3315 mant = addDot(mant);
3316
3317 int newW = width;
3318 if (width != -1) {
3319 if (exp != null)
3320 newW = adjustWidth(width - exp.length - 1, f, neg);
3321 else
3322 newW = adjustWidth(width, f, neg);
3323 }
3324 localizedMagnitude(sb, mant, f, newW, l);
3325
3326 if (exp != null) {
3327 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3328
3329 Flags flags = f.dup().remove(Flags.GROUP);
3330 char sign = exp[0];
3331 assert(sign == '+' || sign == '-');
3350 sb.append(upper ? "0X" : "0x");
3351
3352 if (f.contains(Flags.ZERO_PAD))
3353 for (int i = 0; i < width - s.length() - 2; i++)
3354 sb.append('0');
3355
3356 int idx = s.indexOf('p');
3357 va = s.substring(0, idx).toCharArray();
3358 if (upper) {
3359 String tmp = new String(va);
3360 // don't localize hex
3361 tmp = tmp.toUpperCase(Locale.US);
3362 va = tmp.toCharArray();
3363 }
3364 sb.append(prec != 0 ? addZeros(va, prec) : va);
3365 sb.append(upper ? 'P' : 'p');
3366 sb.append(s.substring(idx+1));
3367 }
3368 }
3369
3370 // Add zeros to the requested precision.
3371 private char[] addZeros(char[] v, int prec) {
3372 // Look for the dot. If we don't find one, the we'll need to add
3373 // it before we add the zeros.
3374 int i;
3375 for (i = 0; i < v.length; i++) {
3376 if (v[i] == '.')
3377 break;
3378 }
3379 boolean needDot = false;
3380 if (i == v.length) {
3381 needDot = true;
3382 }
3383
3384 // Determine existing precision.
3385 int outPrec = v.length - i - (needDot ? 0 : 1);
3386 assert (outPrec <= prec);
3387 if (outPrec == prec)
3388 return v;
3389
|