summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnuradio-core/src/lib/io/gr_file_meta_sink.cc58
-rw-r--r--gnuradio-core/src/lib/io/gr_file_meta_sink.h15
-rw-r--r--gnuradio-core/src/lib/io/gr_file_meta_sink.i4
-rw-r--r--gnuradio-core/src/python/gnuradio/parse_file_metadata.py24
-rw-r--r--gr-utils/src/python/gr_read_file_metadata20
5 files changed, 95 insertions, 26 deletions
diff --git a/gnuradio-core/src/lib/io/gr_file_meta_sink.cc b/gnuradio-core/src/lib/io/gr_file_meta_sink.cc
index 9d092d79fa..401d8299d5 100644
--- a/gnuradio-core/src/lib/io/gr_file_meta_sink.cc
+++ b/gnuradio-core/src/lib/io/gr_file_meta_sink.cc
@@ -60,26 +60,43 @@ gr_file_meta_sink::gr_file_meta_sink(size_t itemsize, const char *filename,
pmt_t timestamp = pmt_make_tuple(pmt_from_uint64(0),
pmt_from_double(0));
+ // handle extra dictionary
+ d_extra = pmt_make_dict();
+ if(extra_dict.size() > 0) {
+ pmt_t extras = pmt_deserialize_str(extra_dict);
+ pmt_t keys = pmt_dict_keys(extras);
+ pmt_t vals = pmt_dict_values(extras);
+ size_t nitems = pmt_length(keys);
+ for(size_t i = 0; i < nitems; i++) {
+ d_extra = pmt_dict_add(d_extra,
+ pmt_nth(i, keys),
+ pmt_nth(i, vals));
+ }
+ }
+
+ d_extra_size = pmt_serialize_str(d_extra).size();
+
d_header = pmt_make_dict();
d_header = pmt_dict_add(d_header, mp("rx_rate"), mp(samp_rate));
d_header = pmt_dict_add(d_header, mp("rx_time"), timestamp);
d_header = pmt_dict_add(d_header, mp("type"), pmt_from_long(type));
d_header = pmt_dict_add(d_header, mp("cplx"), complex ? PMT_T : PMT_F);
- d_header = pmt_dict_add(d_header, mp("strt"), pmt_from_uint64(HEADER_SIZE));
+ d_header = pmt_dict_add(d_header, mp("strt"), pmt_from_uint64(HEADER_SIZE+d_extra_size));
d_header = pmt_dict_add(d_header, mp("size"), pmt_from_uint64(0));
- // handle extra dictionary
- write_header(d_header);
+ write_header(d_header, d_extra);
}
void
-gr_file_meta_sink::write_header(pmt_t header)
+gr_file_meta_sink::write_header(pmt_t header, pmt_t extra)
{
do_update();
std::string header_str = pmt_serialize_str(header);
- if(header_str.size() != HEADER_SIZE)
- throw std::runtime_error("file_meta_sink: header is wrong size.\n");
+ std::string extra_str = pmt_serialize_str(extra);
+
+ if((header_str.size() != HEADER_SIZE) && (extra_str.size() != d_extra_size))
+ throw std::runtime_error("file_meta_sink: header or extras is wrong size.\n");
size_t nwritten = 0;
while(nwritten < header_str.size()) {
@@ -91,6 +108,17 @@ gr_file_meta_sink::write_header(pmt_t header)
throw std::runtime_error("file_meta_sink: error writing header to file.\n");
}
}
+
+ nwritten = 0;
+ while(nwritten < extra_str.size()) {
+ std::string sub = extra_str.substr(nwritten);
+ int count = fwrite(sub.c_str(), sizeof(char), sub.size(), d_fp);
+ nwritten += count;
+ if((count == 0) && (ferror(d_fp))) {
+ fclose(d_fp);
+ throw std::runtime_error("file_meta_sink: error writing extra to file.\n");
+ }
+ }
}
bool
@@ -107,6 +135,10 @@ gr_file_meta_sink::update_header(pmt_t key, pmt_t value)
d_header = pmt_dict_add(d_header, key, value);
return true;
}
+ else if(pmt_dict_has_key(d_extra, key)) {
+ d_extra = pmt_dict_add(d_extra, key, value);
+ return true;
+ }
else {
return false;
}
@@ -118,7 +150,7 @@ gr_file_meta_sink::get_last_header_loc()
uint64_t loc = 0;
pmt_t v = pmt_dict_ref(d_header, mp("strt"), PMT_NIL);
if(!pmt_eq(v, PMT_NIL))
- loc = pmt_to_uint64(v) - HEADER_SIZE;
+ loc = pmt_to_uint64(v) - (HEADER_SIZE+d_extra_size);
return loc;
}
@@ -135,7 +167,7 @@ gr_file_meta_sink::~gr_file_meta_sink()
//std::cerr << " Segment Size: " << seg_size << std::endl;
if(update_header(mp("size"), s)) {
fseek(d_fp, loc, SEEK_SET);
- write_header(d_header);
+ write_header(d_header, d_extra);
}
}
@@ -164,7 +196,7 @@ gr_file_meta_sink::work(int noutput_items,
if(itr->offset == 0) {
if(update_header(itr->key, itr->value)) {
fseek(d_fp, 0, SEEK_SET);
- write_header(d_header);
+ write_header(d_header, d_extra);
}
}
else {
@@ -178,7 +210,7 @@ gr_file_meta_sink::work(int noutput_items,
//std::cerr << " segment size is: " << seg_size << std::endl;
if(update_header(mp("size"), s)) {
fseek(d_fp, loc, SEEK_SET);
- write_header(d_header);
+ write_header(d_header, d_extra);
}
if(update_header(itr->key, itr->value)) {
@@ -192,14 +224,14 @@ gr_file_meta_sink::work(int noutput_items,
// of creating a new header per tag.
uint64_t seg_start = loc;
if(seg_size != 0)
- seg_start += HEADER_SIZE + seg_size;
- pmt_t s = pmt_from_uint64(seg_start + HEADER_SIZE);
+ seg_start += HEADER_SIZE + d_extra_size + seg_size + 1;
+ pmt_t s = pmt_from_uint64(seg_start + HEADER_SIZE + d_extra_size);
if(update_header(mp("strt"), s)) {
//std::cerr << "Adding new header" << std::endl;
//std::cerr << " new header start at: " << seg_start-HEADER_SIZE << std::endl;
//std::cerr << " new seg start at: " << seg_start << std::endl;
fseek(d_fp, seg_start, SEEK_SET);
- write_header(d_header);
+ write_header(d_header, d_extra);
}
}
}
diff --git a/gnuradio-core/src/lib/io/gr_file_meta_sink.h b/gnuradio-core/src/lib/io/gr_file_meta_sink.h
index c0f30bdc08..9ba4878d17 100644
--- a/gnuradio-core/src/lib/io/gr_file_meta_sink.h
+++ b/gnuradio-core/src/lib/io/gr_file_meta_sink.h
@@ -46,8 +46,8 @@ typedef boost::shared_ptr<gr_file_meta_sink> gr_file_meta_sink_sptr;
GR_CORE_API gr_file_meta_sink_sptr
gr_make_file_meta_sink(size_t itemsize, const char *filename,
- double samp_rate, double relative_rate,
- gr_file_types type, bool complex,
+ double samp_rate=1, double relative_rate=1,
+ gr_file_types type=GR_FILE_FLOAT, bool complex=true,
const std::string &extra_dict="");
/*!
@@ -100,15 +100,16 @@ class GR_CORE_API gr_file_meta_sink : public gr_sync_block, public gr_file_sink_
double d_relative_rate;
uint64_t d_total_seg_size;
pmt_t d_header;
- pmt_t d_extra_dict;
+ pmt_t d_extra;
+ size_t d_extra_size;
protected:
gr_file_meta_sink(size_t itemsize, const char *filename,
- double samp_rate, double relative_rate,
- gr_file_types type, bool complex,
- const std::string &extra_dict);
+ double samp_rate=1, double relative_rate=1,
+ gr_file_types type=GR_FILE_FLOAT, bool complex=true,
+ const std::string &extra_dict="");
- void write_header(pmt_t header);
+ void write_header(pmt_t header, pmt_t extra);
bool update_header(pmt_t key, pmt_t value);
uint64_t get_last_header_loc();
diff --git a/gnuradio-core/src/lib/io/gr_file_meta_sink.i b/gnuradio-core/src/lib/io/gr_file_meta_sink.i
index 7d90ca3049..b58a519cec 100644
--- a/gnuradio-core/src/lib/io/gr_file_meta_sink.i
+++ b/gnuradio-core/src/lib/io/gr_file_meta_sink.i
@@ -35,8 +35,8 @@ enum gr_file_types {
gr_file_meta_sink_sptr
gr_make_file_meta_sink(size_t itemsize, const char *filename,
- double samp_rate, double relative_rate,
- gr_file_types type, bool complex,
+ double samp_rate=1, double relative_rate=1,
+ gr_file_types type=GR_FILE_FLOAT, bool complex=true,
const std::string & extra_dict="");
class gr_file_meta_sink : public gr_sync_block, public gr_file_sink_base
diff --git a/gnuradio-core/src/python/gnuradio/parse_file_metadata.py b/gnuradio-core/src/python/gnuradio/parse_file_metadata.py
index cff7566e41..c8a9fbde10 100644
--- a/gnuradio-core/src/python/gnuradio/parse_file_metadata.py
+++ b/gnuradio-core/src/python/gnuradio/parse_file_metadata.py
@@ -112,10 +112,12 @@ def parse_header(p, hdr_start, VERBOSE=False):
r = gr.pmt_dict_ref(p, gr.pmt_string_to_symbol("strt"), dump)
seg_start = gr.pmt_to_uint64(r)
info["strt"] = seg_start
+ info["extra_len"] = seg_start - hdr_start - HEADER_LENGTH
+ info["has_extra"] = info["extra_len"] > 0
if(VERBOSE):
print "Segment Start: {0} bytes".format(seg_start)
- print "Header Length: {0}".format((seg_start-hdr_start))
- print "Extra Header? {0}".format((seg_start-hdr_start) > HEADER_LENGTH)
+ print "Extra Length: {0}".format((info["extra_len"]))
+ print "Extra Header? {0}".format(info["has_extra"])
else:
sys.stderr.write("Could not find key 'strt': invalid or corrupt data file.\n")
sys.exit(1)
@@ -141,3 +143,21 @@ def parse_header(p, hdr_start, VERBOSE=False):
sys.exit(1)
return info
+
+# IF THERE IS EXTRA DATA, PULL OUT THE DICTIONARY AND PARSE IT
+def parse_extra_dict(p, info, VERBOSE=False):
+ if(gr.pmt_is_dict(p) is False):
+ sys.stderr.write("Extra header is not a PMT dictionary: invalid or corrupt data file.\n")
+ sys.exit(1)
+
+ items = gr.pmt_dict_items(p)
+ nitems = gr.pmt_length(items)
+ for i in xrange(nitems):
+ item = gr.pmt_nth(i, items)
+ key = gr.pmt_symbol_to_string(gr.pmt_car(item))
+ val = gr.pmt_to_double(gr.pmt_cdr(item))
+ info[key] = val
+ if(VERBOSE):
+ print "{0}: {1}".format(key, val)
+
+ return info
diff --git a/gr-utils/src/python/gr_read_file_metadata b/gr-utils/src/python/gr_read_file_metadata
index 47109aead2..850c29ee7b 100644
--- a/gr-utils/src/python/gr_read_file_metadata
+++ b/gr-utils/src/python/gr_read_file_metadata
@@ -29,6 +29,7 @@ from gnuradio import parse_file_metadata
def main(filename):
handle = open(filename, "rb")
+ nheaders = 0
nread = 0
while(True):
# read out next header bytes
@@ -45,12 +46,27 @@ def main(filename):
sys.exit(1)
#gr.pmt_print(header)
+ print "HEADER {0}".format(nheaders)
info = parse_file_metadata.parse_header(header, hdr_start, True)
- print "\n\n"
- nread += info['nbytes'] + parse_file_metadata.HEADER_LENGTH
+ if(info["extra_len"] > 0):
+ extra_str = handle.read(info["extra_len"])
+ if(len(extra_str) == 0):
+ break
+
+ try:
+ extra = gr.pmt_deserialize_str(extra_str)
+ except RuntimeError:
+ sys.stderr.write("Could not deserialize extras: invalid or corrupt data file.\n")
+ sys.exit(1)
+ print "\nExtra Header:"
+ extra_info = parse_file_metadata.parse_extra_dict(extra, info, True)
+
+ nheaders += 1
+ nread += info['nbytes'] + parse_file_metadata.HEADER_LENGTH + info["extra_len"] + 1
handle.seek(nread, 0)
+ print "\n\n"
if __name__ == "__main__":
usage="%prog: [options] filename"