Switch to side-by-side view

--- a
+++ b/src/utils/listmem.cpp
@@ -0,0 +1,150 @@
+#include "listmem.h"
+
+#include <string.h>
+#include <iomanip>
+
+using namespace std;
+
+/*
+ * Functions to list a memory buffer:
+ */
+
+/* Turn byte into Hexadecimal ascii representation */
+static char *hexa(unsigned int i)
+{
+    int j;
+    static char asc[3];
+
+    asc[0] = (i >> 4) & 0x0f;
+    asc[1] = i & 0x0f;
+    asc[2] = 0;
+    for (j = 0; j < 2; j++)
+        if (asc[j] > 9) {
+            asc[j] += 55;
+        } else {
+            asc[j] += 48;
+        }
+    return (asc);
+}
+
+static void swap16(unsigned char *d, const unsigned char *s, int n)
+{
+    if (n & 1) {
+        n >>= 1;
+        n++;
+    } else {
+        n >>= 1;
+    }
+    while (n--) {
+        int i;
+        i = 2 * n;
+        d[i] = s[i + 1];
+        d[i + 1] = s[i];
+    }
+}
+
+static void swap32(unsigned char *d, const unsigned char *s, int n)
+{
+    if (n & 3) {
+        n >>= 2;
+        n++;
+    } else {
+        n >>= 2;
+    }
+    while (n--) {
+        int i;
+        i = 4 * n;
+        d[i] = s[i + 3];
+        d[i + 1] = s[i + 2];
+        d[i + 2] = s[i + 1];
+        d[i + 3] = s[i];
+    }
+}
+
+/* Turn byte buffer into hexadecimal representation */
+void charbuftohex(int len, unsigned char *dt, int maxlen, char *str)
+{
+    int i;
+    char *bf;
+
+    for (i = 0, bf = str; i < len; i++) {
+        char *cp;
+        if (bf - str >= maxlen - 4) {
+            break;
+        }
+        cp = hexa((unsigned int)dt[i]);
+        *bf++ = *cp++;
+        *bf++ = *cp++;
+        *bf++ = ' ';
+    }
+    *bf++ = 0;
+}
+
+void listmem(ostream& os, const void *_ptr, int siz, int adr, int opts)
+{
+    const unsigned char *ptr = (const unsigned char *)_ptr;
+    int             i, j, c;
+    char            lastlisted[16];
+    int             alreadysame = 0;
+    int         oneout = 0;
+    unsigned char  *mpt;
+
+    if (opts & (LISTMEM_SWAP16 | LISTMEM_SWAP32)) {
+        if ((mpt = (unsigned char *)malloc(siz + 4)) == NULL) {
+            os << "OUT OF MEMORY\n";
+            return;
+        }
+        if (opts & LISTMEM_SWAP16) {
+            swap16(mpt, ptr, siz);
+        } else if (opts & LISTMEM_SWAP32) {
+            swap32(mpt, ptr, siz);
+        }
+    } else {
+        mpt = (unsigned char *)ptr;
+    }
+
+    for (i = 0; i < siz; i += 16) {
+        /* Check for same data (only print first line in this case) */
+        if (oneout != 0  &&
+                siz - i >= 16 && memcmp(lastlisted, mpt + i, 16) == 0) {
+            if (alreadysame == 0) {
+                os << "*\n";
+                alreadysame = 1;
+            }
+            continue;
+        }
+        alreadysame = 0;
+        /* Line header */
+        os << std::setw(4) << i + adr << " ";
+
+        /* Hexadecimal representation */
+        for (j = 0; j < 16; j++) {
+            if ((i + j) < siz) {
+                os << hexa(mpt[i + j]) << ((j & 1) ? " " : "");
+            } else {
+                os << "  " << ((j & 1) ? " " : "");
+            }
+        }
+        os << "  ";
+
+        /* Also print ascii for values that fit */
+        for (j = 0; j < 16; j++) {
+            if ((i + j) < siz) {
+                c = mpt[i + j];
+                if (c >= 0x20 && c <= 0x7f) {
+                    os << char(c);
+                } else {
+                    os << ".";
+                }
+            } else {
+                os << " ";
+            }
+        }
+        os << "\n";
+        memcpy(lastlisted, mpt + i, 16);
+        oneout = 1;
+    }
+    if (mpt != ptr) {
+        free(mpt);
+    }
+}