|
@@ -0,0 +1,125 @@
|
|
|
|
|
+#include <stdio.h>
|
|
|
|
|
+#include <stdlib.h>
|
|
|
|
|
+#include <unistd.h>
|
|
|
|
|
+#include <sys/mman.h>
|
|
|
|
|
+#include <fcntl.h>
|
|
|
|
|
+#include <sys/stat.h>
|
|
|
|
|
+#include <err.h>
|
|
|
|
|
+#include <getopt.h>
|
|
|
|
|
+#include <time.h>
|
|
|
|
|
+#include <libutil.h>
|
|
|
|
|
+
|
|
|
|
|
+#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);
|
|
|
|
|
+ u_int16_t *sbmax=(u_int16_t *)(addr + statbuf.st_size);
|
|
|
|
|
+ u_int16_t *sb=(u_int16_t *)addr;
|
|
|
|
|
+
|
|
|
|
|
+ if (addr == NULL)
|
|
|
|
|
+ err(EXIT_FAILURE, "Failed to map file %s:\n", inputfile);
|
|
|
|
|
+
|
|
|
|
|
+ clock_t t1, t0;
|
|
|
|
|
+
|
|
|
|
|
+ t0 = clock();
|
|
|
|
|
+ for (;sb < sbmax; sb+=sizeof(u_int16_t))
|
|
|
|
|
+ *(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;
|
|
|
|
|
+}
|
|
|
|
|
+
|