]> granicus.if.org Git - sysstat/commitdiff
Add function to swap bytes of the fields of a structure
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 17 Sep 2017 08:12:30 +0000 (10:12 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 17 Sep 2017 08:12:30 +0000 (10:12 +0200)
This function will be used to convert from one endianness type
(little/big endian) to the other.

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
sa.h
sa_common.c

diff --git a/sa.h b/sa.h
index f83314c18fd4ca3b0bce1f17a5b03d66858c2750..88bd38ecf4f3a405b476dd1e8bc593f204e516e4 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -1203,5 +1203,7 @@ void set_hdr_rectime
        (unsigned int, struct tm *, struct file_header *);
 void set_record_timestamp_string
        (unsigned int, struct record_header *, char *, char *, int, struct tm *);
+void swap_struct
+       (int [], void *, int);
 
 #endif  /* _SA_H */
index 82c0f41821a103ec9f6a026cff415633bf8446ac..87d16e87e092a038a7fbd758cfb3b6602de89d9f 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <time.h>
 #include <errno.h>
 #include <unistd.h>    /* For STDOUT_FILENO, among others */
@@ -977,6 +978,54 @@ void select_default_activity(struct activity *act[])
        }
 }
 
+/*
+ ***************************************************************************
+ * Swap bytes for every numerical field in structure. Used to convert from
+ * one endianness type (big-endian or little-endian) to the other.
+ *
+ * IN:
+ * @types_nr   Number of fields in structure for each following types:
+ *             unsigned long long, unsigned long and int.
+ * @ps         Pointer on structure.
+ * @is64bit    TRUE if data come from a 64-bit machine.
+ ***************************************************************************
+ */
+void swap_struct(int types_nr[], void *ps, int is64bit)
+{
+       int i;
+       uint64_t *x;
+       uint32_t *y;
+
+       x = (uint64_t *) ps;
+       /* For each field of type long long (or double) */
+       for (i = 0; i < types_nr[0]; i++) {
+               *x = __builtin_bswap64(*x);
+               x = (uint64_t *) ((char *) x + ULL_ALIGNMENT_WIDTH);
+       }
+
+       y = (uint32_t *) x;
+       /* For each field of type long */
+       for (i = 0; i < types_nr[1]; i++) {
+               if (is64bit) {
+                       *x = __builtin_bswap64(*x);
+                       x = (uint64_t *) ((char *) x + UL_ALIGNMENT_WIDTH);
+               }
+               else {
+                       *y = __builtin_bswap32(*y);
+                       y = (uint32_t *) ((char *) y + UL_ALIGNMENT_WIDTH);
+               }
+       }
+
+       if (is64bit) {
+               y = (uint32_t *) x;
+       }
+       /* For each field of type int */
+       for (i = 0; i < types_nr[2]; i++) {
+               *y = __builtin_bswap32(*y);
+               y = (uint32_t *) ((char *) y + U_ALIGNMENT_WIDTH);
+       }
+}
+
 /*
  ***************************************************************************
  * Read data from a system activity data file.