aos_send stdin support

This change adds the ability to pipe a message to aos_send over stdin.
aos_send will block waiting for data on stdin if none is provided.

Change-Id: I733ed1a3c1e57b6958d1bc152736cf898760c3dc
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/aos_send.cc b/aos/aos_send.cc
index adfd780..515da71 100644
--- a/aos/aos_send.cc
+++ b/aos/aos_send.cc
@@ -1,3 +1,4 @@
+#include <poll.h>
 #include <unistd.h>
 
 #include <iostream>
@@ -17,7 +18,8 @@
       "Typical Usage: aos_send [--config path_to_config.json]"
       " channel_name message_type '{\"foo\": \"bar\"}'\n"
       "Example usage: aos_send /test aos.examples.Ping "
-      "'{\"value\": 1}'");
+      "'{\"value\": 1}'\n"
+      "Pipe usage: cat ping.json | aos_send /test/ aos.examples.Ping -");
   aos::InitGoogle(&argc, &argv);
 
   aos::CliUtilInfo cli_info;
@@ -38,14 +40,24 @@
     LOG(FATAL) << "Must specify a message to send";
   }
 
+  // Check if the user wants to use stdin (denoted by '-') or the argument
+  // present in argv for the message to send. CliUtilInfo will ensure the
+  // message data will be in argv[1]
+  std::string_view message_to_send{argv[1]};
+  std::string stdin_data;
+  if (message_to_send == "-") {
+    // Read in everything from stdin, blocks when there's no data on stdin
+    stdin_data = std::string(std::istreambuf_iterator(std::cin), {});
+    message_to_send = stdin_data;
+  }
+
   const aos::Channel *const channel = cli_info.found_channels[0];
   const std::unique_ptr<aos::RawSender> sender =
       cli_info.event_loop->MakeRawSender(channel);
   flatbuffers::FlatBufferBuilder fbb(sender->fbb_allocator()->size(),
                                      sender->fbb_allocator());
   fbb.ForceDefaults(true);
-  fbb.Finish(aos::JsonToFlatbuffer(std::string_view(argv[1]), channel->schema(),
-                                   &fbb));
+  fbb.Finish(aos::JsonToFlatbuffer(message_to_send, channel->schema(), &fbb));
 
   if (FLAGS_rate < 0) {
     sender->CheckOk(sender->Send(fbb.GetSize()));