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/WireDecoder.h b/src/WireDecoder.h
new file mode 100644
index 0000000..c520be7
--- /dev/null
+++ b/src/WireDecoder.h
@@ -0,0 +1,149 @@
+/*----------------------------------------------------------------------------*/
+/* 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_WIREDECODER_H_
+#define NT_WIREDECODER_H_
+
+#include <cstddef>
+
+#include "nt_Value.h"
+#include "leb128.h"
+//#include "Log.h"
+#include "raw_istream.h"
+
+namespace nt {
+
+/* Decodes network data into native representation.
+ * This class is designed to read from a raw_istream, which provides a blocking
+ * read interface.  There are no provisions in this class for resuming a read
+ * that was interrupted partway.  Read functions return false if
+ * raw_istream.read() returned false (indicating the end of the input data
+ * stream).
+ */
+class WireDecoder {
+ public:
+  explicit WireDecoder(raw_istream& is, unsigned int proto_rev);
+  ~WireDecoder();
+
+  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 error indicator. */
+  void Reset() { 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; }
+
+  void set_error(const char* error) { m_error = error; }
+
+  /* Reads the specified number of bytes.
+   * @param buf pointer to read data (output parameter)
+   * @param len number of bytes to read
+   * Caution: the buffer is only temporarily valid.
+   */
+  bool Read(const char** buf, std::size_t len) {
+    if (len > m_allocated) Realloc(len);
+    *buf = m_buf;
+    bool rv = m_is.read(m_buf, len);
+#if 0
+    nt::Logger& logger = nt::Logger::GetInstance();
+    if (logger.min_level() <= NT_LOG_DEBUG4 && logger.HasLogger()) {
+      std::ostringstream oss;
+      oss << "read " << len << " bytes:" << std::hex;
+      if (!rv)
+        oss << "error";
+      else {
+        for (std::size_t i=0; i < len; ++i)
+          oss << ' ' << (unsigned int)((*buf)[i]);
+      }
+      logger.Log(NT_LOG_DEBUG4, __FILE__, __LINE__, oss.str().c_str());
+    }
+#endif
+    return rv;
+  }
+
+  /* Reads a single byte. */
+  bool Read8(unsigned int* val) {
+    const char* buf;
+    if (!Read(&buf, 1)) return false;
+    *val = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    return true;
+  }
+
+  /* Reads a 16-bit word. */
+  bool Read16(unsigned int* val) {
+    const char* buf;
+    if (!Read(&buf, 2)) return false;
+    unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    ++buf;
+    v <<= 8;
+    v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    *val = v;
+    return true;
+  }
+
+  /* Reads a 32-bit word. */
+  bool Read32(unsigned long* val) {
+    const char* buf;
+    if (!Read(&buf, 4)) return false;
+    unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    ++buf;
+    v <<= 8;
+    v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    ++buf;
+    v <<= 8;
+    v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    ++buf;
+    v <<= 8;
+    v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    *val = v;
+    return true;
+  }
+
+  /* Reads a double. */
+  bool ReadDouble(double* val);
+
+  /* Reads an ULEB128-encoded unsigned integer. */
+  bool ReadUleb128(unsigned long* val) {
+    return nt::ReadUleb128(m_is, val);
+  }
+
+  bool ReadType(NT_Type* type);
+  bool ReadString(std::string* str);
+  std::shared_ptr<Value> ReadValue(NT_Type type);
+
+  WireDecoder(const WireDecoder&) = delete;
+  WireDecoder& operator=(const WireDecoder&) = delete;
+
+ protected:
+  /* The protocol revision.  E.g. 0x0200 for version 2.0. */
+  unsigned int m_proto_rev;
+
+  /* Error indicator. */
+  const char* m_error;
+
+ private:
+  /* Reallocate temporary buffer to specified length. */
+  void Realloc(std::size_t len);
+
+  /* input stream */
+  raw_istream& m_is;
+
+  /* temporary buffer */
+  char* m_buf;
+
+  /* allocated size of temporary buffer */
+  std::size_t m_allocated;
+};
+
+}  // namespace nt
+
+#endif  // NT_WIREDECODER_H_