Squashed 'third_party/ntcore_2016/' content from commit d8de5e4

Change-Id: Id4839f41b6a620d8bae58dcf1710016671cc4992
git-subtree-dir: third_party/ntcore_2016
git-subtree-split: d8de5e4f19e612e7102172c0dbf152ce82d3d63a
diff --git a/src/WireEncoder.h b/src/WireEncoder.h
new file mode 100644
index 0000000..40a4ca0
--- /dev/null
+++ b/src/WireEncoder.h
@@ -0,0 +1,105 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2015. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NT_WIREENCODER_H_
+#define NT_WIREENCODER_H_
+
+#include <cassert>
+#include <cstddef>
+
+#include "llvm/SmallVector.h"
+#include "llvm/StringRef.h"
+#include "nt_Value.h"
+
+namespace nt {
+
+/* Encodes native data for network transmission.
+ * This class maintains an internal memory buffer for written data so that
+ * it can be efficiently bursted to the network after a number of writes
+ * have been performed.  For this reason, all operations are non-blocking.
+ */
+class WireEncoder {
+ public:
+  explicit WireEncoder(unsigned int proto_rev);
+
+  /* Change the protocol revision (mostly affects value encoding). */
+  void set_proto_rev(unsigned int proto_rev) { m_proto_rev = proto_rev; }
+
+  /* Get the active protocol revision. */
+  unsigned int proto_rev() const { return m_proto_rev; }
+
+  /* Clears buffer and error indicator. */
+  void Reset() {
+    m_data.clear();
+    m_error = nullptr;
+  }
+
+  /* Returns error indicator (a string describing the error).  Returns nullptr
+   * if no error has occurred.
+   */
+  const char* error() const { return m_error; }
+
+  /* Returns pointer to start of memory buffer with written data. */
+  const char* data() const { return m_data.data(); }
+
+  /* Returns number of bytes written to memory buffer. */
+  std::size_t size() const { return m_data.size(); }
+
+  llvm::StringRef ToStringRef() const {
+    return llvm::StringRef(m_data.data(), m_data.size());
+  }
+
+  /* Writes a single byte. */
+  void Write8(unsigned int val) { m_data.push_back((char)(val & 0xff)); }
+
+  /* Writes a 16-bit word. */
+  void Write16(unsigned int val) {
+    m_data.append({(char)((val >> 8) & 0xff), (char)(val & 0xff)});
+  }
+
+  /* Writes a 32-bit word. */
+  void Write32(unsigned long val) {
+    m_data.append({(char)((val >> 24) & 0xff),
+                   (char)((val >> 16) & 0xff),
+                   (char)((val >> 8) & 0xff),
+                   (char)(val & 0xff)});
+  }
+
+  /* Writes a double. */
+  void WriteDouble(double val);
+
+  /* Writes an ULEB128-encoded unsigned integer. */
+  void WriteUleb128(unsigned long val);
+
+  void WriteType(NT_Type type);
+  void WriteValue(const Value& value);
+  void WriteString(llvm::StringRef str);
+
+  /* Utility function to get the written size of a value (without actually
+   * writing it).
+   */
+  std::size_t GetValueSize(const Value& value) const;
+
+  /* Utility function to get the written size of a string (without actually
+   * writing it).
+   */
+  std::size_t GetStringSize(llvm::StringRef str) const;
+
+ protected:
+  /* The protocol revision.  E.g. 0x0200 for version 2.0. */
+  unsigned int m_proto_rev;
+
+  /* Error indicator. */
+  const char* m_error;
+
+ private:
+  llvm::SmallVector<char, 256> m_data;
+};
+
+}  // namespace nt
+
+#endif  // NT_WIREENCODER_H_