/*
 * Copyright 2006 The Android Open Source Project
 *
 * JDWP spy.
 */
#define _JDWP_MISC_INLINE
#include "Common.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>

static const char gHexDigit[] = "0123456789abcdef";

/*
 * Print a hex dump.  Just hands control off to the fancy version.
 */
void printHexDump(const void* vaddr, size_t length)
{
    printHexDumpEx(stdout, vaddr, length, kHexDumpLocal, "");
}
void printHexDump2(const void* vaddr, size_t length, const char* prefix)
{
    printHexDumpEx(stdout, vaddr, length, kHexDumpLocal, prefix);
}

/*
 * Print a hex dump in this format:
 *
01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef\n
 */
void printHexDumpEx(FILE* fp, const void* vaddr, size_t length,
    HexDumpMode mode, const char* prefix)
{
    const unsigned char* addr = reinterpret_cast<const unsigned char*>(vaddr);
    char out[77];       /* exact fit */
    uintptr_t offset;   /* offset to show while printing */
    char* hex;
    char* asc;
    int gap;

    if (mode == kHexDumpLocal)
        offset = 0;
    else
        offset = (uintptr_t) addr;

    memset(out, ' ', sizeof(out)-1);
    out[8] = ':';
    out[sizeof(out)-2] = '\n';
    out[sizeof(out)-1] = '\0';

    gap = (int) offset & 0x0f;
    while (length) {
        unsigned int lineOffset = offset & ~0x0f;
        char* hex = out;
        char* asc = out + 59;

        for (int i = 0; i < 8; i++) {
            *hex++ = gHexDigit[lineOffset >> 28];
            lineOffset <<= 4;
        }
        hex++;
        hex++;

        int count = ((int)length > 16-gap) ? 16-gap : (int) length; /* cap length */
        assert(count != 0);
        assert(count+gap <= 16);

        if (gap) {
            /* only on first line */
            hex += gap * 3;
            asc += gap;
        }

        int i;
        for (i = gap ; i < count+gap; i++) {
            *hex++ = gHexDigit[*addr >> 4];
            *hex++ = gHexDigit[*addr & 0x0f];
            hex++;
            if (isprint(*addr))
                *asc++ = *addr;
            else
                *asc++ = '.';
            addr++;
        }
        for ( ; i < 16; i++) {
            /* erase extra stuff; only happens on last line */
            *hex++ = ' ';
            *hex++ = ' ';
            hex++;
            *asc++ = ' ';
        }

        fprintf(fp, "%s%s", prefix, out);

        gap = 0;
        length -= count;
        offset += count;
    }
}


/*
 * Explain it.
 */
static void usage(const char* progName)
{
    fprintf(stderr, "Usage: %s VM-port [debugger-listen-port]\n\n", progName);
    fprintf(stderr,
"When a debugger connects to the debugger-listen-port, jdwpspy will connect\n");
    fprintf(stderr, "to the VM on the VM-port.\n");
}

/*
 * Parse args.
 */
int main(int argc, char* argv[])
{
    if (argc < 2 || argc > 3) {
        usage("jdwpspy");
        return 2;
    }

    setvbuf(stdout, NULL, _IONBF, 0);

    /* may want this to be host:port */
    int connectPort = atoi(argv[1]);

    int listenPort;
    if (argc > 2)
        listenPort = atoi(argv[2]);
    else
        listenPort = connectPort + 1;

    int cc = run("localhost", connectPort, listenPort);

    return (cc != 0);
}
