/// <summary> /// Append a count to the string builder. /// </summary> /// /// <param name="unit">the unit</param> /// <param name="count">the count</param> /// <param name="cv">the format to use for displaying the count</param> /// <param name="useSep">whether to use the count separator, if available</param> /// <param name="name">the term name</param> /// <param name="last">true if this is the last unit to be formatted</param> /// <param name="sb">the string builder to which to append the text</param> /// <returns>index to use if might have required or optional suffix, or -1 if /// none required</returns> public int AppendCount(TimeUnit unit, bool omitCount, bool useDigitPrefix, int count, int cv, bool useSep, String name, bool last, StringBuilder sb) { if (cv == IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.HALF_FRACTION && dr.halves == null) { cv = IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.INTEGER; } if (!omitCount && useDigitPrefix && dr.digitPrefix != null) { sb.Append(dr.digitPrefix); } int index = unit.Ordinal(); switch (cv) { case IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.INTEGER: { if (!omitCount) { AppendInteger(count / 1000, 1, 10, sb); } } break; case IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.INTEGER_CUSTOM: { int val = count / 1000; // only custom names we have for now if (unit == IBM.ICU.Impl.Duration.TimeUnit.MINUTE && (dr.fiveMinutes != null || dr.fifteenMinutes != null)) { if (val != 0 && val % 5 == 0) { if (dr.fifteenMinutes != null && (val == 15 || val == 45)) { val = (val == 15) ? 1 : 3; if (!omitCount) { AppendInteger(val, 1, 10, sb); } name = dr.fifteenMinutes; index = 8; // hack break; } if (dr.fiveMinutes != null) { val = val / 5; if (!omitCount) { AppendInteger(val, 1, 10, sb); } name = dr.fiveMinutes; index = 9; // hack break; } } } if (!omitCount) { AppendInteger(val, 1, 10, sb); } } break; case IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.HALF_FRACTION: { // 0, 1/2, 1, 1-1/2... int v = count / 500; if (v != 1) { if (!omitCount) { AppendCountValue(count, 1, 0, sb); } } if ((v & 0x1) == 1) { // hack, using half name if (v == 1 && dr.halfNames != null && dr.halfNames[index] != null) { sb.Append(name); return((last) ? index : -1); } int solox = (v == 1) ? 0 : 1; if (dr.genders != null && dr.halves.Length > 2) { if (dr.genders[index] == IBM.ICU.Impl.Duration.Impl.DataRecord.EGender.F) { solox += 2; } } int hp = (dr.halfPlacements == null) ? IBM.ICU.Impl.Duration.Impl.DataRecord.EHalfPlacement.PREFIX : dr.halfPlacements[solox & 0x1]; String half = dr.halves[solox]; String measure = (dr.measures == null) ? null : dr.measures[index]; switch (hp) { case IBM.ICU.Impl.Duration.Impl.DataRecord.EHalfPlacement.PREFIX: sb.Append(half); break; case IBM.ICU.Impl.Duration.Impl.DataRecord.EHalfPlacement.AFTER_FIRST: { if (measure != null) { sb.Append(measure); sb.Append(half); if (useSep && !omitCount) { sb.Append(dr.countSep); } sb.Append(name); } else // ignore sep completely { sb.Append(name); sb.Append(half); return((last) ? index : -1); // might use suffix } } return(-1); // exit early case IBM.ICU.Impl.Duration.Impl.DataRecord.EHalfPlacement.LAST: { if (measure != null) { sb.Append(measure); } if (useSep && !omitCount) { sb.Append(dr.countSep); } sb.Append(name); sb.Append(half); } return((last) ? index : -1); // might use suffix } } } break; default: { int decimals = 1; switch (cv) { case IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.DECIMAL2: decimals = 2; break; case IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.DECIMAL3: decimals = 3; break; default: break; } if (!omitCount) { AppendCountValue(count, 1, decimals, sb); } } break; } if (!omitCount && useSep) { sb.Append(dr.countSep); } if (!omitCount && dr.measures != null && index < dr.measures.Length) { String measure_0 = dr.measures[index]; if (measure_0 != null) { sb.Append(measure_0); } } sb.Append(name); return((last) ? index : -1); }
private int ComputeForm(TimeUnit unit, int count, int cv, bool lastOfMultiple) { // first check if a particular form is forced by the countvariant. if // SO, just return that. otherwise convert the count to an integer // and use pluralization rules to determine which form to use. // careful, can't assume any forms but plural exist. if (trace) { System.Console.Error.WriteLine("pfd.cf unit: " + unit + " count: " + count + " cv: " + cv + " dr.pl: " + dr.pl); ILOG.J2CsMapping.Threading.ThreadWrapper.DumpStack(); } if (dr.pl == IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.NONE) { return(FORM_PLURAL); } // otherwise, assume we have at least a singular and plural form int val = count / 1000; switch (cv) { case IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.INTEGER: case IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.INTEGER_CUSTOM: { // do more analysis based on floor of count } break; case IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.HALF_FRACTION: { switch (dr.fractionHandling) { case IBM.ICU.Impl.Duration.Impl.DataRecord.EFractionHandling.FPLURAL: return(FORM_PLURAL); case IBM.ICU.Impl.Duration.Impl.DataRecord.EFractionHandling.FSINGULAR_PLURAL_ANDAHALF: case IBM.ICU.Impl.Duration.Impl.DataRecord.EFractionHandling.FSINGULAR_PLURAL: { // if half-floor is 1/2, use singular // else if half-floor is not integral, use plural // else do more analysis int v = (int)(count / 500); if (v == 1) { if (dr.halfNames != null && dr.halfNames[unit.Ordinal()] != null) { return(FORM_HALF_SPELLED); } return(FORM_SINGULAR_NO_OMIT); } if ((v & 0x1) == 1) { if (dr.pl == IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.ARABIC && v > 21) // hack { return(FORM_SINGULAR_NO_OMIT); } if (v == 3 && dr.pl == IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.PLURAL && dr.fractionHandling != IBM.ICU.Impl.Duration.Impl.DataRecord.EFractionHandling.FSINGULAR_PLURAL_ANDAHALF) { return(FORM_PLURAL); } } // it will display like an integer, so do more analysis } break; case IBM.ICU.Impl.Duration.Impl.DataRecord.EFractionHandling.FPAUCAL: { int v_0 = (int)(count / 500); if (v_0 == 1 || v_0 == 3) { return(FORM_PAUCAL); } // else use integral form } break; default: throw new InvalidOperationException(); } } break; default: { // for all decimals switch (dr.decimalHandling) { case IBM.ICU.Impl.Duration.Impl.DataRecord.EDecimalHandling.DPLURAL: break; case IBM.ICU.Impl.Duration.Impl.DataRecord.EDecimalHandling.DSINGULAR: return(FORM_SINGULAR_NO_OMIT); case IBM.ICU.Impl.Duration.Impl.DataRecord.EDecimalHandling.DSINGULAR_SUBONE: if (count < 1000) { return(FORM_SINGULAR_NO_OMIT); } break; case IBM.ICU.Impl.Duration.Impl.DataRecord.EDecimalHandling.DPAUCAL: if (dr.pl == IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.PAUCAL) { return(FORM_PAUCAL); } break; default: break; } return(FORM_PLURAL); } } // select among pluralization forms if (trace && count == 0) { System.Console.Error.WriteLine("EZeroHandling = " + dr.zeroHandling); } if (count == 0 && dr.zeroHandling == IBM.ICU.Impl.Duration.Impl.DataRecord.EZeroHandling.ZSINGULAR) { return(FORM_SINGULAR_SPELLED); } int form = FORM_PLURAL; switch (dr.pl) { case IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.NONE: break; // never get here case IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.PLURAL: { if (val == 1) { form = FORM_SINGULAR_SPELLED; // defaults to form_singular if no // spelled forms } } break; case IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.DUAL: { if (val == 2) { form = FORM_DUAL; } else if (val == 1) { form = FORM_SINGULAR; } } break; case IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.PAUCAL: { int v_1 = val; v_1 = v_1 % 100; if (v_1 > 20) { v_1 = v_1 % 10; } if (v_1 == 1) { form = FORM_SINGULAR; } else if (v_1 > 1 && v_1 < 5) { form = FORM_PAUCAL; } } break; /* * case EPluralization.RPT_DUAL_FEW: { int v = val; if (v > 20) { v = v * % 10; } if (v == 1) { form = FORM_SINGULAR; } else if (v == 2) { form * = FORM_DUAL; } else if (v > 2 && v < 5) { form = FORM_PAUCAL; } } * break; */ case IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.HEBREW: { if (val == 2) { form = FORM_DUAL; } else if (val == 1) { if (lastOfMultiple) { form = FORM_SINGULAR_SPELLED; } else { form = FORM_SINGULAR; } } else if (unit == IBM.ICU.Impl.Duration.TimeUnit.YEAR && val > 11) { form = FORM_SINGULAR_NO_OMIT; } } break; case IBM.ICU.Impl.Duration.Impl.DataRecord.EPluralization.ARABIC: { if (val == 2) { form = FORM_DUAL; } else if (val == 1) { form = FORM_SINGULAR; } else if (val > 10) { form = FORM_SINGULAR_NO_OMIT; } } break; default: System.Console.Error.WriteLine("dr.pl is " + dr.pl); throw new InvalidOperationException(); } return(form); }
/// <summary> /// Append the count and unit to the string builder. /// </summary> /// /// <param name="unit">the unit to append</param> /// <param name="count">the count of units, /// 1000</param> /// <param name="cv">the format to use for displaying the count</param> /// <param name="uv">the format to use for displaying the unit</param> /// <param name="useCountSep">if false, force no separator between count and unit</param> /// <param name="useDigitPrefix">if true, use the digit prefix</param> /// <param name="multiple">true if there are multiple units in this string</param> /// <param name="last">true if this is the last unit</param> /// <param name="wasSkipped">true if the unit(s) before this were skipped</param> /// <param name="sb">the string builder to which to append the text</param> /// <param name=" return true if will require skip marker"></param> public bool AppendUnit(TimeUnit unit, int count, int cv, int uv, bool useCountSep, bool useDigitPrefix, bool multiple, bool last, bool wasSkipped, StringBuilder sb) { int px = unit.Ordinal(); bool willRequireSkipMarker = false; if (dr.requiresSkipMarker != null && dr.requiresSkipMarker[px] && dr.skippedUnitMarker != null) { if (!wasSkipped && last) { sb.Append(dr.skippedUnitMarker); } willRequireSkipMarker = true; } if (uv != IBM.ICU.Impl.Duration.Impl.DataRecord.EUnitVariant.PLURALIZED) { bool useMedium = uv == IBM.ICU.Impl.Duration.Impl.DataRecord.EUnitVariant.MEDIUM; String[] names = (useMedium) ? dr.mediumNames : dr.shortNames; if (names == null || names[px] == null) { names = (useMedium) ? dr.shortNames : dr.mediumNames; } if (names != null && names[px] != null) { AppendCount(unit, false, false, count, cv, useCountSep, names[px], last, sb); // omit suffix, ok? return(false); // omit skip marker } } // check cv if (cv == IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.HALF_FRACTION && dr.halfSupport != null) { switch (dr.halfSupport[px]) { case IBM.ICU.Impl.Duration.Impl.DataRecord.EHalfSupport.YES: break; case IBM.ICU.Impl.Duration.Impl.DataRecord.EHalfSupport.ONE_PLUS: if (count > 1000) { break; } { { count = (count / 500) * 500; cv = IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.DECIMAL1; } break; } break; // else fall through to decimal case IBM.ICU.Impl.Duration.Impl.DataRecord.EHalfSupport.NO: { count = (count / 500) * 500; // round to 1/2 cv = IBM.ICU.Impl.Duration.Impl.DataRecord.ECountVariant.DECIMAL1; } break; } } String name = null; int form = ComputeForm(unit, count, cv, multiple && last); if (form == FORM_SINGULAR_SPELLED) { if (dr.singularNames == null) { form = FORM_SINGULAR; name = dr.pluralNames[px][form]; } else { name = dr.singularNames[px]; } } else if (form == FORM_SINGULAR_NO_OMIT) { name = dr.pluralNames[px][FORM_SINGULAR]; } else if (form == FORM_HALF_SPELLED) { name = dr.halfNames[px]; } else { try { name = dr.pluralNames[px][form]; } catch (NullReferenceException e) { System.Console.Out.WriteLine("Null Pointer in PeriodFormatterData[" + localeName + "].au px: " + px + " form: " + form + " pn: " + dr.pluralNames); throw e; } } if (name == null) { form = FORM_PLURAL; name = dr.pluralNames[px][form]; } bool omitCount = (form == FORM_SINGULAR_SPELLED || form == FORM_HALF_SPELLED) || (dr.omitSingularCount && form == FORM_SINGULAR) || (dr.omitDualCount && form == FORM_DUAL); int suffixIndex = AppendCount(unit, omitCount, useDigitPrefix, count, cv, useCountSep, name, last, sb); if (last && suffixIndex >= 0) { String suffix = null; if (dr.rqdSuffixes != null && suffixIndex < dr.rqdSuffixes.Length) { suffix = dr.rqdSuffixes[suffixIndex]; } if (suffix == null && dr.optSuffixes != null && suffixIndex < dr.optSuffixes.Length) { suffix = dr.optSuffixes[suffixIndex]; } if (suffix != null) { sb.Append(suffix); } } return(willRequireSkipMarker); }