diff --git a/lib/version.bzl b/lib/version.bzl index 53d3cca..e03c2c3 100644 --- a/lib/version.bzl +++ b/lib/version.bzl @@ -1 +1 @@ -EMBAG_VERSION = "0.0.41" +EMBAG_VERSION = "0.0.42" diff --git a/python/embag.cc b/python/embag.cc index a151094..a199a02 100644 --- a/python/embag.cc +++ b/python/embag.cc @@ -19,13 +19,26 @@ PYBIND11_MODULE(libembag, m) { return std::make_shared(std::make_shared(bytes)); })) .def("topics", &Embag::Bag::topics) - .def("read_messages", [](std::shared_ptr &bag, const std::vector& topics) { - Embag::View view{}; - view.addBag(bag); - view.getMessages(topics); + .def( + "read_messages", + [](std::shared_ptr &bag, py::object topics) { + Embag::View view{}; + view.addBag(bag); + if (topics.is_none()) { + view.getMessages(); + } else if (py::isinstance(topics)) { + view.getMessages(topics.cast()); + } else if (py::isinstance(topics)) { + view.getMessages(topics.cast>()); + } else { + throw std::runtime_error("topics must be None, a string, or a list!"); + } - return py::make_iterator(IteratorCompat{view.begin()}, IteratorCompat{view.end()}); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */, py::arg("topics")) + return py::make_iterator(IteratorCompat{view.begin()}, IteratorCompat{view.end()}); + }, + py::keep_alive<0, 1>(), /* Essential: keep object alive while iterator exists */ + py::arg("topics") = py::none() + ) .def("getSchema", [](std::shared_ptr &bag, const std::string &topic) { auto builder = SchemaBuilder{bag}; return builder.generateSchema(topic); @@ -77,6 +90,9 @@ PYBIND11_MODULE(libembag, m) { .def("data", [](std::shared_ptr &m) { return m->data(); }) + .def_property_readonly("raw_data", [](std::shared_ptr &m) { + return py::bytes(&m->raw_buffer->at(m->raw_buffer_offset), m->raw_data_len); + }) .def( "dict", []( diff --git a/test/BUILD b/test/BUILD index 17e9eb8..3285ff7 100644 --- a/test/BUILD +++ b/test/BUILD @@ -16,6 +16,7 @@ py_test( srcs = ["embag_test_python.py"], data = [ "test.bag", + "test_bag_raw_messages.P", "//python:libembag.so", ], python_version = "PY3", @@ -27,6 +28,7 @@ py_test( srcs = ["embag_test_python.py"], data = [ "test.bag", + "test_bag_raw_messages.P", "//python:libembag.so", ], python_version = "PY2", diff --git a/test/embag_test_python.py b/test/embag_test_python.py index 4ac918d..85ed749 100644 --- a/test/embag_test_python.py +++ b/test/embag_test_python.py @@ -1,6 +1,7 @@ import python.libembag as embag from collections import OrderedDict import numpy as np +import pickle import struct import sys import unittest @@ -243,5 +244,15 @@ def testROSTimeDicting(self): assert as_ros_time.to_nsec() == as_int assert as_ros_time.to_sec() == as_float + def testMessageRawData(self): + """ + Tests that the raw_data property of a RosMessage returns the same data as rospy + """ + with open('test/test_bag_raw_messages.P', 'rb') as raw_messages_file: + raw_messages = pickle.load(raw_messages_file) + + for index, msg in enumerate(self.view.getMessages()): + assert raw_messages[index] == msg.raw_data + if __name__ == "__main__": unittest.main() diff --git a/test/test_bag_raw_messages.P b/test/test_bag_raw_messages.P new file mode 100644 index 0000000..9e42d3a Binary files /dev/null and b/test/test_bag_raw_messages.P differ