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