001: /**
002: *
003: */package clime.messadmin.utils;
004:
005: import java.text.FieldPosition;
006: import java.text.NumberFormat;
007: import java.text.ParsePosition;
008: import java.util.Locale;
009:
010: /**
011: * Formats a number of bytes, adding a suffix
012: * @author Cédrik LIME
013: */
014: public class BytesFormat extends NumberFormat {
015: protected static final int DEFAULT_FRACTIONS_DIGITS = 2;
016:
017: protected static final double KB = 1024;
018: protected static final double MB = KB * 1024;
019: protected static final double GB = MB * 1024;
020: protected static final double TB = GB * 1024;
021:
022: protected static final String B_STR = "B";
023: protected static final String KB_STR = "KB";
024: protected static final String MB_STR = "MB";
025: protected static final String GB_STR = "GB";
026: protected static final String TB_STR = "TB";
027:
028: protected String B_suffix;
029: protected String KB_suffix;
030: protected String MB_suffix;
031: protected String GB_suffix;
032: protected String TB_suffix;
033:
034: protected Locale locale;
035:
036: /**
037: *
038: */
039: public BytesFormat(Locale locale, String separator) {
040: super ();
041: this .locale = locale;
042: if (separator == null) {
043: separator = "";
044: }
045: B_suffix = separator + B_STR;
046: KB_suffix = separator + KB_STR;
047: MB_suffix = separator + MB_STR;
048: GB_suffix = separator + GB_STR;
049: TB_suffix = separator + TB_STR;
050: }
051:
052: public static BytesFormat getBytesInstance(String separator) {
053: return new BytesFormat(Locale.getDefault(), separator); // super-class is not thread-safe
054: }
055:
056: public static BytesFormat getBytesInstance(Locale locale,
057: String separator) {
058: return new BytesFormat(locale, separator); // super-class is not thread-safe
059: }
060:
061: /**
062: * {@inheritDoc}
063: */
064: public StringBuffer format(double number, StringBuffer toAppendTo,
065: FieldPosition pos) {
066: if (number > Long.MAX_VALUE) {
067: throw new IllegalArgumentException(
068: "Can not format double numbers greater than Long.MAX_VALUE");//$NON-NLS-1$
069: }
070: return format((long) number, toAppendTo, pos);
071: }
072:
073: /**
074: * {@inheritDoc}
075: */
076: public StringBuffer format(long number, StringBuffer toAppendTo,
077: FieldPosition pos) {
078: bytesToHumanString(number, DEFAULT_FRACTIONS_DIGITS, toAppendTo);
079: return toAppendTo;
080: }
081:
082: /**
083: * {@inheritDoc}
084: */
085: public Number parse(String text, ParsePosition parsePosition) {
086: throw new UnsupportedOperationException();
087: }
088:
089: /**
090: * Smart formatter for bytes
091: * @param bytes
092: * @param toAppendTo buffer where to put the formated, human-readable String
093: */
094: protected void bytesToHumanString(long bytes, int fractionsDigits,
095: StringBuffer toAppendTo) {
096: if (bytes < 0) {
097: toAppendTo.append(bytes);
098: return;
099: }
100: double result = bytes;
101: String suffix = "";//$NON-NLS-1$
102: // Could use a ChoiceFormat() + MessageFormat() instead,
103: // but this is faster
104: if (bytes < KB) {
105: result = bytes;
106: suffix = B_suffix;
107: } else if (bytes >= KB && bytes < MB) {
108: result = round(bytes / KB, fractionsDigits);
109: suffix = KB_suffix;
110: } else if (bytes >= MB && bytes < GB) {
111: result = round(bytes / MB, fractionsDigits);
112: suffix = MB_suffix;
113: } else if (bytes >= GB && bytes < TB) {
114: result = round(bytes / GB, fractionsDigits);
115: suffix = GB_suffix;
116: } else {
117: result = round(bytes / TB, fractionsDigits);
118: suffix = TB_suffix;
119: }
120: NumberFormat nf = NumberFormat.getNumberInstance(locale);
121: nf.setMinimumFractionDigits(0);
122: nf.setMaximumFractionDigits(fractionsDigits);
123: nf.setGroupingUsed(super .isGroupingUsed());
124: toAppendTo.append(nf.format(result)).append(suffix);
125: }
126:
127: private double round(double value, int fractionsDigits) {
128: double powValue = Math.pow(10, fractionsDigits);
129: return Math.round(value * powValue) / powValue;
130: }
131: }
|