jim         99/05/21 20:49:33

  Modified:    src/ap   ap_snprintf.c
  Log:
  Provide some "faster" versions of the
  conversion functions when the number value doesn't warrant use of
  quads
  
  Revision  Changes    Path
  1.32      +89 -6     apache-1.3/src/ap/ap_snprintf.c
  
  Index: ap_snprintf.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/ap/ap_snprintf.c,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- ap_snprintf.c     1999/05/22 01:46:48     1.31
  +++ ap_snprintf.c     1999/05/22 03:49:32     1.32
  @@ -344,7 +344,57 @@
    * The caller provides a buffer for the string: that is the buf_end argument
    * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
    * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
  + *
  + * Note: we have 2 versions. One is used when we need to use quads (conv_10),
  + * the other isn't (conv_10_l). We're assuming the latter is faster.
    */
  +static char *conv_10_l(register wide_int num, register bool_int is_unsigned,
  +                  register bool_int *is_negative, char *buf_end,
  +                  register int *len)
  +{
  +    register char *p = buf_end;
  +    register u_wide_int magnitude;
  +
  +    if (is_unsigned) {
  +     magnitude = (u_wide_int) num;
  +     *is_negative = FALSE;
  +    }
  +    else {
  +     *is_negative = (num < 0);
  +
  +     /*
  +      * On a 2's complement machine, negating the most negative integer 
  +      * results in a number that cannot be represented as a signed integer.
  +      * Here is what we do to obtain the number's magnitude:
  +      *      a. add 1 to the number
  +      *      b. negate it (becomes positive)
  +      *      c. convert it to unsigned
  +      *      d. add 1
  +      */
  +     if (*is_negative) {
  +         wide_int t = num + 1;
  +
  +         magnitude = ((u_wide_int) -t) + 1;
  +     }
  +     else
  +         magnitude = (u_wide_int) num;
  +    }
  +
  +    /*
  +     * We use a do-while loop so that we write at least 1 digit 
  +     */
  +    do {
  +     register u_wide_int new_magnitude = magnitude / 10;
  +
  +     *--p = (char) (magnitude - new_magnitude * 10 + '0');
  +     magnitude = new_magnitude;
  +    }
  +    while (magnitude);
  +
  +    *len = buf_end - p;
  +    return (p);
  +}
  +
   static char *conv_10(register widest_int num, register bool_int is_unsigned,
                     register bool_int *is_negative, char *buf_end,
                     register int *len)
  @@ -352,6 +402,14 @@
       register char *p = buf_end;
       register u_widest_int magnitude;
   
  +    /*
  +     * If the value is less than the maximum unsigned long value,
  +     * then we know we aren't using quads, so use the faster function
  +     */
  +    if (num <= ULONG_MAX)
  +     return(conv_10_l( (wide_int)num, is_unsigned, is_negative,
  +            buf_end, len));
  +
       if (is_unsigned) {
        magnitude = (u_widest_int) num;
        *is_negative = FALSE;
  @@ -401,13 +459,13 @@
       bool_int is_negative;
       int sub_len;
   
  -    p = conv_10((addr & 0x000000FF)      , TRUE, &is_negative, p, &sub_len);
  +    p = conv_10_l((addr & 0x000000FF)      , TRUE, &is_negative, p, 
&sub_len);
       *--p = '.';
  -    p = conv_10((addr & 0x0000FF00) >>  8, TRUE, &is_negative, p, &sub_len);
  +    p = conv_10_l((addr & 0x0000FF00) >>  8, TRUE, &is_negative, p, 
&sub_len);
       *--p = '.';
  -    p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len);
  +    p = conv_10_l((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, 
&sub_len);
       *--p = '.';
  -    p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len);
  +    p = conv_10_l((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, 
&sub_len);
   
       *len = buf_end - p;
       return (p);
  @@ -421,7 +479,7 @@
       bool_int is_negative;
       int sub_len;
   
  -    p = conv_10(ntohs(si->sin_port), TRUE, &is_negative, p, &sub_len);
  +    p = conv_10_l(ntohs(si->sin_port), TRUE, &is_negative, p, &sub_len);
       *--p = ':';
       p = conv_in_addr(&si->sin_addr, p, &sub_len);
   
  @@ -498,7 +556,7 @@
        *s++ = format;          /* either e or E */
        decimal_point--;
        if (decimal_point != 0) {
  -         p = conv_10((widest_int) decimal_point, FALSE, 
&exponent_is_negative,
  +         p = conv_10_l((wide_int) decimal_point, FALSE, 
&exponent_is_negative,
                        &temp[EXPONENT_LENGTH], &t_len);
            *s++ = exponent_is_negative ? '-' : '+';
   
  @@ -531,7 +589,29 @@
    * The caller provides a buffer for the string: that is the buf_end argument
    * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
    * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
  + *
  + * As with conv_10, we have a faster version which is used when
  + * the number isn't quad size.
    */
  +static char *conv_p2_l(register u_wide_int num, register int nbits,
  +                  char format, char *buf_end, register int *len)
  +{
  +    register int mask = (1 << nbits) - 1;
  +    register char *p = buf_end;
  +    static const char low_digits[] = "0123456789abcdef";
  +    static const char upper_digits[] = "0123456789ABCDEF";
  +    register const char *digits = (format == 'X') ? upper_digits : 
low_digits;
  +
  +    do {
  +     *--p = digits[num & mask];
  +     num >>= nbits;
  +    }
  +    while (num);
  +
  +    *len = buf_end - p;
  +    return (p);
  +}
  +
   static char *conv_p2(register u_widest_int num, register int nbits,
                     char format, char *buf_end, register int *len)
   {
  @@ -540,6 +620,9 @@
       static const char low_digits[] = "0123456789abcdef";
       static const char upper_digits[] = "0123456789ABCDEF";
       register const char *digits = (format == 'X') ? upper_digits : 
low_digits;
  +
  +    if (num <= ULONG_MAX)
  +     return(conv_p2_l( (u_wide_int)num, nbits, format, buf_end, len));
   
       do {
        *--p = digits[num & mask];
  
  
  

Reply via email to