WPILibC++  unspecified
WireDecoder.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) FIRST 2015-2018. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #ifndef NTCORE_WIREDECODER_H_
9 #define NTCORE_WIREDECODER_H_
10 
11 #include <stdint.h>
12 
13 #include <cstddef>
14 #include <memory>
15 #include <string>
16 
17 #include <support/leb128.h>
18 #include <support/raw_istream.h>
19 
20 #include "Log.h"
21 #include "networktables/NetworkTableValue.h"
22 
23 namespace nt {
24 
25 /* Decodes network data into native representation.
26  * This class is designed to read from a raw_istream, which provides a blocking
27  * read interface. There are no provisions in this class for resuming a read
28  * that was interrupted partway. Read functions return false if
29  * raw_istream.read() returned false (indicating the end of the input data
30  * stream).
31  */
32 class WireDecoder {
33  public:
34  WireDecoder(wpi::raw_istream& is, unsigned int proto_rev,
35  wpi::Logger& logger);
36  ~WireDecoder();
37 
38  void set_proto_rev(unsigned int proto_rev) { m_proto_rev = proto_rev; }
39 
40  /* Get the active protocol revision. */
41  unsigned int proto_rev() const { return m_proto_rev; }
42 
43  /* Get the logger. */
44  wpi::Logger& logger() const { return m_logger; }
45 
46  /* Clears error indicator. */
47  void Reset() { m_error = nullptr; }
48 
49  /* Returns error indicator (a string describing the error). Returns nullptr
50  * if no error has occurred.
51  */
52  const char* error() const { return m_error; }
53 
54  void set_error(const char* error) { m_error = error; }
55 
56  /* Reads the specified number of bytes.
57  * @param buf pointer to read data (output parameter)
58  * @param len number of bytes to read
59  * Caution: the buffer is only temporarily valid.
60  */
61  bool Read(const char** buf, size_t len) {
62  if (len > m_allocated) Realloc(len);
63  *buf = m_buf;
64  m_is.read(m_buf, len);
65 #if 0
66  if (m_logger.min_level() <= NT_LOG_DEBUG4 && m_logger.HasLogger()) {
67  std::ostringstream oss;
68  oss << "read " << len << " bytes:" << std::hex;
69  if (!rv) {
70  oss << "error";
71  } else {
72  for (size_t i = 0; i < len; ++i)
73  oss << ' ' << static_cast<unsigned int>((*buf)[i]);
74  }
75  m_logger.Log(NT_LOG_DEBUG4, __FILE__, __LINE__, oss.str().c_str());
76  }
77 #endif
78  return !m_is.has_error();
79  }
80 
81  /* Reads a single byte. */
82  bool Read8(unsigned int* val) {
83  const char* buf;
84  if (!Read(&buf, 1)) return false;
85  *val = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
86  return true;
87  }
88 
89  /* Reads a 16-bit word. */
90  bool Read16(unsigned int* val) {
91  const char* buf;
92  if (!Read(&buf, 2)) return false;
93  unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
94  ++buf;
95  v <<= 8;
96  v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
97  *val = v;
98  return true;
99  }
100 
101  /* Reads a 32-bit word. */
102  bool Read32(uint32_t* val) {
103  const char* buf;
104  if (!Read(&buf, 4)) return false;
105  unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
106  ++buf;
107  v <<= 8;
108  v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
109  ++buf;
110  v <<= 8;
111  v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
112  ++buf;
113  v <<= 8;
114  v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
115  *val = v;
116  return true;
117  }
118 
119  /* Reads a double. */
120  bool ReadDouble(double* val);
121 
122  /* Reads an ULEB128-encoded unsigned integer. */
123  bool ReadUleb128(uint64_t* val) { return wpi::ReadUleb128(m_is, val); }
124 
125  bool ReadType(NT_Type* type);
126  bool ReadString(std::string* str);
127  std::shared_ptr<Value> ReadValue(NT_Type type);
128 
129  WireDecoder(const WireDecoder&) = delete;
130  WireDecoder& operator=(const WireDecoder&) = delete;
131 
132  protected:
133  /* The protocol revision. E.g. 0x0200 for version 2.0. */
134  unsigned int m_proto_rev;
135 
136  /* Error indicator. */
137  const char* m_error;
138 
139  private:
140  /* Reallocate temporary buffer to specified length. */
141  void Realloc(size_t len);
142 
143  /* input stream */
144  wpi::raw_istream& m_is;
145 
146  /* logger */
147  wpi::Logger& m_logger;
148 
149  /* temporary buffer */
150  char* m_buf;
151 
152  /* allocated size of temporary buffer */
153  size_t m_allocated;
154 };
155 
156 } // namespace nt
157 
158 #endif // NTCORE_WIREDECODER_H_
Definition: raw_istream.h:21
Definition: IEntryNotifier.h:16
Definition: Logger.h:30
Definition: WireDecoder.h:32