blob: c520be7b71815e7dbf02f1df7310f31106a6f004 [file] [log] [blame]
Brian Silvermanf7bd1c22015-12-24 16:07:11 -08001/*----------------------------------------------------------------------------*/
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 "nt_Value.h"
14#include "leb128.h"
15//#include "Log.h"
16#include "raw_istream.h"
17
18namespace 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 */
27class WireDecoder {
28 public:
29 explicit WireDecoder(raw_istream& is, unsigned int proto_rev);
30 ~WireDecoder();
31
32 void set_proto_rev(unsigned int proto_rev) { m_proto_rev = proto_rev; }
33
34 /* Get the active protocol revision. */
35 unsigned int proto_rev() const { return m_proto_rev; }
36
37 /* Clears error indicator. */
38 void Reset() { m_error = nullptr; }
39
40 /* Returns error indicator (a string describing the error). Returns nullptr
41 * if no error has occurred.
42 */
43 const char* error() const { return m_error; }
44
45 void set_error(const char* error) { m_error = error; }
46
47 /* Reads the specified number of bytes.
48 * @param buf pointer to read data (output parameter)
49 * @param len number of bytes to read
50 * Caution: the buffer is only temporarily valid.
51 */
52 bool Read(const char** buf, std::size_t len) {
53 if (len > m_allocated) Realloc(len);
54 *buf = m_buf;
55 bool rv = m_is.read(m_buf, len);
56#if 0
57 nt::Logger& logger = nt::Logger::GetInstance();
58 if (logger.min_level() <= NT_LOG_DEBUG4 && logger.HasLogger()) {
59 std::ostringstream oss;
60 oss << "read " << len << " bytes:" << std::hex;
61 if (!rv)
62 oss << "error";
63 else {
64 for (std::size_t i=0; i < len; ++i)
65 oss << ' ' << (unsigned int)((*buf)[i]);
66 }
67 logger.Log(NT_LOG_DEBUG4, __FILE__, __LINE__, oss.str().c_str());
68 }
69#endif
70 return rv;
71 }
72
73 /* Reads a single byte. */
74 bool Read8(unsigned int* val) {
75 const char* buf;
76 if (!Read(&buf, 1)) return false;
77 *val = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
78 return true;
79 }
80
81 /* Reads a 16-bit word. */
82 bool Read16(unsigned int* val) {
83 const char* buf;
84 if (!Read(&buf, 2)) return false;
85 unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
86 ++buf;
87 v <<= 8;
88 v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
89 *val = v;
90 return true;
91 }
92
93 /* Reads a 32-bit word. */
94 bool Read32(unsigned long* val) {
95 const char* buf;
96 if (!Read(&buf, 4)) return false;
97 unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
98 ++buf;
99 v <<= 8;
100 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 *val = v;
108 return true;
109 }
110
111 /* Reads a double. */
112 bool ReadDouble(double* val);
113
114 /* Reads an ULEB128-encoded unsigned integer. */
115 bool ReadUleb128(unsigned long* val) {
116 return nt::ReadUleb128(m_is, val);
117 }
118
119 bool ReadType(NT_Type* type);
120 bool ReadString(std::string* str);
121 std::shared_ptr<Value> ReadValue(NT_Type type);
122
123 WireDecoder(const WireDecoder&) = delete;
124 WireDecoder& operator=(const WireDecoder&) = delete;
125
126 protected:
127 /* The protocol revision. E.g. 0x0200 for version 2.0. */
128 unsigned int m_proto_rev;
129
130 /* Error indicator. */
131 const char* m_error;
132
133 private:
134 /* Reallocate temporary buffer to specified length. */
135 void Realloc(std::size_t len);
136
137 /* input stream */
138 raw_istream& m_is;
139
140 /* temporary buffer */
141 char* m_buf;
142
143 /* allocated size of temporary buffer */
144 std::size_t m_allocated;
145};
146
147} // namespace nt
148
149#endif // NT_WIREDECODER_H_