package org.basex.query.util.format; import static org.basex.util.Token.*; import org.basex.util.TokenBuilder; /** * English language formatter. Can be instantiated via {@link Formatter#get}. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ final class FormatterEN extends Formatter { /** Written number (0). */ private static final byte[] ZERO = token("Zero"); /** Written numbers (1-20). */ private static final byte[][] WORDS = tokens("", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"); /** Written numbers (20-100). */ private static final byte[][] WORDS10 = tokens("", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"); /** Written numbers (100, 1000, ...). */ private static final byte[][] WORDS100 = tokens("Hundred", "Thousand", "Million", "Billion", "Trillion", "Quadrillion", "Quintillion"); /** Units (100, 1000, ...). */ private static final long[] UNITS100 = { 100, 1000, 1000000, 1000000000, 1000000000000L, 1000000000000000L, 1000000000000000000L }; /** Ordinal Numbers (1-20). */ private static final byte[][] ORDINALS = tokens("", "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth", "Eleventh", "Twelfth", "Thirteenth", "Fourteenth", "Fifteenth", "Sixteenth", "Seventeenth", "Eighteenth", "Nineteenth"); /** Ordinal Numbers (20-100). */ private static final byte[][] ORDINALS10 = tokens("", "Tenth", "Twentieth", "Thirtieth", "Fortieth", "Fiftieth", "Sixtieth", "Seventieth", "Eightieth", "Ninetieth"); /** Days. */ private static final byte[][] DAYS = tokens("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"); /** Months. */ private static final byte[][] MONTHS = tokens( "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); /** AM/PM Markers. */ private static final byte[][] AMPM = tokens("AM", "PM"); /** And. */ private static final byte[] AND = token("and"); /** Ordinal suffixes (st, nr, rd, th). */ private static final byte[][] ORDSUFFIX = tokens("st", "nd", "rd", "th"); /** Eras: BC, AD. */ private static final byte[][] ERAS = tokens("BC", "AD"); @Override public byte[] word(final long n, final byte[] ord) { final TokenBuilder tb = new TokenBuilder(); if(n == 0) tb.add(ZERO); else word(tb, n, ord); return tb.finish(); } @Override public byte[] ordinal(final long n, final byte[] ord) { if(ord == null) return EMPTY; final int f = (int) (n % 10); return ORDSUFFIX[f > 0 && f < 4 && n % 100 / 10 != 1 ? f - 1 : 3]; } @Override public byte[] month(final int n, final int min, final int max) { final TokenBuilder tb = new TokenBuilder(substring(MONTHS[n], 0, max)); while(tb.size() < min) tb.add(' '); return tb.finish(); } @Override public byte[] day(final int n, final int min, final int max) { final TokenBuilder tb = new TokenBuilder(substring(DAYS[n], 0, max)); while(tb.size() < min) tb.add(' '); return tb.finish(); } @Override public byte[] ampm(final boolean am) { return AMPM[am ? 0 : 1]; } @Override public byte[] calendar() { return ERAS[1]; } @Override public byte[] era(final int year) { return ERAS[year < 0 ? 0 : 1]; } // PRIVATE METHODS ========================================================== /** * Creates a word character sequence for the specified number. * @param tb token builder * @param n number to be formatted * @param ord ordinal suffix */ private static void word(final TokenBuilder tb, final long n, final byte[] ord) { if(n == 0) { //tb.add(ZERO); } else if(n < 20) { tb.add((ord != null ? ORDINALS : WORDS)[(int) n]); } else if(n < 100) { final int r = (int) (n % 10); if(r == 0) { tb.add((ord != null ? ORDINALS10 : WORDS10)[(int) n / 10]); } else { tb.add(WORDS10[(int) n / 10]).add(' '); tb.add((ord != null ? ORDINALS : WORDS)[r]); } } else { for(int w = WORDS100.length - 1; w >= 0; w--) { final long f = UNITS100[w]; if(n < f) continue; word(tb, n / f, null); tb.add(' ').add(WORDS100[w]); final long r = n % f; if(r == 0) { if(ord != null) tb.add(ORDSUFFIX[3]); } else { tb.add(' '); if(r < 100) tb.add(AND).add(' '); } word(tb, r, ord); break; } } } }