implemented and tested PrintField
diff --git a/aos/common/common.gyp b/aos/common/common.gyp
index a774936..7c38c53 100644
--- a/aos/common/common.gyp
+++ b/aos/common/common.gyp
@@ -44,8 +44,12 @@
{
'target_name': 'queue_types',
'type': 'static_library',
+ 'variables': {
+ 'print_field_cc': '<(SHARED_INTERMEDIATE_DIR)/print_field.cc',
+ },
'sources': [
'queue_types.cc',
+ '<(print_field_cc)',
],
'dependencies': [
'<(AOS)/build/aos.gyp:logging_interface',
@@ -53,6 +57,23 @@
'<(AOS)/linux_code/ipc_lib/ipc_lib.gyp:core_lib',
'mutex',
],
+ 'actions': [
+ {
+ 'variables': {
+ 'script': '<(AOS)/build/queues/print_field.rb',
+ },
+ 'action_name': 'gen_print_field',
+ 'inputs': [
+ '<(script)',
+ '<!@(find <(AOS)/build/queues/ -name *.rb)',
+ ],
+ 'outputs': [
+ '<(print_field_cc)',
+ ],
+ 'action': ['ruby', '<(script)', '<(print_field_cc)'],
+ 'message': 'Generating print_field.cc',
+ },
+ ],
},
{
'target_name': 'queue_types_test',
diff --git a/aos/common/queue_types.h b/aos/common/queue_types.h
index 9955fe7..cf7287f 100644
--- a/aos/common/queue_types.h
+++ b/aos/common/queue_types.h
@@ -15,18 +15,21 @@
// output is where to write the text representation.
// output_bytes should point to the number of bytes available to write in
// output. It will be reduced by the number of bytes that were actually written.
-// input is where to read the data in from.
+// input is where to read the data in from (in network byte order, aka from
+// Serialize).
// input_bytes should point to the number of bytes available to read from input.
// It will be reduced by the number of bytes that were actually read.
// type is the ID of a type to print. It must be a primitive type.
//
+// Returns true for success and false for not.
+//
// The implementation of this is generated by the ruby code.
-// TODO(brians): Actually do that.
bool PrintField(char *output, size_t *output_bytes, void *input,
- size_t *input_bytes, uint32_t type);
+ size_t *input_bytes, uint32_t type)
+ __attribute__((warn_unused_result));
// The type IDs this uses are 2 parts: a 16 bit size and a 16 bit hash. Sizes
-// for primitive types are stored with 8192 added.
+// for primitive types are stored with 8192 (0x2000) added.
//
// Serializing/deserializing includes all of the fields too.
struct MessageType {
@@ -69,7 +72,7 @@
static MessageType *Deserialize(const char *buffer, size_t *bytes);
static bool IsPrimitive(uint32_t type_id) {
- return (type_id & 0xFFFF) >= 8192;
+ return (type_id & 0x2000) != 0;
}
// The type ID for this.
@@ -95,9 +98,9 @@
DISALLOW_COPY_AND_ASSIGN(MessageType);
};
-// Implements a cache of types which usually works per-process but can (when
-// explicitly instructed) put a type in shared memory which other processes will
-// automatically receive.
+// Implements a cache of types which generally works per-process but can (when
+// instructed) put a type in shared memory which other processes will
+// automatically be able to retrieve.
// All of these functions are thread-safe.
namespace type_cache {
diff --git a/aos/common/queue_types_test.cc b/aos/common/queue_types_test.cc
index 287d555..a23c33b 100644
--- a/aos/common/queue_types_test.cc
+++ b/aos/common/queue_types_test.cc
@@ -5,8 +5,13 @@
#include "gtest/gtest.h"
#include "aos/common/test_queue.q.h"
+#include "aos/common/byteorder.h"
+
+using ::aos::common::testing::Structure;
+using ::aos::common::testing::MessageWithStructure;
namespace aos {
+namespace testing {
typedef MessageType::Field Field;
@@ -70,4 +75,57 @@
EXPECT_TRUE(Equal(kTestType1, *deserialized));
}
+class PrintFieldTest : public ::testing::Test {
+ public:
+ char input[128], output[128];
+ size_t input_bytes, output_bytes;
+};
+
+TEST_F(PrintFieldTest, Basic) {
+ static const uint16_t kData = 971;
+ input_bytes = sizeof(kData);
+ to_network(&kData, input);
+ output_bytes = sizeof(output);
+ ASSERT_TRUE(PrintField(output, &output_bytes, input, &input_bytes,
+ Structure::GetType()->fields[1]->type));
+ EXPECT_EQ(0u, input_bytes);
+ EXPECT_EQ(sizeof(output) - 4, output_bytes);
+ EXPECT_EQ(::std::string("971\0", 4),
+ ::std::string(output, sizeof(output) - output_bytes));
+}
+
+// Tests PrintField with trailing input bytes and no extra output bytes.
+TEST_F(PrintFieldTest, OtherSizes) {
+ static const float kData = 16.78;
+ static const ::std::string kString("16.780001");
+ static const size_t kExtraInputBytes = 4;
+ input_bytes = sizeof(kData) + kExtraInputBytes;
+ to_network(&kData, input);
+ output_bytes = kString.size() + 1;
+ assert(output_bytes <= sizeof(output));
+ ASSERT_TRUE(PrintField(output, &output_bytes, input, &input_bytes,
+ Structure::GetType()->fields[2]->type));
+ EXPECT_EQ(kExtraInputBytes, input_bytes);
+ EXPECT_EQ(0u, output_bytes);
+ EXPECT_EQ(kString, ::std::string(output));
+}
+
+TEST_F(PrintFieldTest, InputTooSmall) {
+ static const float kData = 0;
+ input_bytes = sizeof(kData) - 1;
+ output_bytes = sizeof(output);
+ EXPECT_FALSE(PrintField(output, &output_bytes, input, &input_bytes,
+ Structure::GetType()->fields[2]->type));
+}
+
+TEST_F(PrintFieldTest, OutputTooSmall) {
+ static const uint16_t kData = 12345;
+ input_bytes = sizeof(input);
+ to_network(&kData, input);
+ output_bytes = 5;
+ EXPECT_FALSE(PrintField(output, &output_bytes, input, &input_bytes,
+ Structure::GetType()->fields[1]->type));
+}
+
+} // namespace testing
} // namespace aos
diff --git a/aos/common/test_queue.q b/aos/common/test_queue.q
index 878be08..d603802 100644
--- a/aos/common/test_queue.q
+++ b/aos/common/test_queue.q
@@ -3,6 +3,7 @@
struct Structure {
bool struct_bool;
uint16_t struct_int;
+ float struct_float;
};
message MessageWithStructure {