From Colin O'Flynn:
[obnox/wireshark/wip.git] / print.c
diff --git a/print.c b/print.c
index a8788b2aad41718872a61975da2bfbc2cff66f99..0f0014cbb0e11d9e7896459f6fdd64893c8a13e4 100644 (file)
--- a/print.c
+++ b/print.c
 #include <epan/tvbuff.h>
 #include <epan/packet.h>
 #include <epan/emem.h>
+#include <epan/expert.h>
 
 #include "packet-range.h"
 #include "print.h"
+#include "isprint.h"
 #include "ps.h"
 #include "version_info.h"
 #include <wsutil/file_util.h>
@@ -256,7 +258,7 @@ write_pdml_preamble(FILE *fh, const gchar* filename)
        fputs("<?xml-stylesheet type=\"text/xsl\" href=\"" PDML2HTML_XSL "\"?>\n", fh);
        fprintf(fh, "<!-- You can find " PDML2HTML_XSL " in %s or at http://anonsvn.wireshark.org/trunk/wireshark/" PDML2HTML_XSL ". -->\n", get_datafile_dir());
        fputs("<pdml version=\"" PDML_VERSION "\" ", fh);
-       fprintf(fh, "creator=\"%s/%s\" time=\"%s\" capture_file=\"%s\">\n", PACKAGE, VERSION, ts, filename);
+       fprintf(fh, "creator=\"%s/%s\" time=\"%s\" capture_file=\"%s\">\n", PACKAGE, VERSION, ts, filename ? filename : "");
 }
 
 void
@@ -312,7 +314,7 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                /* Open fake protocol wrapper */
                fputs("<proto name=\"fake-field-wrapper\">\n", pdata->fh);
 
-               /* Indent to increased level before writint out field */
+               /* Indent to increased level before writing out field */
                pdata->level++;
                for (i = -1; i < pdata->level; i++) {
                        fputs("  ", pdata->fh);
@@ -335,7 +337,11 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                print_escaped_xml(pdata->fh, label_ptr);
 
                fprintf(pdata->fh, "\" size=\"%d", fi->length);
-               fprintf(pdata->fh, "\" pos=\"%d", fi->start);
+               if (node->parent && node->parent->finfo && (fi->start < node->parent->finfo->start)) {
+                       fprintf(pdata->fh, "\" pos=\"%d", node->parent->finfo->start + fi->start);
+               } else {
+                       fprintf(pdata->fh, "\" pos=\"%d", fi->start);
+               }
 
                fputs("\" value=\"", pdata->fh);
                write_pdml_field_hex_value(pdata, fi);
@@ -355,11 +361,11 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                /* Write out field with data */
                fputs("<field name=\"data\" value=\"", pdata->fh);
                write_pdml_field_hex_value(pdata, fi);
-               fputs("\"/>\n", pdata->fh);
+               fputs("\">\n", pdata->fh);
        }
        /* Normal protocols and fields */
        else {
-               if (fi->hfinfo->type == FT_PROTOCOL) {
+               if (fi->hfinfo->type == FT_PROTOCOL && fi->hfinfo->id != proto_expert) {
                        fputs("<proto name=\"", pdata->fh);
                }
                else {
@@ -400,7 +406,11 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                        fprintf(pdata->fh, "\" hide=\"yes");
 
                fprintf(pdata->fh, "\" size=\"%d", fi->length);
-               fprintf(pdata->fh, "\" pos=\"%d", fi->start);
+               if (node->parent && node->parent->finfo && (fi->start < node->parent->finfo->start)) {
+                       fprintf(pdata->fh, "\" pos=\"%d", node->parent->finfo->start + fi->start);
+               } else {
+                       fprintf(pdata->fh, "\" pos=\"%d", fi->start);
+               }
 /*             fprintf(pdata->fh, "\" id=\"%d", fi->hfinfo->id);*/
 
                /* show, value, and unmaskedvalue attributes */
@@ -484,13 +494,16 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                        fputs("  ", pdata->fh);
                }
                /* Close off current element */
-               if (fi->hfinfo->id != proto_data) {   /* Data protocol uses simple tags */
+               /* Data and expert "protocols" use simple tags */
+               if (fi->hfinfo->id != proto_data && fi->hfinfo->id != proto_expert) {
                        if (fi->hfinfo->type == FT_PROTOCOL) {
                                fputs("</proto>\n", pdata->fh);
                        }
                        else {
                                fputs("</field>\n", pdata->fh);
                        }
+               } else {
+                       fputs("</field>\n", pdata->fh);
                }
        }
 
@@ -692,28 +705,62 @@ write_carrays_preamble(FILE *fh _U_)
 }
 
 void
-proto_tree_write_carrays(const guint8 *pd, guint32 len, guint32 num, FILE *fh)
+proto_tree_write_carrays(guint32 num, FILE *fh, epan_dissect_t *edt)
 {
-        guint32 i = 0;
-
-       if (!len)
-               return;
-
-       fprintf(fh, "char pkt%u[] = {\n", num);
+       guint32 i = 0, src_num = 0;
+       GSList *src_le;
+       data_source *src;
+       tvbuff_t *tvb;
+       const char *name;
+       const guchar *cp;
+       guint length;
+       char ascii[9];
 
-        for (i = 0; i < len; i++) {
+       for (src_le = edt->pi.data_src; src_le != NULL; src_le = src_le->next) {
+               memset(ascii, 0, sizeof(ascii));
+               src = (data_source *)src_le->data;
+               tvb = src->tvb;
+               length = tvb_length(tvb);
+               if (length == 0)
+                       continue;
 
-               fprintf(fh, "0x%02x", *(pd + i));
+               cp = tvb_get_ptr(tvb, 0, length);
 
-               if (i == (len - 1)) {
-                       fprintf(fh, " };\n\n");
-                       break;
+               name = get_data_source_name(src);
+               if (name)
+                       fprintf(fh, "/* %s */\n", name);
+               if (src_num) {
+                       fprintf(fh, "static const unsigned char pkt%u_%u[%u] = {\n",
+                               num, src_num, length);
+               } else {
+                       fprintf(fh, "static const unsigned char pkt%u[%u] = {\n",
+                               num, length);
                }
+               src_num++;
+
+               for (i = 0; i < length; i++) {
+                       fprintf(fh, "0x%02x", *(cp + i));
+                       ascii[i % 8] = isprint(*(cp + i)) ? *(cp + i) : '.';
+
+                       if (i == (length - 1)) {
+                               guint rem;
+                               rem = length % 8;
+                               if (rem) {
+                                       guint j;
+                                       for ( j = 0; j < 8 - rem; j++ )
+                                               fprintf(fh, "      ");
+                               }
+                               fprintf(fh, "  /* %s */\n};\n\n", ascii);
+                               break;
+                       }
 
-               if (!((i + 1) % 8)) {
-                       fprintf(fh, ", \n");
-               } else {
-                       fprintf(fh, ", ");
+                       if (!((i + 1) % 8)) {
+                               fprintf(fh, ", /* %s */\n", ascii);
+                               memset(ascii, 0, sizeof(ascii));
+                       }
+                       else {
+                               fprintf(fh, ", ");
+                       }
                }
        }
 }