You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by "William A. Rowe, Jr." <wr...@rowe-clan.net> on 2001/07/25 07:41:18 UTC

[new fn] Cleaning up formatted file sizes

A funny thing happened on the way to normalizing and optimizing both
mod_include's static generate_size() and mod_autoindexes' ap_send_size().

My (simple !?!) goals were to accept 64 bit offsets and clean up the floating
point arithmetic.

I'd argue the following numbering schema would actually make more sense...

  0  through   9  these apply only to raw bytes (not powers-of).
1.0p through 9.9p these apply only to powers-of
 10p through 972p apply to both power-of and raw byte counts

973/1024 has the interesting result of .9502, nicely rounding-up to 1.0, bringing 
us to the next power.  Which means, we had overdone things by one character (it is
%4dp, or %4.1fp today, where p refers to the power.)  In changing it, we lose one
significant digit in some cases, however we gain several significant digits in <1k
results.

Finally, note that every reference I can find refers to K as the binary 2^10, vs
the value of k as 10^3.  While we once used 'k', I've correct this here.

If there is no argument to my irrational desire to 'fix' this, I'll commit it
later this week to apr_strings.c  :-)

APR_DECLARE(char *) apr_strfsize(apr_off_t size, char *buf)
{
    const char ord[] = "KMTPE";
    const char *o = ord;
    int remain;

    if (size < 0) {
        return strcpy(buf, "  - ");
    }
    if (size < 973) {
        sprintf(buf, "%3d ", (int) size, o);
        return buf;
    }
    do {
        remain = (int)(size & 1023);
        size >>= 10;
        if (size >= 973) {
            ++o;
            continue;
        }
        if (size < 9 || (size == 9 && remain < 973)) {
            if ((remain = ((remain * 5) + 256) / 512) >= 10)
                ++size, remain = 0;
            sprintf(buf, "%d.%d%c", (int) size, remain, *o);
            return buf;
        }
        if (remain >= 512)
            ++size;
        sprintf(buf, "%3d%c", (int) size, *o);
        return buf;
    } while (1);
}