made more preparations for putting queue messages into logs
diff --git a/aos/common/queue.h b/aos/common/queue.h
index d37fe59..77fdf0d 100644
--- a/aos/common/queue.h
+++ b/aos/common/queue.h
@@ -16,9 +16,56 @@
 #endif  // USE_UNSAFE
 #include "aos/common/time.h"
 
-
 namespace aos {
 
+#ifndef SWIG
+
+// Prints the value from 1 message field into output.
+// 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 changed to the number of bytes that were actually written.
+// input is where to read the data in from.
+// input_bytes should point to the number of bytes available to read from input.
+// It will be changed to the number of bytes that were actually read.
+// type is the ID of a type to print. It must be a primitive type.
+//
+// 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);
+
+// 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.
+//
+// Serializing/deserializing includes all of the fields too.
+struct MessageType {
+  struct Field {
+    uint32_t type;
+    const char *name;
+  };
+
+  ~MessageType() {
+    for (int i = 0; i < number_fields; ++i) {
+      delete fields[i];
+    }
+  }
+
+  // Returns -1 for error.
+  ssize_t Serialize(char *buffer, size_t max_bytes) const;
+  // bytes should start out as the number of bytes available in buffer and gets
+  // set to the number actually read before returning.
+  // Returns a new instance allocated with new or NULL for error.
+  static MessageType *Deserialize(const char *buffer, size_t *bytes);
+
+  uint32_t id;
+  const char *name;
+
+  int number_fields;
+  const Field *fields[];
+};
+
+#endif  // SWIG
+
 // This class is a base class for all messages sent over queues.
 class Message {
  public:
@@ -29,13 +76,17 @@
   Message() : sent_time(0, 0) {}
 
   // Zeros out the time.
+  // Overriden to zero the whole message.
   void Zero();
-  // Returns the size of the message in bytes.
+  // Returns the size of the common fields.
+  // Overriden to return the size of the whole message.
   static size_t Size() { return sizeof(Time); }
 
   // Deserializes the common fields from the buffer.
+  // Overriden to deserialize the whole message.
   size_t Deserialize(const char *buffer);
   // Serializes the common fields into the buffer.
+  // Overriden to serialize the whole message.
   size_t Serialize(char *buffer) const;
 
   // Populates sent_time with the current time.
@@ -43,6 +94,10 @@
 
   // Writes the contents of the message to the provided buffer.
   size_t Print(char *buffer, int length) const;
+
+#ifndef SWIG
+  const MessageType &GetType() const;
+#endif  // SWIG
 };
 
 template <class T> class Queue;
@@ -117,7 +172,7 @@
   // ScopedMessagePtr<X> ptr = queue.MakeMessage();
   // but we don't want to allow them to then say
   // ScopedMessagePtr<X> new_ptr = ptr;
-  // And, if they do actually want to copy the pointer, then it will correctly
+  // And, if they do actually want to move the pointer, then it will correctly
   // clear out the source so there aren't 2 pointers to the message lying
   // around.
   ScopedMessagePtr(ScopedMessagePtr<T> &&ptr)
@@ -197,7 +252,7 @@
   }
 
   // Initializes the queue.  This may optionally be called to do any one time
-  // work before sending information, and may be be called mulitple times.
+  // work before sending information, and may be be called multiple times.
   // Init will be called when a message is sent, but this will cause sending to
   // take a different amount of time the first cycle.
   void Init();
@@ -224,7 +279,7 @@
 
   // Returns true if the latest value in the queue is newer than age mseconds.
   bool IsNewerThanMS(int age) {
-    // TODO(aschuh): Log very verbosely if something is _ever_ stale;
+    // TODO(aschuh): Log very verbosely if something is _ever_ stale.
     if (get() != NULL) {
       return Age() < time::Time::InMS(age);
     } else {