string_helpers.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /*
  2. * Helpers for formatting and printing strings
  3. *
  4. * Copyright 31 August 2008 James Bottomley
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/math64.h>
  8. #include <linux/module.h>
  9. #include <linux/string_helpers.h>
  10. /**
  11. * string_get_size - get the size in the specified units
  12. * @size: The size to be converted
  13. * @units: units to use (powers of 1000 or 1024)
  14. * @buf: buffer to format to
  15. * @len: length of buffer
  16. *
  17. * This function returns a string formatted to 3 significant figures
  18. * giving the size in the required units. Returns 0 on success or
  19. * error on failure. @buf is always zero terminated.
  20. *
  21. */
  22. int string_get_size(u64 size, const enum string_size_units units,
  23. char *buf, int len)
  24. {
  25. const char *units_10[] = { "B", "kB", "MB", "GB", "TB", "PB",
  26. "EB", "ZB", "YB", NULL};
  27. const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB",
  28. "EiB", "ZiB", "YiB", NULL };
  29. const char **units_str[] = {
  30. [STRING_UNITS_10] = units_10,
  31. [STRING_UNITS_2] = units_2,
  32. };
  33. const unsigned int divisor[] = {
  34. [STRING_UNITS_10] = 1000,
  35. [STRING_UNITS_2] = 1024,
  36. };
  37. int i, j;
  38. u64 remainder = 0, sf_cap;
  39. char tmp[8];
  40. tmp[0] = '\0';
  41. i = 0;
  42. if (size >= divisor[units]) {
  43. while (size >= divisor[units] && units_str[units][i]) {
  44. remainder = do_div(size, divisor[units]);
  45. i++;
  46. }
  47. sf_cap = size;
  48. for (j = 0; sf_cap*10 < 1000; j++)
  49. sf_cap *= 10;
  50. if (j) {
  51. remainder *= 1000;
  52. do_div(remainder, divisor[units]);
  53. snprintf(tmp, sizeof(tmp), ".%03lld",
  54. (unsigned long long)remainder);
  55. tmp[j+1] = '\0';
  56. }
  57. }
  58. snprintf(buf, len, "%lld%s %s", (unsigned long long)size,
  59. tmp, units_str[units][i]);
  60. return 0;
  61. }
  62. EXPORT_SYMBOL(string_get_size);