public int compareInternal()

in utils/common/src/main/java/org/apache/brooklyn/util/text/NaturalOrderComparator.java [128:222]


    public int compareInternal(String a, String b) {

        int ia = 0, ib = 0;
        int nza = 0, nzb = 0;
        char ca, cb;
        int result;

        while (true) {
            // only count the number of zeroes leading the last number compared
            nza = nzb = 0;

            ca = charAt(a, ia); cb = charAt(b, ib);

            // skip over leading spaces or zeros
            while (Character.isSpaceChar(ca) || ca == '0') {
                if (ca == '0') {
                    nza++;
                } else {
                    // only count consecutive zeroes
                    nza = 0;
                }

                ca = charAt(a, ++ia);
            }

            while (Character.isSpaceChar(cb) || cb == '0') {
                if (cb == '0') {
                    nzb++;
                } else {
                    // only count consecutive zeroes
                    nzb = 0;
                }

                cb = charAt(b, ++ib);
            }

            // process run of digits
            if (Character.isDigit(ca) && Character.isDigit(cb)) {
                if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0) {
                    return result;
                }
                // numeric portion is the same; previously we incremented and checked again
                // which is inefficient (we keep checking remaining numbers here);
                // also if we want to compare on 0's after comparing remainder of string
                // we need to recurse here after skipping the digits we just checked above
                do {
                    ia++; ib++;
                    boolean aDigitsDone = ia >= a.length() || !Character.isDigit(charAt(a, ia));
                    boolean bDigitsDone = ib >= b.length() || !Character.isDigit(charAt(b, ib));
                    if (aDigitsDone != bDigitsDone) {
                        // sanity check
                        throw new IllegalStateException("Digit sequence lengths should have matched, '"+a+"' v '"+b+"'");
                    }
                    if (aDigitsDone) break;
                } while (true);
                if (ia < a.length() || ib < b.length()) {
                    if (ia >= a.length()) return -1;  // only b has more chars
                    if (ib >= b.length()) return 1;  // only a has more chars
                    // both have remaining chars; neither is numeric due to compareRight; recurse into remaining
                    if ((result = compareInternal(a.substring(ia), b.substring(ib))) != 0) {
                        return result;
                    }
                }
                // numbers are equal value, remaining string compares identical; 
                // comes down to whether there are any leading zeroes here
                return nzb-nza;
                
            } else if ((Character.isDigit(ca) || nza>0) && (Character.isDigit(cb) || nzb>0)) {
                // both sides are numbers, but at least one is a sequence of zeros
                if (nza==0) {
                    // b=0, a>0
                    return 1;
                }
                if (nzb==0) {
                    // inverse
                    return -1;
                }
                // both sides were zero, continue to next check below
            }

            if (ca == 0 && cb == 0) {
                // The strings compare the same.  Perhaps the caller
                // will want to call strcmp to break the tie.
                return nza - nzb;
            }

            if (ca < cb) {
                return -1;
            } else if (ca > cb) {
                return +1;
            }

            ++ia; ++ib;
        }
    }