swap16.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/mman.h>
  5. #include <fcntl.h>
  6. #include <sys/stat.h>
  7. #include <err.h>
  8. #include <getopt.h>
  9. #include <time.h>
  10. #include <libutil.h>
  11. #define swab16(x) (u_int16_t)__builtin_bswap16((u_int16_t)(x))
  12. /*
  13. * smart helpers
  14. */
  15. void fd_close(int *fd)
  16. {
  17. close(*fd);
  18. *fd = -1;
  19. }
  20. #define _smartfd __attribute((cleanup(fd_close)))
  21. void file_close(FILE **fd)
  22. {
  23. fclose(*fd);
  24. *fd = NULL;
  25. }
  26. #define _smartfile __attribute((cleanup(file_close)))
  27. __attribute__((noreturn)) static int usage(void)
  28. {
  29. fputs("swap16 [--input] file\n", stderr);
  30. exit (EXIT_SUCCESS);
  31. }
  32. /*
  33. * Print human readable numbers
  34. *
  35. * @width: spaces
  36. * @bytes: value in bytes
  37. */
  38. static void printsize(size_t width, off_t bytes)
  39. {
  40. /*
  41. * Reserve one space before the size and allocate room for
  42. * the trailing '\0'.
  43. */
  44. char buf[5];
  45. humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
  46. HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
  47. (void)printf("%*s", (u_int)width, buf);
  48. }
  49. int main(int argc, char *argv[])
  50. {
  51. static struct option longopts[] = {
  52. { "input", required_argument, NULL, 'i' },
  53. { NULL, 0, NULL, 0 }
  54. };
  55. int ch;
  56. _smartfd int fd = -1;
  57. char *inputfile = NULL;
  58. while ((ch = getopt_long(argc, argv, "hi:", longopts, NULL)) != -1) {
  59. switch (ch) {
  60. case 'i':
  61. inputfile = optarg;
  62. break;
  63. case 0:
  64. /* long option */
  65. break;
  66. default:
  67. usage();
  68. }
  69. }
  70. argc -= optind;
  71. argv += optind;
  72. /* if not already set, get the last arguments as the input filename */
  73. if (!inputfile && argv) {
  74. inputfile = *argv;
  75. argv++;
  76. }
  77. /* sanity checks */
  78. if (*argv || (inputfile == NULL))
  79. usage();
  80. fd = open(inputfile, O_RDWR);
  81. if (fd < 0) {
  82. err(EXIT_FAILURE, "failed to open %s:", inputfile);
  83. }
  84. /* File analysis */
  85. struct stat statbuf = { 0 };
  86. fstat(fd, & statbuf);
  87. printf("Parsing:");
  88. printsize(10, statbuf.st_size);
  89. puts(".");
  90. char *addr = (char *)mmap(NULL, (size_t)statbuf.st_size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
  91. if (addr == NULL)
  92. err(EXIT_FAILURE, "Failed to map file %s:\n", inputfile);
  93. u_int16_t *sbmax=(u_int16_t *)(addr + statbuf.st_size);
  94. u_int16_t *sb=(u_int16_t *)addr;
  95. clock_t t1, t0;
  96. t0 = clock();
  97. for (;sb < sbmax; sb++)
  98. *(sb)=swab16(*sb);
  99. t1 = clock();
  100. printf("Swab : %6.3f ms.\n", 1000.0 * (double)(t1 - t0) / CLOCKS_PER_SEC);
  101. munmap(addr, (size_t)statbuf.st_size);
  102. return EXIT_SUCCESS;
  103. }