X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;ds=inline;f=src%2Finput%2Ftrace32_ad.c;h=1f69028887b09a297bec438174430a205d94aa5c;hb=8c4bff1d25e1c41ef44e3570823789a82f24b12a;hp=cf8ab298ddeb602af9090d336fcd381413d6de5b;hpb=8bc2fa6d820d05f88fa003baa9837ebc7663681d;p=libsigrok.git diff --git a/src/input/trace32_ad.c b/src/input/trace32_ad.c index cf8ab298..1f690288 100644 --- a/src/input/trace32_ad.c +++ b/src/input/trace32_ad.c @@ -45,7 +45,7 @@ #define LOG_PREFIX "input/trace32_ad" -#define CHUNK_SIZE 10240 +#define CHUNK_SIZE (4 * 1024 * 1024) #define MAX_POD_COUNT 12 #define HEADER_SIZE 80 @@ -98,6 +98,29 @@ struct context { static int process_header(GString *buf, struct context *inc); static void create_channels(struct sr_input *in); +/* Transform non-printable chars to '\xNN' presentation. */ +static char *printable_name(const char *name) +{ + size_t l, i; + char *s, *p; + + if (!name) + return NULL; + l = strlen(name); + s = g_malloc0(l * strlen("\\x00") + 1); + for (p = s, i = 0; i < l; i++) { + if (g_ascii_isprint(name[i])) { + *p++ = name[i]; + } else { + snprintf(p, 5, "\\x%05x", name[i]); + p += strlen("\\x00"); + } + } + *p = '\0'; + + return s; +} + static char get_pod_name_from_id(int id) { switch (id) { @@ -156,18 +179,25 @@ static int init(struct sr_input *in, GHashTable *options) return SR_OK; } -static int format_match(GHashTable *metadata) +static int format_match(GHashTable *metadata, unsigned int *confidence) { GString *buf; + int rc; buf = g_hash_table_lookup(metadata, GINT_TO_POINTER(SR_INPUT_META_HEADER)); + rc = process_header(buf, NULL); - return process_header(buf, NULL); + if (rc != SR_OK) + return rc; + *confidence = 10; + + return SR_OK; } static int process_header(GString *buf, struct context *inc) { char *format_name, *format_name_sig; + char *p; int i, record_size, device_id; /* @@ -189,7 +219,13 @@ static int process_header(GString *buf, struct context *inc) * 78-79 (0x4E-4F) ?? */ - /* Note: inc is off-limits until we check whether it's a valid pointer. */ + /* + * Note: The routine is called from different contexts. Either + * to auto-detect the file format (format_match(), 'inc' is NULL), + * or to process the data during acquisition (receive(), 'inc' + * is a valid pointer). This header parse routine shall gracefully + * deal with unexpected or incorrect input data. + */ format_name = g_strndup(buf->str, 32); @@ -213,16 +249,20 @@ static int process_header(GString *buf, struct context *inc) inc->format = AD_FORMAT_TXTHDR; g_free(format_name_sig); g_free(format_name); - sr_err("This format isn't implemented yet, aborting."); + if (inc) + sr_err("This format isn't implemented yet, aborting."); return SR_ERR; } else { g_free(format_name_sig); g_free(format_name); - sr_err("Don't know this file format, aborting."); + if (inc) + sr_err("Don't know this file format, aborting."); return SR_ERR; } - sr_dbg("File says it's \"%s\"", format_name); + p = printable_name(format_name); + sr_dbg("File says it's \"%s\"", p); + g_free(p); record_size = R8(buf->str + 56); device_id = 0;