extern SR_PRIV struct sr_input_module input_chronovu_la8;
extern SR_PRIV struct sr_input_module input_csv;
extern SR_PRIV struct sr_input_module input_binary;
+extern SR_PRIV struct sr_input_module input_trace32_ad;
extern SR_PRIV struct sr_input_module input_vcd;
extern SR_PRIV struct sr_input_module input_wav;
+extern SR_PRIV struct sr_input_module input_raw_analog;
+extern SR_PRIV struct sr_input_module input_logicport;
+extern SR_PRIV struct sr_input_module input_null;
/* @endcond */
static const struct sr_input_module *input_module_list[] = {
&input_binary,
&input_chronovu_la8,
&input_csv,
+ &input_trace32_ad,
&input_vcd,
&input_wav,
+ &input_raw_analog,
+ &input_logicport,
+ &input_null,
NULL,
};
GHashTable *options)
{
struct sr_input *in;
- struct sr_option *mod_opts;
+ const struct sr_option *mod_opts;
const GVariantType *gvt;
GHashTable *new_opts;
GHashTableIter iter;
* 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.
*/
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];
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]) {
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);
- g_string_insert_len((*in)->buf, 0, buf->str, buf->len);
- break;
+ sr_spew("Module %s matched, confidence %u.", imod->id, conf);
+ if (conf >= best_conf)
+ continue;
+ best_imod = imod;
+ best_conf = conf;
}
- return ret;
-}
+ if (best_imod) {
+ *in = sr_input_new(best_imod, NULL);
+ g_string_insert_len((*in)->buf, 0, buf->str, buf->len);
+ return SR_OK;
+ }
-/** Retrieve the size of the open stream @a file.
- * This function only works on seekable streams. However, the set of seekable
- * streams is generally congruent with the set of streams that have a size.
- * Code that needs to work with any type of stream (including pipes) should
- * require neither seekability nor advance knowledge of the size.
- * On failure, the return value is negative and errno is set.
- * @param file An I/O stream opened in binary mode.
- * @return The size of @a file in bytes, or a negative value on failure.
- */
-SR_PRIV int64_t sr_file_get_size(FILE *file)
-{
- off_t filepos, filesize;
-
- /* ftello() and fseeko() are not standard C, but part of POSIX.1-2001.
- * Thus, if these functions are available at all, they can reasonably
- * be expected to also conform to POSIX semantics. In particular, this
- * means that ftello() after fseeko(..., SEEK_END) has a defined result
- * and can be used to get the size of a seekable stream.
- * On Windows, the result is fully defined only for binary streams.
- */
- filepos = ftello(file);
- if (filepos < 0)
- return -1;
-
- if (fseeko(file, 0, SEEK_END) < 0)
- return -1;
-
- filesize = ftello(file);
- if (filesize < 0)
- return -1;
-
- if (fseeko(file, filepos, SEEK_SET) < 0)
- return -1;
-
- return filesize;
+ 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];
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]) {
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;
}
/**
return in->module->end((struct sr_input *)in);
}
+/**
+ * Reset the input module's input handling structures.
+ *
+ * Causes the input module to reset its internal state so that we can re-send
+ * the input data from the beginning without having to re-create the entire
+ * input module.
+ *
+ * @since 0.5.0
+ */
+SR_API int sr_input_reset(const struct sr_input *in)
+{
+ if (!in->module->reset) {
+ sr_spew("Tried to reset %s module but no reset handler found.",
+ in->module->id);
+ return SR_OK;
+ }
+
+ sr_spew("Resetting %s module.", in->module->id);
+ return in->module->reset((struct sr_input *)in);
+}
+
/**
* Free the specified input instance and all associated resources.
*
if (in->module->cleanup)
in->module->cleanup((struct sr_input *)in);
- if (in->sdi)
- sr_dev_inst_free(in->sdi);
+ sr_dev_inst_free(in->sdi);
if (in->buf->len > 64) {
/* That seems more than just some sub-unitsize leftover... */
sr_warn("Found %" G_GSIZE_FORMAT