X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Finput%2Finput.c;h=48660d379b9b6e69fde4546cbe8f91a7a67669b9;hb=54ee427df0d923c8e17f3dc8ee57552b6c5fd57b;hp=18a4b639ed5160e122e046bed5b44a463fe3ed96;hpb=7102443a4adb1743c5a053deee8fd2a93670fc19;p=libsigrok.git diff --git a/src/input/input.c b/src/input/input.c index 18a4b639..48660d37 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -342,7 +342,9 @@ static gboolean check_required_metadata(const uint8_t *metadata, uint8_t *avail) * 128 bytes is normally enough. * * If an input module is found, an instance is created into *in. - * Otherwise, *in contains NULL. + * Otherwise, *in contains NULL. When multiple input moduless claim + * support for the format, the one with highest confidence takes + * precedence. Applications will see at most one input module spec. * * If an instance is created, it has the given buffer used for scanning * already submitted to it, to be processed before more data is sent. @@ -353,9 +355,10 @@ static gboolean check_required_metadata(const uint8_t *metadata, uint8_t *avail) */ SR_API int sr_input_scan_buffer(GString *buf, const struct sr_input **in) { - const struct sr_input_module *imod; + const struct sr_input_module *imod, *best_imod; GHashTable *meta; unsigned int m, i; + unsigned int conf, best_conf; int ret; uint8_t mitem, avail_metadata[8]; @@ -364,7 +367,8 @@ SR_API int sr_input_scan_buffer(GString *buf, const struct sr_input **in) avail_metadata[1] = 0; *in = NULL; - ret = SR_ERR; + best_imod = NULL; + best_conf = ~0; for (i = 0; input_module_list[i]; i++) { imod = input_module_list[i]; if (!imod->metadata[0]) { @@ -388,45 +392,55 @@ SR_API int sr_input_scan_buffer(GString *buf, const struct sr_input **in) continue; } sr_spew("Trying module %s.", imod->id); - ret = imod->format_match(meta); + ret = imod->format_match(meta, &conf); g_hash_table_destroy(meta); if (ret == SR_ERR_DATA) { /* Module recognized this buffer, but cannot handle it. */ - break; + continue; } else if (ret == SR_ERR) { /* Module didn't recognize this buffer. */ continue; } else if (ret != SR_OK) { /* Can be SR_ERR_NA. */ - return ret; + continue; } /* Found a matching module. */ - sr_spew("Module %s matched.", imod->id); - *in = sr_input_new(imod, NULL); + sr_spew("Module %s matched, confidence %u.", imod->id, conf); + if (conf >= best_conf) + continue; + best_imod = imod; + best_conf = conf; + } + + if (best_imod) { + *in = sr_input_new(best_imod, NULL); g_string_insert_len((*in)->buf, 0, buf->str, buf->len); - break; + return SR_OK; } - return ret; + return SR_ERR; } /** * Try to find an input module that can parse the given file. * * If an input module is found, an instance is created into *in. - * Otherwise, *in contains NULL. + * Otherwise, *in contains NULL. When multiple input moduless claim + * support for the format, the one with highest confidence takes + * precedence. Applications will see at most one input module spec. * */ SR_API int sr_input_scan_file(const char *filename, const struct sr_input **in) { int64_t filesize; FILE *stream; - const struct sr_input_module *imod; + const struct sr_input_module *imod, *best_imod; GHashTable *meta; GString *header; size_t count; unsigned int midx, i; + unsigned int conf, best_conf; int ret; uint8_t avail_metadata[8]; @@ -475,8 +489,8 @@ SR_API int sr_input_scan_file(const char *filename, const struct sr_input **in) avail_metadata[midx] = 0; /* TODO: MIME type */ - ret = SR_ERR; - + best_imod = NULL; + best_conf = ~0; for (i = 0; input_module_list[i]; i++) { imod = input_module_list[i]; if (!imod->metadata[0]) { @@ -490,24 +504,30 @@ SR_API int sr_input_scan_file(const char *filename, const struct sr_input **in) sr_dbg("Trying module %s.", imod->id); - ret = imod->format_match(meta); + ret = imod->format_match(meta, &conf); if (ret == SR_ERR) { /* Module didn't recognize this buffer. */ continue; } else if (ret != SR_OK) { /* Module recognized this buffer, but cannot handle it. */ - break; + continue; } /* Found a matching module. */ - sr_dbg("Module %s matched.", imod->id); - - *in = sr_input_new(imod, NULL); - break; + sr_dbg("Module %s matched, confidence %u.", imod->id, conf); + if (conf >= best_conf) + continue; + best_imod = imod; + best_conf = conf; } g_hash_table_destroy(meta); g_string_free(header, TRUE); - return ret; + if (best_imod) { + *in = sr_input_new(best_imod, NULL); + return SR_OK; + } + + return SR_ERR; } /**