#include #include #include #include #include #include #include #include #include #include #define swab16(x) (u_int16_t)__builtin_bswap16((u_int16_t)(x)) /* * smart helpers */ void fd_close(int *fd) { close(*fd); *fd = -1; } #define _smartfd __attribute((cleanup(fd_close))) void file_close(FILE **fd) { fclose(*fd); *fd = NULL; } #define _smartfile __attribute((cleanup(file_close))) __attribute__((noreturn)) static int usage(void) { fputs("swap16 [--input] file\n", stderr); exit (EXIT_SUCCESS); } /* * Print human readable numbers * * @width: spaces * @bytes: value in bytes */ static void printsize(size_t width, off_t bytes) { /* * Reserve one space before the size and allocate room for * the trailing '\0'. */ char buf[5]; humanize_number(buf, sizeof(buf), (int64_t)bytes, "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); (void)printf("%*s", (u_int)width, buf); } int main(int argc, char *argv[]) { static struct option longopts[] = { { "input", required_argument, NULL, 'i' }, { NULL, 0, NULL, 0 } }; int ch; _smartfd int fd = -1; char *inputfile = NULL; while ((ch = getopt_long(argc, argv, "hi:", longopts, NULL)) != -1) { switch (ch) { case 'i': inputfile = optarg; break; case 0: /* long option */ break; default: usage(); } } argc -= optind; argv += optind; /* if not already set, get the last arguments as the input filename */ if (!inputfile && argv) { inputfile = *argv; argv++; } /* sanity checks */ if (*argv || (inputfile == NULL)) usage(); fd = open(inputfile, O_RDWR); if (fd < 0) { err(EXIT_FAILURE, "failed to open %s:", inputfile); } /* File analysis */ struct stat statbuf = { 0 }; fstat(fd, & statbuf); printf("Parsing:"); printsize(10, statbuf.st_size); puts("."); char *addr = (char *)mmap(NULL, (size_t)statbuf.st_size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); if (addr == NULL) err(EXIT_FAILURE, "Failed to map file %s:\n", inputfile); u_int16_t *sbmax=(u_int16_t *)(addr + statbuf.st_size); u_int16_t *sb=(u_int16_t *)addr; clock_t t1, t0; t0 = clock(); for (;sb < sbmax; sb++) *(sb)=swab16(*sb); t1 = clock(); printf("Swab : %6.3f ms.\n", 1000.0 * (double)(t1 - t0) / CLOCKS_PER_SEC); munmap(addr, (size_t)statbuf.st_size); return EXIT_SUCCESS; }