blob: 40a4ca070bc4107785eebeb36f991875a8500eaf [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_WIREENCODER_H_
9#define NT_WIREENCODER_H_
10
11#include <cassert>
12#include <cstddef>
13
14#include "llvm/SmallVector.h"
15#include "llvm/StringRef.h"
16#include "nt_Value.h"
17
18namespace nt {
19
20/* Encodes native data for network transmission.
21 * This class maintains an internal memory buffer for written data so that
22 * it can be efficiently bursted to the network after a number of writes
23 * have been performed. For this reason, all operations are non-blocking.
24 */
25class WireEncoder {
26 public:
27 explicit WireEncoder(unsigned int proto_rev);
28
29 /* Change the protocol revision (mostly affects value encoding). */
30 void set_proto_rev(unsigned int proto_rev) { m_proto_rev = proto_rev; }
31
32 /* Get the active protocol revision. */
33 unsigned int proto_rev() const { return m_proto_rev; }
34
35 /* Clears buffer and error indicator. */
36 void Reset() {
37 m_data.clear();
38 m_error = nullptr;
39 }
40
41 /* Returns error indicator (a string describing the error). Returns nullptr
42 * if no error has occurred.
43 */
44 const char* error() const { return m_error; }
45
46 /* Returns pointer to start of memory buffer with written data. */
47 const char* data() const { return m_data.data(); }
48
49 /* Returns number of bytes written to memory buffer. */
50 std::size_t size() const { return m_data.size(); }
51
52 llvm::StringRef ToStringRef() const {
53 return llvm::StringRef(m_data.data(), m_data.size());
54 }
55
56 /* Writes a single byte. */
57 void Write8(unsigned int val) { m_data.push_back((char)(val & 0xff)); }
58
59 /* Writes a 16-bit word. */
60 void Write16(unsigned int val) {
61 m_data.append({(char)((val >> 8) & 0xff), (char)(val & 0xff)});
62 }
63
64 /* Writes a 32-bit word. */
65 void Write32(unsigned long val) {
66 m_data.append({(char)((val >> 24) & 0xff),
67 (char)((val >> 16) & 0xff),
68 (char)((val >> 8) & 0xff),
69 (char)(val & 0xff)});
70 }
71
72 /* Writes a double. */
73 void WriteDouble(double val);
74
75 /* Writes an ULEB128-encoded unsigned integer. */
76 void WriteUleb128(unsigned long val);
77
78 void WriteType(NT_Type type);
79 void WriteValue(const Value& value);
80 void WriteString(llvm::StringRef str);
81
82 /* Utility function to get the written size of a value (without actually
83 * writing it).
84 */
85 std::size_t GetValueSize(const Value& value) const;
86
87 /* Utility function to get the written size of a string (without actually
88 * writing it).
89 */
90 std::size_t GetStringSize(llvm::StringRef str) const;
91
92 protected:
93 /* The protocol revision. E.g. 0x0200 for version 2.0. */
94 unsigned int m_proto_rev;
95
96 /* Error indicator. */
97 const char* m_error;
98
99 private:
100 llvm::SmallVector<char, 256> m_data;
101};
102
103} // namespace nt
104
105#endif // NT_WIREENCODER_H_