StrUtil_CapacityToBytes(uint64 *out,        // OUT: The output value
                        const char *str,    // IN: String to parse
                        unsigned int bytes) // IN: Bytes per unit in an
                                            //     unadorned string

{
   double quantity;
   char *rest;

   ASSERT(out);
   ASSERT(str);

   errno = 0;
   quantity = strtod(str, &rest);
   if (errno == ERANGE) {
      return FALSE;
   }

   /* Skip over any whitespace in the suffix. */
   while (*rest == ' ' || *rest == '\t') {
      rest++;
   }
   if (*rest != '\0') {
      uint64 shift;
      Bool suffixOK = TRUE;

      /*
       * [kK], [mM], [gG], and [tT] represent kilo, mega, giga, and tera
       * byte quantities respectively. [bB] represents a singular byte
       * quantity. [sS] represents a sector quantity.
       *
       * For kilo, mega, giga, and tera we're OK with an additional byte
       * suffix. Otherwise, the presence of an additional suffix is an error.
       */
      switch (*rest) {
      case 'b': case 'B': shift = 0;  suffixOK = FALSE; break;
      case 's': case 'S': shift = 9;  suffixOK = FALSE; break;
      case 'k': case 'K': shift = 10;                   break;
      case 'm': case 'M': shift = 20;                   break;
      case 'g': case 'G': shift = 30;                   break;
      case 't': case 'T': shift = 40;                   break;
      default :                                         return FALSE;
      }
      switch(*++rest) {
      case '\0':
         break;
      case 'b': case 'B':
         if (suffixOK && !*++rest) {
            break;
         }
         /* FALLTHRU */
      default:
         return FALSE;
      }
      quantity *= CONST64U(1) << shift;
   } else {
      /*
       * No suffix, so multiply by the number of bytes per unit as specified
       * by the caller.
       */
      quantity *= bytes;
   }

   *out = quantity;

   return TRUE;
}
StrUtil_CapacityToBytes(uint64 *out,         
                        const char *str,     
                        unsigned int bytes)  
                                             

{
   double quantity;
   char *rest;

   ASSERT(out);
   ASSERT(str);

   errno = 0;
   quantity = strtod(str, &rest);
   if (errno == ERANGE) {
      return FALSE;
   }

    
   while (*rest == ' ' || *rest == '\t') {
      rest++;
   }
   if (*rest != '\0') {
      uint64 shift;
      Bool suffixOK = TRUE;

       
      switch (*rest) {
      case 'b': case 'B': shift = 0;  suffixOK = FALSE; break;
      case 's': case 'S': shift = 9;  suffixOK = FALSE; break;
      case 'k': case 'K': shift = 10;                   break;
      case 'm': case 'M': shift = 20;                   break;
      case 'g': case 'G': shift = 30;                   break;
      case 't': case 'T': shift = 40;                   break;
      default :                                         return FALSE;
      }
      switch(*++rest) {
      case '\0':
         break;
      case 'b': case 'B':
         if (suffixOK && !*++rest) {
            break;
         }
          
      default:
         return FALSE;
      }
      quantity *= CONST64U(1) << shift;
   } else {
       
      quantity *= bytes;
   }

   *out = quantity;

   return TRUE;
}