Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        /// <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);
        }