mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-25 01:41:43 +00:00
Reformat per new coding guidelines.
Change-Id: Ib0e5d3a6fabe6db414d72b334ca7a7f33bc5726b
This commit is contained in:
@@ -64,12 +64,12 @@
|
||||
|
||||
#include "nt_base64.h"
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
/* aaaack but it's fast and const should make it shared text page. */
|
||||
// aaaack but it's fast and const should make it shared text page.
|
||||
static const unsigned char pr2six[256] =
|
||||
{
|
||||
/* ASCII table */
|
||||
// ASCII table
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
|
||||
@@ -88,106 +88,88 @@ static const unsigned char pr2six[256] =
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
|
||||
};
|
||||
|
||||
std::size_t
|
||||
base64decode_len(const char *bufcoded)
|
||||
{
|
||||
const unsigned char *bufin = (const unsigned char *) bufcoded;
|
||||
while (pr2six[*(bufin++)] <= 63) {}
|
||||
std::size_t base64decode_len(const char *bufcoded) {
|
||||
const unsigned char *bufin = (const unsigned char *)bufcoded;
|
||||
while (pr2six[*(bufin++)] <= 63) {
|
||||
}
|
||||
|
||||
std::size_t nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
|
||||
std::size_t nbytesdecoded = ((nprbytes + 3) / 4) * 3;
|
||||
std::size_t nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
|
||||
std::size_t nbytesdecoded = ((nprbytes + 3) / 4) * 3;
|
||||
|
||||
return nbytesdecoded + 1;
|
||||
return nbytesdecoded + 1;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
base64decode(char *bufplain, const char *bufcoded)
|
||||
{
|
||||
const unsigned char *bufin = (const unsigned char *) bufcoded;
|
||||
while (pr2six[*(bufin++)] <= 63) {}
|
||||
std::size_t nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
|
||||
std::size_t nbytesdecoded = ((nprbytes + 3) / 4) * 3;
|
||||
std::size_t base64decode(char *bufplain, const char *bufcoded) {
|
||||
const unsigned char *bufin = (const unsigned char *)bufcoded;
|
||||
while (pr2six[*(bufin++)] <= 63) {
|
||||
}
|
||||
std::size_t nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
|
||||
std::size_t nbytesdecoded = ((nprbytes + 3) / 4) * 3;
|
||||
|
||||
unsigned char *bufout = (unsigned char *) bufplain;
|
||||
bufin = (const unsigned char *) bufcoded;
|
||||
unsigned char *bufout = (unsigned char *)bufplain;
|
||||
bufin = (const unsigned char *)bufcoded;
|
||||
|
||||
while (nprbytes > 4)
|
||||
{
|
||||
*(bufout++) =
|
||||
(unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
|
||||
*(bufout++) =
|
||||
(unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
|
||||
*(bufout++) =
|
||||
(unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
|
||||
bufin += 4;
|
||||
nprbytes -= 4;
|
||||
}
|
||||
while (nprbytes > 4) {
|
||||
*(bufout++) = (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
|
||||
*(bufout++) =
|
||||
(unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
|
||||
*(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
|
||||
bufin += 4;
|
||||
nprbytes -= 4;
|
||||
}
|
||||
|
||||
/* Note: (nprbytes == 1) would be an error, so just ingore that case */
|
||||
if (nprbytes > 1)
|
||||
{
|
||||
*(bufout++) =
|
||||
(unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
|
||||
}
|
||||
if (nprbytes > 2)
|
||||
{
|
||||
*(bufout++) =
|
||||
(unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
|
||||
}
|
||||
if (nprbytes > 3)
|
||||
{
|
||||
*(bufout++) =
|
||||
(unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
|
||||
}
|
||||
// Note: (nprbytes == 1) would be an error, so just ingore that case
|
||||
if (nprbytes > 1) {
|
||||
*(bufout++) = (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
|
||||
}
|
||||
if (nprbytes > 2) {
|
||||
*(bufout++) =
|
||||
(unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
|
||||
}
|
||||
if (nprbytes > 3) {
|
||||
*(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
|
||||
}
|
||||
|
||||
*(bufout++) = '\0';
|
||||
nbytesdecoded -= (4 - nprbytes) & 3;
|
||||
return nbytesdecoded;
|
||||
*(bufout++) = '\0';
|
||||
nbytesdecoded -= (4 - nprbytes) & 3;
|
||||
return nbytesdecoded;
|
||||
}
|
||||
|
||||
static const char basis_64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
std::size_t
|
||||
base64encode_len(std::size_t len)
|
||||
{
|
||||
return ((len + 2) / 3 * 4) + 1;
|
||||
std::size_t base64encode_len(std::size_t len) {
|
||||
return ((len + 2) / 3 * 4) + 1;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
base64encode(char *encoded, const unsigned char *string, std::size_t len)
|
||||
{
|
||||
std::size_t i;
|
||||
char *p = encoded;
|
||||
std::size_t base64encode(char *encoded, const unsigned char *string,
|
||||
std::size_t len) {
|
||||
std::size_t i;
|
||||
char *p = encoded;
|
||||
|
||||
for (i = 0; i < len - 2; i += 3)
|
||||
{
|
||||
*p++ = basis_64[(string[i] >> 2) & 0x3F];
|
||||
*p++ = basis_64[((string[i] & 0x3) << 4) |
|
||||
((int) (string[i + 1] & 0xF0) >> 4)];
|
||||
*p++ = basis_64[((string[i + 1] & 0xF) << 2) |
|
||||
((int) (string[i + 2] & 0xC0) >> 6)];
|
||||
*p++ = basis_64[string[i + 2] & 0x3F];
|
||||
}
|
||||
if (i < len)
|
||||
{
|
||||
*p++ = basis_64[(string[i] >> 2) & 0x3F];
|
||||
if (i == (len - 1))
|
||||
{
|
||||
*p++ = basis_64[((string[i] & 0x3) << 4)];
|
||||
*p++ = '=';
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = basis_64[((string[i] & 0x3) << 4) |
|
||||
((int) (string[i + 1] & 0xF0) >> 4)];
|
||||
*p++ = basis_64[((string[i + 1] & 0xF) << 2)];
|
||||
}
|
||||
*p++ = '=';
|
||||
for (i = 0; i < len - 2; i += 3) {
|
||||
*p++ = basis_64[(string[i] >> 2) & 0x3F];
|
||||
*p++ =
|
||||
basis_64[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)];
|
||||
*p++ = basis_64[((string[i + 1] & 0xF) << 2) |
|
||||
((int)(string[i + 2] & 0xC0) >> 6)];
|
||||
*p++ = basis_64[string[i + 2] & 0x3F];
|
||||
}
|
||||
if (i < len) {
|
||||
*p++ = basis_64[(string[i] >> 2) & 0x3F];
|
||||
if (i == (len - 1)) {
|
||||
*p++ = basis_64[((string[i] & 0x3) << 4)];
|
||||
*p++ = '=';
|
||||
} else {
|
||||
*p++ = basis_64[((string[i] & 0x3) << 4) |
|
||||
((int)(string[i + 1] & 0xF0) >> 4)];
|
||||
*p++ = basis_64[((string[i + 1] & 0xF) << 2)];
|
||||
}
|
||||
*p++ = '=';
|
||||
}
|
||||
|
||||
*p++ = '\0';
|
||||
return p - encoded;
|
||||
*p++ = '\0';
|
||||
return p - encoded;
|
||||
}
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
std::size_t base64decode_len(const char *bufcoded);
|
||||
std::size_t base64decode(char *bufplain, const char *bufcoded);
|
||||
@@ -18,6 +18,6 @@ std::size_t base64encode_len(std::size_t len);
|
||||
std::size_t base64encode(char *encoded, const unsigned char *string,
|
||||
std::size_t len);
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_BASE64_H_ */
|
||||
#endif // NT_BASE64_H_
|
||||
|
||||
@@ -8,26 +8,26 @@
|
||||
#ifndef NT_INTERNAL_H_
|
||||
#define NT_INTERNAL_H_
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
enum MsgType {
|
||||
NT_MSG_KEEP_ALIVE = 0x00,
|
||||
NT_MSG_CLIENT_HELLO = 0x01,
|
||||
NT_MSG_PROTO_UNSUP = 0x02,
|
||||
NT_MSG_SERVER_HELLO_DONE = 0x03,
|
||||
NT_MSG_SERVER_HELLO = 0x04,
|
||||
NT_MSG_CLIENT_HELLO_DONE = 0x05,
|
||||
NT_MSG_ENTRY_ASSIGN = 0x10,
|
||||
NT_MSG_ENTRY_UPDATE = 0x11,
|
||||
NT_MSG_FLAGS_UPDATE = 0x12,
|
||||
NT_MSG_ENTRY_DELETE = 0x13,
|
||||
NT_MSG_CLEAR_ENTRIES = 0x14,
|
||||
NT_MSG_EXECUTE_RPC = 0x20,
|
||||
NT_MSG_RPC_RESPONSE = 0x21
|
||||
NT_MSG_KEEP_ALIVE = 0x00,
|
||||
NT_MSG_CLIENT_HELLO = 0x01,
|
||||
NT_MSG_PROTO_UNSUP = 0x02,
|
||||
NT_MSG_SERVER_HELLO_DONE = 0x03,
|
||||
NT_MSG_SERVER_HELLO = 0x04,
|
||||
NT_MSG_CLIENT_HELLO_DONE = 0x05,
|
||||
NT_MSG_ENTRY_ASSIGN = 0x10,
|
||||
NT_MSG_ENTRY_UPDATE = 0x11,
|
||||
NT_MSG_FLAGS_UPDATE = 0x12,
|
||||
NT_MSG_ENTRY_DELETE = 0x13,
|
||||
NT_MSG_CLEAR_ENTRIES = 0x14,
|
||||
NT_MSG_EXECUTE_RPC = 0x20,
|
||||
NT_MSG_RPC_RESPONSE = 0x21
|
||||
};
|
||||
|
||||
#define NT_CLEAR_ALL_MAGIC 0xD06CB27Aul
|
||||
#define NT_CLEAR_ALL_MAGIC 0xD06CB27Aul
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_INTERNAL_H_ */
|
||||
#endif // NT_INTERNAL_H_
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "nt_raw_istream.h"
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
/**
|
||||
* size_uleb128 - get size of unsigned LEB128 data
|
||||
@@ -20,15 +20,13 @@ namespace NtImpl {
|
||||
* on the encodings refer to section "7.6 - Variable Length Data". Return
|
||||
* the number of bytes required.
|
||||
*/
|
||||
std::size_t
|
||||
size_uleb128(unsigned long val)
|
||||
{
|
||||
std::size_t count = 0;
|
||||
do {
|
||||
val >>= 7;
|
||||
++count;
|
||||
} while (val != 0);
|
||||
return count;
|
||||
std::size_t size_uleb128(unsigned long val) {
|
||||
std::size_t count = 0;
|
||||
do {
|
||||
val >>= 7;
|
||||
++count;
|
||||
} while (val != 0);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,24 +39,22 @@ size_uleb128(unsigned long val)
|
||||
* encodings refer to section "7.6 - Variable Length Data". Return
|
||||
* the number of bytes written.
|
||||
*/
|
||||
std::size_t
|
||||
write_uleb128(char* addr, unsigned long val)
|
||||
{
|
||||
std::size_t count = 0;
|
||||
std::size_t write_uleb128(char* addr, unsigned long val) {
|
||||
std::size_t count = 0;
|
||||
|
||||
do {
|
||||
unsigned char byte = val & 0x7f;
|
||||
val >>= 7;
|
||||
do {
|
||||
unsigned char byte = val & 0x7f;
|
||||
val >>= 7;
|
||||
|
||||
if (val != 0)
|
||||
byte |= 0x80; // mark this byte to show that more bytes will follow
|
||||
if (val != 0)
|
||||
byte |= 0x80; // mark this byte to show that more bytes will follow
|
||||
|
||||
*((unsigned char *)addr) = byte;
|
||||
addr++;
|
||||
count++;
|
||||
} while (val != 0);
|
||||
*((unsigned char*)addr) = byte;
|
||||
addr++;
|
||||
count++;
|
||||
} while (val != 0);
|
||||
|
||||
return count;
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,29 +67,25 @@ write_uleb128(char* addr, unsigned long val)
|
||||
* encodings refer to section "7.6 - Variable Length Data". Return
|
||||
* the number of bytes read.
|
||||
*/
|
||||
std::size_t
|
||||
read_uleb128(char* addr, unsigned long* ret)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
int shift = 0;
|
||||
std::size_t count = 0;
|
||||
std::size_t read_uleb128(char* addr, unsigned long* ret) {
|
||||
unsigned long result = 0;
|
||||
int shift = 0;
|
||||
std::size_t count = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
unsigned char byte = *((unsigned char *)addr);
|
||||
addr++;
|
||||
count++;
|
||||
while (1) {
|
||||
unsigned char byte = *((unsigned char*)addr);
|
||||
addr++;
|
||||
count++;
|
||||
|
||||
result |= (byte & 0x7f) << shift;
|
||||
shift += 7;
|
||||
result |= (byte & 0x7f) << shift;
|
||||
shift += 7;
|
||||
|
||||
if (!(byte & 0x80))
|
||||
break;
|
||||
}
|
||||
if (!(byte & 0x80)) break;
|
||||
}
|
||||
|
||||
*ret = result;
|
||||
*ret = result;
|
||||
|
||||
return count;
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,28 +98,23 @@ read_uleb128(char* addr, unsigned long* ret)
|
||||
* encodings refer to section "7.6 - Variable Length Data". Return
|
||||
* false on stream error, true on success.
|
||||
*/
|
||||
bool
|
||||
read_uleb128(raw_istream& is, unsigned long* ret)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
int shift = 0;
|
||||
bool read_uleb128(raw_istream& is, unsigned long* ret) {
|
||||
unsigned long result = 0;
|
||||
int shift = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
unsigned char byte;
|
||||
if (!is.read((char*)&byte, 1))
|
||||
return false;
|
||||
while (1) {
|
||||
unsigned char byte;
|
||||
if (!is.read((char*)&byte, 1)) return false;
|
||||
|
||||
result |= (byte & 0x7f) << shift;
|
||||
shift += 7;
|
||||
result |= (byte & 0x7f) << shift;
|
||||
shift += 7;
|
||||
|
||||
if (!(byte & 0x80))
|
||||
break;
|
||||
}
|
||||
if (!(byte & 0x80)) break;
|
||||
}
|
||||
|
||||
*ret = result;
|
||||
*ret = result;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
class raw_istream;
|
||||
|
||||
@@ -19,6 +19,6 @@ std::size_t write_uleb128(char* addr, unsigned long val);
|
||||
std::size_t read_uleb128(char* addr, unsigned long* ret);
|
||||
bool read_uleb128(raw_istream& is, unsigned long* ret);
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_LEB128_H_ */
|
||||
#endif // NT_LEB128_H_
|
||||
|
||||
@@ -14,191 +14,156 @@
|
||||
#include "nt_internal.h"
|
||||
#include "nt_leb128.h"
|
||||
|
||||
using namespace NtImpl;
|
||||
using namespace ntimpl;
|
||||
|
||||
void
|
||||
MessageHandler::anchor()
|
||||
{
|
||||
}
|
||||
void MessageHandler::anchor() {}
|
||||
|
||||
MessageReader::MessageReader(MessageHandler& handler,
|
||||
raw_istream& is,
|
||||
MessageReader::MessageReader(MessageHandler& handler, raw_istream& is,
|
||||
unsigned int proto_rev)
|
||||
: WireDecoder(is, proto_rev)
|
||||
, m_handler(handler)
|
||||
{
|
||||
}
|
||||
: WireDecoder(is, proto_rev), m_handler(handler) {}
|
||||
|
||||
MessageReader::~MessageReader()
|
||||
{
|
||||
}
|
||||
MessageReader::~MessageReader() {}
|
||||
|
||||
bool
|
||||
MessageReader::Run()
|
||||
{
|
||||
unsigned int msg_type;
|
||||
if (!Read8(&msg_type)) return false;
|
||||
switch (msg_type)
|
||||
{
|
||||
bool MessageReader::Run() {
|
||||
unsigned int msg_type;
|
||||
if (!Read8(&msg_type)) return false;
|
||||
switch (msg_type) {
|
||||
case NT_MSG_KEEP_ALIVE:
|
||||
m_handler.GotKeepAlive();
|
||||
break;
|
||||
case NT_MSG_CLIENT_HELLO:
|
||||
{
|
||||
unsigned int proto_rev;
|
||||
if (!Read16(&proto_rev)) return false;
|
||||
NT_String self_id;
|
||||
NT_InitString(&self_id);
|
||||
// This intentionally uses the provided proto_rev instead of
|
||||
// m_proto_rev.
|
||||
if (proto_rev >= 0x0300u)
|
||||
{
|
||||
if (!ReadString(&self_id)) return false;
|
||||
}
|
||||
m_handler.GotClientHello(proto_rev, self_id);
|
||||
break;
|
||||
m_handler.GotKeepAlive();
|
||||
break;
|
||||
case NT_MSG_CLIENT_HELLO: {
|
||||
unsigned int proto_rev;
|
||||
if (!Read16(&proto_rev)) return false;
|
||||
NT_String self_id;
|
||||
NT_InitString(&self_id);
|
||||
// This intentionally uses the provided proto_rev instead of
|
||||
// m_proto_rev.
|
||||
if (proto_rev >= 0x0300u) {
|
||||
if (!ReadString(&self_id)) return false;
|
||||
}
|
||||
m_handler.GotClientHello(proto_rev, self_id);
|
||||
break;
|
||||
}
|
||||
case NT_MSG_PROTO_UNSUP:
|
||||
{
|
||||
unsigned int proto_rev;
|
||||
if (!Read16(&proto_rev)) return false;
|
||||
m_handler.GotProtoUnsup(proto_rev);
|
||||
break;
|
||||
case NT_MSG_PROTO_UNSUP: {
|
||||
unsigned int proto_rev;
|
||||
if (!Read16(&proto_rev)) return false;
|
||||
m_handler.GotProtoUnsup(proto_rev);
|
||||
break;
|
||||
}
|
||||
case NT_MSG_SERVER_HELLO_DONE:
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "received SERVER_HELLO_DONE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
m_handler.GotServerHelloDone();
|
||||
break;
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "received SERVER_HELLO_DONE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
m_handler.GotServerHelloDone();
|
||||
break;
|
||||
case NT_MSG_CLIENT_HELLO_DONE:
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "received CLIENT_HELLO_DONE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
m_handler.GotClientHelloDone();
|
||||
break;
|
||||
case NT_MSG_ENTRY_ASSIGN:
|
||||
{
|
||||
NT_String name;
|
||||
if (!ReadString(&name)) return false;
|
||||
NT_Type type;
|
||||
unsigned int id, seq_num;
|
||||
unsigned int flags = 0;
|
||||
NT_Value value;
|
||||
if (!ReadType(&type) ||
|
||||
!Read16(&id) ||
|
||||
!Read16(&seq_num) ||
|
||||
(m_proto_rev >= 0x0300u && !Read8(&flags)) ||
|
||||
!ReadValue(type, &value))
|
||||
{
|
||||
NT_DisposeString(&name);
|
||||
return false;
|
||||
}
|
||||
m_handler.GotEntryAssign(name, id, seq_num, value, flags);
|
||||
break;
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "received CLIENT_HELLO_DONE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
m_handler.GotClientHelloDone();
|
||||
break;
|
||||
case NT_MSG_ENTRY_ASSIGN: {
|
||||
NT_String name;
|
||||
if (!ReadString(&name)) return false;
|
||||
NT_Type type;
|
||||
unsigned int id, seq_num;
|
||||
unsigned int flags = 0;
|
||||
NT_Value value;
|
||||
if (!ReadType(&type) || !Read16(&id) || !Read16(&seq_num) ||
|
||||
(m_proto_rev >= 0x0300u && !Read8(&flags)) ||
|
||||
!ReadValue(type, &value)) {
|
||||
NT_DisposeString(&name);
|
||||
return false;
|
||||
}
|
||||
m_handler.GotEntryAssign(name, id, seq_num, value, flags);
|
||||
break;
|
||||
}
|
||||
case NT_MSG_ENTRY_UPDATE:
|
||||
{
|
||||
unsigned int id, seq_num;
|
||||
NT_Value value;
|
||||
if (!Read16(&id)) return false;
|
||||
if (!Read16(&seq_num)) return false;
|
||||
NT_Type type;
|
||||
if (m_proto_rev >= 0x0300u)
|
||||
{
|
||||
unsigned int itype;
|
||||
if (!Read8(&itype)) return false;
|
||||
type = static_cast<NT_Type>(itype);
|
||||
}
|
||||
else
|
||||
type = m_handler.GetEntryType(id);
|
||||
if (!ReadValue(type, &value)) return false;
|
||||
m_handler.GotEntryUpdate(id, seq_num, value);
|
||||
break;
|
||||
case NT_MSG_ENTRY_UPDATE: {
|
||||
unsigned int id, seq_num;
|
||||
NT_Value value;
|
||||
if (!Read16(&id)) return false;
|
||||
if (!Read16(&seq_num)) return false;
|
||||
NT_Type type;
|
||||
if (m_proto_rev >= 0x0300u) {
|
||||
unsigned int itype;
|
||||
if (!Read8(&itype)) return false;
|
||||
type = static_cast<NT_Type>(itype);
|
||||
} else
|
||||
type = m_handler.GetEntryType(id);
|
||||
if (!ReadValue(type, &value)) return false;
|
||||
m_handler.GotEntryUpdate(id, seq_num, value);
|
||||
break;
|
||||
}
|
||||
case NT_MSG_FLAGS_UPDATE:
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "received FLAGS_UPDATE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned int id, flags;
|
||||
if (!Read16(&id)) return false;
|
||||
if (!Read8(&flags)) return false;
|
||||
m_handler.GotFlagsUpdate(id, flags);
|
||||
break;
|
||||
case NT_MSG_FLAGS_UPDATE: {
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "received FLAGS_UPDATE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned int id, flags;
|
||||
if (!Read16(&id)) return false;
|
||||
if (!Read8(&flags)) return false;
|
||||
m_handler.GotFlagsUpdate(id, flags);
|
||||
break;
|
||||
}
|
||||
case NT_MSG_ENTRY_DELETE:
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "received ENTRY_DELETE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned int id;
|
||||
if (!Read16(&id)) return false;
|
||||
m_handler.GotEntryDelete(id);
|
||||
break;
|
||||
case NT_MSG_ENTRY_DELETE: {
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "received ENTRY_DELETE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned int id;
|
||||
if (!Read16(&id)) return false;
|
||||
m_handler.GotEntryDelete(id);
|
||||
break;
|
||||
}
|
||||
case NT_MSG_CLEAR_ENTRIES:
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "received CLEAR_ENTRIES in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned long magic;
|
||||
if (!Read32(&magic)) return false;
|
||||
if (magic != NT_CLEAR_ALL_MAGIC)
|
||||
{
|
||||
m_error = "received incorrect CLEAR_ENTRIES magic value, ignoring";
|
||||
return true;
|
||||
}
|
||||
m_handler.GotClearEntries();
|
||||
break;
|
||||
case NT_MSG_CLEAR_ENTRIES: {
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "received CLEAR_ENTRIES in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned long magic;
|
||||
if (!Read32(&magic)) return false;
|
||||
if (magic != NT_CLEAR_ALL_MAGIC) {
|
||||
m_error = "received incorrect CLEAR_ENTRIES magic value, ignoring";
|
||||
return true;
|
||||
}
|
||||
m_handler.GotClearEntries();
|
||||
break;
|
||||
}
|
||||
case NT_MSG_EXECUTE_RPC:
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "received EXECUTE_RPC in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned int id, uid;
|
||||
if (!Read16(&id)) return false;
|
||||
if (!Read16(&uid)) return false;
|
||||
unsigned long size;
|
||||
if (!ReadULEB128(&size)) return false;
|
||||
char *params;
|
||||
if (!Read(¶ms, size)) return false;
|
||||
m_handler.GotExecuteRpc(id, uid, params, size);
|
||||
break;
|
||||
case NT_MSG_EXECUTE_RPC: {
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "received EXECUTE_RPC in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned int id, uid;
|
||||
if (!Read16(&id)) return false;
|
||||
if (!Read16(&uid)) return false;
|
||||
unsigned long size;
|
||||
if (!ReadULEB128(&size)) return false;
|
||||
char* params;
|
||||
if (!Read(¶ms, size)) return false;
|
||||
m_handler.GotExecuteRpc(id, uid, params, size);
|
||||
break;
|
||||
}
|
||||
case NT_MSG_RPC_RESPONSE:
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "received RPC_RESPONSE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned int id, uid;
|
||||
if (!Read16(&id)) return false;
|
||||
if (!Read16(&uid)) return false;
|
||||
unsigned long size;
|
||||
if (!ReadULEB128(&size)) return false;
|
||||
char *results;
|
||||
if (!Read(&results, size)) return false;
|
||||
m_handler.GotRpcResponse(id, uid, results, size);
|
||||
break;
|
||||
case NT_MSG_RPC_RESPONSE: {
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "received RPC_RESPONSE in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
unsigned int id, uid;
|
||||
if (!Read16(&id)) return false;
|
||||
if (!Read16(&uid)) return false;
|
||||
unsigned long size;
|
||||
if (!ReadULEB128(&size)) return false;
|
||||
char* results;
|
||||
if (!Read(&results, size)) return false;
|
||||
m_handler.GotRpcResponse(id, uid, results, size);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
m_error = "unrecognized message type";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
m_error = "unrecognized message type";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,84 +10,65 @@
|
||||
|
||||
#include "nt_wiredecoder.h"
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
class MessageHandler
|
||||
{
|
||||
void anchor();
|
||||
class MessageHandler {
|
||||
void anchor();
|
||||
|
||||
public:
|
||||
// Needed for protocol rev 2.0 ENTRY_UPDATE messages.
|
||||
virtual NT_Type GetEntryType(unsigned int id) = 0;
|
||||
public:
|
||||
// Needed for protocol rev 2.0 ENTRY_UPDATE messages.
|
||||
virtual NT_Type GetEntryType(unsigned int id) = 0;
|
||||
|
||||
// All of these functions are expected to take ownership of passed
|
||||
// strings/values.
|
||||
virtual ~MessageHandler() {}
|
||||
virtual void GotKeepAlive() = 0;
|
||||
virtual void GotClientHello(unsigned int proto_rev,
|
||||
NT_String& self_id) = 0;
|
||||
virtual void GotProtoUnsup(unsigned int proto_rev) = 0;
|
||||
virtual void GotServerHelloDone() = 0;
|
||||
virtual void GotServerHello(unsigned int flags,
|
||||
NT_String& self_id) = 0;
|
||||
virtual void GotClientHelloDone() = 0;
|
||||
virtual void GotEntryAssign(NT_String& name,
|
||||
unsigned int id,
|
||||
unsigned int seq_num,
|
||||
NT_Value& value,
|
||||
unsigned int flags) = 0;
|
||||
virtual void GotEntryUpdate(unsigned int id,
|
||||
unsigned int seq_num,
|
||||
NT_Value& value) = 0;
|
||||
virtual void GotFlagsUpdate(unsigned int id, unsigned int flags) = 0;
|
||||
virtual void GotEntryDelete(unsigned int id) = 0;
|
||||
virtual void GotClearEntries() = 0;
|
||||
virtual void GotExecuteRpc(unsigned int id,
|
||||
unsigned int uid,
|
||||
const char* params,
|
||||
std::size_t params_len) = 0;
|
||||
virtual void GotRpcResponse(unsigned int id,
|
||||
unsigned int uid,
|
||||
const char* results,
|
||||
std::size_t results_len) = 0;
|
||||
// All of these functions are expected to take ownership of passed
|
||||
// strings/values.
|
||||
virtual ~MessageHandler() {}
|
||||
virtual void GotKeepAlive() = 0;
|
||||
virtual void GotClientHello(unsigned int proto_rev, NT_String& self_id) = 0;
|
||||
virtual void GotProtoUnsup(unsigned int proto_rev) = 0;
|
||||
virtual void GotServerHelloDone() = 0;
|
||||
virtual void GotServerHello(unsigned int flags, NT_String& self_id) = 0;
|
||||
virtual void GotClientHelloDone() = 0;
|
||||
virtual void GotEntryAssign(NT_String& name, unsigned int id,
|
||||
unsigned int seq_num, NT_Value& value,
|
||||
unsigned int flags) = 0;
|
||||
virtual void GotEntryUpdate(unsigned int id, unsigned int seq_num,
|
||||
NT_Value& value) = 0;
|
||||
virtual void GotFlagsUpdate(unsigned int id, unsigned int flags) = 0;
|
||||
virtual void GotEntryDelete(unsigned int id) = 0;
|
||||
virtual void GotClearEntries() = 0;
|
||||
virtual void GotExecuteRpc(unsigned int id, unsigned int uid,
|
||||
const char* params, std::size_t params_len) = 0;
|
||||
virtual void GotRpcResponse(unsigned int id, unsigned int uid,
|
||||
const char* results, std::size_t results_len) = 0;
|
||||
|
||||
MessageHandler() = default;
|
||||
MessageHandler(const MessageHandler&) = delete;
|
||||
MessageHandler& operator= (const MessageHandler&) = delete;
|
||||
MessageHandler() = default;
|
||||
MessageHandler(const MessageHandler&) = delete;
|
||||
MessageHandler& operator=(const MessageHandler&) = delete;
|
||||
};
|
||||
|
||||
class MessageReader : private WireDecoder
|
||||
{
|
||||
public:
|
||||
explicit MessageReader(MessageHandler &handler,
|
||||
raw_istream& is,
|
||||
unsigned int proto_rev);
|
||||
~MessageReader();
|
||||
class MessageReader : private WireDecoder {
|
||||
public:
|
||||
explicit MessageReader(MessageHandler& handler, raw_istream& is,
|
||||
unsigned int proto_rev);
|
||||
~MessageReader();
|
||||
|
||||
void SetProtocolRev(unsigned int proto_rev)
|
||||
{
|
||||
WireDecoder::SetProtocolRev(proto_rev);
|
||||
}
|
||||
void SetProtocolRev(unsigned int proto_rev) {
|
||||
WireDecoder::SetProtocolRev(proto_rev);
|
||||
}
|
||||
|
||||
bool Run();
|
||||
bool Run();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
WireDecoder::Reset();
|
||||
}
|
||||
void Reset() { WireDecoder::Reset(); }
|
||||
|
||||
const char* GetError() const
|
||||
{
|
||||
return WireDecoder::GetError();
|
||||
}
|
||||
const char* GetError() const { return WireDecoder::GetError(); }
|
||||
|
||||
MessageReader(const MessageReader&) = delete;
|
||||
MessageReader& operator= (const MessageReader&) = delete;
|
||||
MessageReader(const MessageReader&) = delete;
|
||||
MessageReader& operator=(const MessageReader&) = delete;
|
||||
|
||||
private:
|
||||
MessageHandler& m_handler;
|
||||
private:
|
||||
MessageHandler& m_handler;
|
||||
};
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_MESSAGEREADER_H_ */
|
||||
#endif // NT_MESSAGEREADER_H_
|
||||
|
||||
@@ -9,155 +9,107 @@
|
||||
|
||||
#include "nt_internal.h"
|
||||
|
||||
using namespace NtImpl;
|
||||
using namespace ntimpl;
|
||||
|
||||
MessageWriter::~MessageWriter()
|
||||
{
|
||||
MessageWriter::~MessageWriter() {}
|
||||
|
||||
void MessageWriter::WriteKeepAlive() { Write8(NT_MSG_KEEP_ALIVE); }
|
||||
|
||||
void MessageWriter::WriteClientHello(const NT_String& self_id) {
|
||||
Write8(NT_MSG_CLIENT_HELLO);
|
||||
Write16(m_proto_rev);
|
||||
if (m_proto_rev < 0x0300u) return;
|
||||
WriteString(self_id);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteKeepAlive()
|
||||
{
|
||||
Write8(NT_MSG_KEEP_ALIVE);
|
||||
void MessageWriter::WriteProtoUnsup() {
|
||||
Write8(NT_MSG_PROTO_UNSUP);
|
||||
Write16(m_proto_rev);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteClientHello(const NT_String& self_id)
|
||||
{
|
||||
Write8(NT_MSG_CLIENT_HELLO);
|
||||
Write16(m_proto_rev);
|
||||
if (m_proto_rev < 0x0300u)
|
||||
return;
|
||||
WriteString(self_id);
|
||||
void MessageWriter::WriteServerHelloDone() { Write8(NT_MSG_SERVER_HELLO_DONE); }
|
||||
|
||||
void MessageWriter::WriteServerHello(unsigned int flags,
|
||||
const NT_String& self_id) {
|
||||
if (m_proto_rev < 0x0300u) return; // new message in version 3.0
|
||||
Write8(NT_MSG_SERVER_HELLO);
|
||||
Write8(flags);
|
||||
WriteString(self_id);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteProtoUnsup()
|
||||
{
|
||||
Write8(NT_MSG_PROTO_UNSUP);
|
||||
Write16(m_proto_rev);
|
||||
void MessageWriter::WriteClientHelloDone() {
|
||||
if (m_proto_rev < 0x0300u) return; // new message in version 3.0
|
||||
Write8(NT_MSG_CLIENT_HELLO_DONE);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteServerHelloDone()
|
||||
{
|
||||
Write8(NT_MSG_SERVER_HELLO_DONE);
|
||||
void MessageWriter::WriteEntryAssign(const NT_String& name, unsigned int id,
|
||||
unsigned int seq_num,
|
||||
const NT_Value& value,
|
||||
unsigned int flags) {
|
||||
Write8(NT_MSG_ENTRY_ASSIGN);
|
||||
WriteString(name);
|
||||
WriteType(value.type);
|
||||
Write16(id);
|
||||
Write16(seq_num);
|
||||
if (m_proto_rev >= 0x0300u) Write8(flags);
|
||||
WriteValue(value);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteServerHello(unsigned int flags, const NT_String& self_id)
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
return; // new message in version 3.0
|
||||
Write8(NT_MSG_SERVER_HELLO);
|
||||
Write8(flags);
|
||||
WriteString(self_id);
|
||||
void MessageWriter::WriteEntryUpdate(unsigned int id, unsigned int seq_num,
|
||||
const NT_Value& value) {
|
||||
Write8(NT_MSG_ENTRY_UPDATE);
|
||||
Write16(id);
|
||||
Write16(seq_num);
|
||||
if (m_proto_rev >= 0x0300u) Write8(value.type);
|
||||
WriteValue(value);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteClientHelloDone()
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
return; // new message in version 3.0
|
||||
Write8(NT_MSG_CLIENT_HELLO_DONE);
|
||||
void MessageWriter::WriteFlagsUpdate(unsigned int id, unsigned int flags) {
|
||||
if (m_proto_rev < 0x0300u) return; // new message in version 3.0
|
||||
Write8(NT_MSG_FLAGS_UPDATE);
|
||||
Write16(id);
|
||||
Write8(flags);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteEntryAssign(const NT_String& name,
|
||||
unsigned int id,
|
||||
unsigned int seq_num,
|
||||
const NT_Value& value,
|
||||
unsigned int flags)
|
||||
{
|
||||
Write8(NT_MSG_ENTRY_ASSIGN);
|
||||
WriteString(name);
|
||||
WriteType(value.type);
|
||||
Write16(id);
|
||||
Write16(seq_num);
|
||||
if (m_proto_rev >= 0x0300u)
|
||||
Write8(flags);
|
||||
WriteValue(value);
|
||||
void MessageWriter::WriteEntryDelete(unsigned int id) {
|
||||
if (m_proto_rev < 0x0300u) return; // new message in version 3.0
|
||||
Write8(NT_MSG_ENTRY_DELETE);
|
||||
Write16(id);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteEntryUpdate(unsigned int id,
|
||||
unsigned int seq_num,
|
||||
const NT_Value& value)
|
||||
{
|
||||
Write8(NT_MSG_ENTRY_UPDATE);
|
||||
Write16(id);
|
||||
Write16(seq_num);
|
||||
if (m_proto_rev >= 0x0300u)
|
||||
Write8(value.type);
|
||||
WriteValue(value);
|
||||
void MessageWriter::WriteClearEntries() {
|
||||
if (m_proto_rev < 0x0300u) return; // new message in version 3.0
|
||||
|
||||
Write8(NT_MSG_CLEAR_ENTRIES);
|
||||
Write32(NT_CLEAR_ALL_MAGIC);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteFlagsUpdate(unsigned int id, unsigned int flags)
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
return; // new message in version 3.0
|
||||
Write8(NT_MSG_FLAGS_UPDATE);
|
||||
Write16(id);
|
||||
Write8(flags);
|
||||
void MessageWriter::WriteExecuteRpc(unsigned int id, unsigned int uid,
|
||||
const NT_Value* params_start,
|
||||
const NT_Value* params_end) {
|
||||
WriteRpc(NT_MSG_EXECUTE_RPC, id, uid, params_start, params_end);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteEntryDelete(unsigned int id)
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
return; // new message in version 3.0
|
||||
Write8(NT_MSG_ENTRY_DELETE);
|
||||
Write16(id);
|
||||
void MessageWriter::WriteRpcResponse(unsigned int id, unsigned int uid,
|
||||
const NT_Value* results_start,
|
||||
const NT_Value* results_end) {
|
||||
WriteRpc(NT_MSG_RPC_RESPONSE, id, uid, results_start, results_end);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteClearEntries()
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
return; // new message in version 3.0
|
||||
void MessageWriter::WriteRpc(unsigned int msg_type, unsigned int id,
|
||||
unsigned int uid, const NT_Value* values_start,
|
||||
const NT_Value* values_end) {
|
||||
if (m_proto_rev < 0x0300u) return; // new message in version 3.0
|
||||
|
||||
Write8(NT_MSG_CLEAR_ENTRIES);
|
||||
Write32(NT_CLEAR_ALL_MAGIC);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteExecuteRpc(unsigned int id,
|
||||
unsigned int uid,
|
||||
const NT_Value* params_start,
|
||||
const NT_Value* params_end)
|
||||
{
|
||||
WriteRpc(NT_MSG_EXECUTE_RPC, id, uid, params_start, params_end);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteRpcResponse(unsigned int id,
|
||||
unsigned int uid,
|
||||
const NT_Value* results_start,
|
||||
const NT_Value* results_end)
|
||||
{
|
||||
WriteRpc(NT_MSG_RPC_RESPONSE, id, uid, results_start, results_end);
|
||||
}
|
||||
|
||||
void
|
||||
MessageWriter::WriteRpc(unsigned int msg_type,
|
||||
unsigned int id,
|
||||
unsigned int uid,
|
||||
const NT_Value* values_start,
|
||||
const NT_Value* values_end)
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
return; // new message in version 3.0
|
||||
|
||||
Write8(msg_type);
|
||||
Write16(id);
|
||||
Write16(uid);
|
||||
|
||||
unsigned long len = 0;
|
||||
for (const NT_Value* value = values_start; value != values_end; ++value)
|
||||
len += GetValueSize(*value);
|
||||
WriteULEB128(len);
|
||||
|
||||
for (const NT_Value* value = values_start; value != values_end; ++value)
|
||||
WriteValue(*value);
|
||||
Write8(msg_type);
|
||||
Write16(id);
|
||||
Write16(uid);
|
||||
|
||||
unsigned long len = 0;
|
||||
for (const NT_Value* value = values_start; value != values_end; ++value)
|
||||
len += GetValueSize(*value);
|
||||
WriteULEB128(len);
|
||||
|
||||
for (const NT_Value* value = values_start; value != values_end; ++value)
|
||||
WriteValue(*value);
|
||||
}
|
||||
|
||||
@@ -10,76 +10,54 @@
|
||||
|
||||
#include "nt_wireencoder.h"
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
class MessageWriter : private WireEncoder
|
||||
{
|
||||
public:
|
||||
explicit MessageWriter(unsigned int proto_rev) : WireEncoder(proto_rev) {}
|
||||
~MessageWriter();
|
||||
class MessageWriter : private WireEncoder {
|
||||
public:
|
||||
explicit MessageWriter(unsigned int proto_rev) : WireEncoder(proto_rev) {}
|
||||
~MessageWriter();
|
||||
|
||||
void SetProtocolRev(unsigned int proto_rev)
|
||||
{
|
||||
WireEncoder::SetProtocolRev(proto_rev);
|
||||
}
|
||||
void SetProtocolRev(unsigned int proto_rev) {
|
||||
WireEncoder::SetProtocolRev(proto_rev);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
WireEncoder::Reset();
|
||||
}
|
||||
void Reset() { WireEncoder::Reset(); }
|
||||
|
||||
const char* GetError() const
|
||||
{
|
||||
return WireEncoder::GetError();
|
||||
}
|
||||
const char* GetError() const { return WireEncoder::GetError(); }
|
||||
|
||||
const char* GetData() const
|
||||
{
|
||||
return WireEncoder::GetData();
|
||||
}
|
||||
const char* GetData() const { return WireEncoder::GetData(); }
|
||||
|
||||
std::size_t GetSize() const
|
||||
{
|
||||
return WireEncoder::GetSize();
|
||||
}
|
||||
std::size_t GetSize() const { return WireEncoder::GetSize(); }
|
||||
|
||||
void WriteKeepAlive();
|
||||
void WriteClientHello(const NT_String& self_id);
|
||||
void WriteProtoUnsup();
|
||||
void WriteServerHelloDone();
|
||||
void WriteServerHello(unsigned int flags, const NT_String& self_id);
|
||||
void WriteClientHelloDone();
|
||||
void WriteEntryAssign(const NT_String& name,
|
||||
unsigned int id,
|
||||
unsigned int seq_num,
|
||||
const NT_Value& value,
|
||||
unsigned int flags);
|
||||
void WriteEntryUpdate(unsigned int id,
|
||||
unsigned int seq_num,
|
||||
const NT_Value& value);
|
||||
void WriteFlagsUpdate(unsigned int id, unsigned int flags);
|
||||
void WriteEntryDelete(unsigned int id);
|
||||
void WriteClearEntries();
|
||||
void WriteExecuteRpc(unsigned int id,
|
||||
unsigned int uid,
|
||||
const NT_Value* params_start,
|
||||
const NT_Value* params_end);
|
||||
void WriteRpcResponse(unsigned int id,
|
||||
unsigned int uid,
|
||||
const NT_Value* results_start,
|
||||
const NT_Value* results_end);
|
||||
void WriteKeepAlive();
|
||||
void WriteClientHello(const NT_String& self_id);
|
||||
void WriteProtoUnsup();
|
||||
void WriteServerHelloDone();
|
||||
void WriteServerHello(unsigned int flags, const NT_String& self_id);
|
||||
void WriteClientHelloDone();
|
||||
void WriteEntryAssign(const NT_String& name, unsigned int id,
|
||||
unsigned int seq_num, const NT_Value& value,
|
||||
unsigned int flags);
|
||||
void WriteEntryUpdate(unsigned int id, unsigned int seq_num,
|
||||
const NT_Value& value);
|
||||
void WriteFlagsUpdate(unsigned int id, unsigned int flags);
|
||||
void WriteEntryDelete(unsigned int id);
|
||||
void WriteClearEntries();
|
||||
void WriteExecuteRpc(unsigned int id, unsigned int uid,
|
||||
const NT_Value* params_start,
|
||||
const NT_Value* params_end);
|
||||
void WriteRpcResponse(unsigned int id, unsigned int uid,
|
||||
const NT_Value* results_start,
|
||||
const NT_Value* results_end);
|
||||
|
||||
MessageWriter(const MessageWriter&) = delete;
|
||||
MessageWriter& operator= (const MessageWriter&) = delete;
|
||||
MessageWriter(const MessageWriter&) = delete;
|
||||
MessageWriter& operator=(const MessageWriter&) = delete;
|
||||
|
||||
private:
|
||||
void WriteRpc(unsigned int msg_type,
|
||||
unsigned int id,
|
||||
unsigned int uid,
|
||||
const NT_Value* values_start,
|
||||
const NT_Value* values_end);
|
||||
private:
|
||||
void WriteRpc(unsigned int msg_type, unsigned int id, unsigned int uid,
|
||||
const NT_Value* values_start, const NT_Value* values_end);
|
||||
};
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_MESSAGEWRITER_H_ */
|
||||
#endif // NT_MESSAGEWRITER_H_
|
||||
|
||||
@@ -13,142 +13,143 @@
|
||||
#include "nt_base64.h"
|
||||
#include "nt_storage.h"
|
||||
|
||||
using namespace NtImpl;
|
||||
using namespace ntimpl;
|
||||
|
||||
static void
|
||||
write_string(FILE* f, llvm::StringRef str)
|
||||
{
|
||||
fputc('"', f);
|
||||
for (unsigned int i = 0, e = str.size(); i != e; ++i)
|
||||
{
|
||||
unsigned char c = str[i];
|
||||
static void write_string(FILE* f, llvm::StringRef str) {
|
||||
fputc('"', f);
|
||||
for (unsigned int i = 0, e = str.size(); i != e; ++i) {
|
||||
unsigned char c = str[i];
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\\': fputs("\\\\", f); break;
|
||||
case '\t': fputs("\\t", f); break;
|
||||
case '\n': fputs("\\n", f); break;
|
||||
case '"': fputs("\\\"", f); break;
|
||||
default:
|
||||
if (std::isprint(c))
|
||||
{
|
||||
fputc(c, f);
|
||||
break;
|
||||
}
|
||||
|
||||
// Write out the escaped representation.
|
||||
fputs("\\x", f);
|
||||
fputc(llvm::hexdigit((c >> 4 & 0xF)), f);
|
||||
fputc(llvm::hexdigit((c >> 0) & 0xF), f);
|
||||
switch (c) {
|
||||
case '\\':
|
||||
fputs("\\\\", f);
|
||||
break;
|
||||
case '\t':
|
||||
fputs("\\t", f);
|
||||
break;
|
||||
case '\n':
|
||||
fputs("\\n", f);
|
||||
break;
|
||||
case '"':
|
||||
fputs("\\\"", f);
|
||||
break;
|
||||
default:
|
||||
if (std::isprint(c)) {
|
||||
fputc(c, f);
|
||||
break;
|
||||
}
|
||||
|
||||
// Write out the escaped representation.
|
||||
fputs("\\x", f);
|
||||
fputc(llvm::hexdigit((c >> 4 & 0xF)), f);
|
||||
fputc(llvm::hexdigit((c >> 0) & 0xF), f);
|
||||
}
|
||||
fputc('"', f);
|
||||
}
|
||||
fputc('"', f);
|
||||
}
|
||||
|
||||
const char*
|
||||
NT_SavePersistent(const char* filename)
|
||||
{
|
||||
FILE* f = fopen(filename, "wt");
|
||||
if (!f)
|
||||
return "could not open file";
|
||||
const char* NT_SavePersistent(const char* filename) {
|
||||
FILE* f = fopen(filename, "wt");
|
||||
if (!f) return "could not open file";
|
||||
|
||||
fputs("[NetworkTables Storage 3.0]\n", f);
|
||||
fputs("[NetworkTables Storage 3.0]\n", f);
|
||||
|
||||
Storage& storage = Storage::GetInstance();
|
||||
for (Storage::EntriesMap::const_iterator i = storage.entries.begin(),
|
||||
end = storage.entries.end(); i != end; ++i)
|
||||
{
|
||||
const StorageEntry& entry = i->getValue();
|
||||
// only write persistent-flagged values
|
||||
if ((entry.flags & NT_PERSISTENT) == 0)
|
||||
continue;
|
||||
Storage& storage = Storage::GetInstance();
|
||||
for (Storage::EntriesMap::const_iterator i = storage.entries.begin(),
|
||||
end = storage.entries.end();
|
||||
i != end; ++i) {
|
||||
const StorageEntry& entry = i->getValue();
|
||||
// only write persistent-flagged values
|
||||
if ((entry.flags & NT_PERSISTENT) == 0) continue;
|
||||
|
||||
// type
|
||||
const NT_Value& v = entry.value;
|
||||
switch (v.type)
|
||||
{
|
||||
case NT_BOOLEAN: fputs("boolean ", f); break;
|
||||
case NT_DOUBLE: fputs("double ", f); break;
|
||||
case NT_STRING: fputs("string ", f); break;
|
||||
case NT_RAW: fputs("raw ", f); break;
|
||||
case NT_BOOLEAN_ARRAY: fputs("array boolean ", f); break;
|
||||
case NT_DOUBLE_ARRAY: fputs("array double ", f); break;
|
||||
case NT_STRING_ARRAY: fputs("array string ", f); break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// name
|
||||
write_string(f, i->getKey());
|
||||
|
||||
// =
|
||||
fputc('=', f);
|
||||
|
||||
// value
|
||||
switch (v.type)
|
||||
{
|
||||
case NT_BOOLEAN:
|
||||
fputs(v.data.v_boolean ? "true" : "false", f);
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
fprintf(f, "%g", v.data.v_double);
|
||||
break;
|
||||
case NT_STRING:
|
||||
write_string(f, make_StringRef(v.data.v_string));
|
||||
break;
|
||||
case NT_RAW:
|
||||
{
|
||||
char* buf = new char[base64encode_len(v.data.v_raw.len)];
|
||||
base64encode(buf,
|
||||
reinterpret_cast<const unsigned char*>(v.data.v_raw.str),
|
||||
v.data.v_raw.len);
|
||||
fputs(buf, f);
|
||||
delete[] buf;
|
||||
break;
|
||||
}
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
for (size_t i=0; i<v.data.arr_boolean.size; ++i)
|
||||
{
|
||||
fputs(v.data.arr_boolean.arr[i] ? "true" : "false", f);
|
||||
if (i != (v.data.arr_boolean.size - 1))
|
||||
fputc(',', f);
|
||||
}
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
for (size_t i=0; i<v.data.arr_double.size; ++i)
|
||||
{
|
||||
fprintf(f, "%g", v.data.arr_double.arr[i]);
|
||||
if (i != (v.data.arr_double.size - 1))
|
||||
fputc(',', f);
|
||||
}
|
||||
break;
|
||||
case NT_STRING_ARRAY:
|
||||
for (size_t i=0; i<v.data.arr_double.size; ++i)
|
||||
{
|
||||
write_string(f, make_StringRef(v.data.arr_string.arr[i]));
|
||||
if (i != (v.data.arr_double.size - 1))
|
||||
fputc(',', f);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// eol
|
||||
fputc('\n', f);
|
||||
// type
|
||||
const NT_Value& v = entry.value;
|
||||
switch (v.type) {
|
||||
case NT_BOOLEAN:
|
||||
fputs("boolean ", f);
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
fputs("double ", f);
|
||||
break;
|
||||
case NT_STRING:
|
||||
fputs("string ", f);
|
||||
break;
|
||||
case NT_RAW:
|
||||
fputs("raw ", f);
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
fputs("array boolean ", f);
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
fputs("array double ", f);
|
||||
break;
|
||||
case NT_STRING_ARRAY:
|
||||
fputs("array string ", f);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
// name
|
||||
write_string(f, i->getKey());
|
||||
|
||||
// =
|
||||
fputc('=', f);
|
||||
|
||||
// value
|
||||
switch (v.type) {
|
||||
case NT_BOOLEAN:
|
||||
fputs(v.data.v_boolean ? "true" : "false", f);
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
fprintf(f, "%g", v.data.v_double);
|
||||
break;
|
||||
case NT_STRING:
|
||||
write_string(f, make_StringRef(v.data.v_string));
|
||||
break;
|
||||
case NT_RAW: {
|
||||
char* buf = new char[base64encode_len(v.data.v_raw.len)];
|
||||
base64encode(buf,
|
||||
reinterpret_cast<const unsigned char*>(v.data.v_raw.str),
|
||||
v.data.v_raw.len);
|
||||
fputs(buf, f);
|
||||
delete[] buf;
|
||||
break;
|
||||
}
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
for (size_t i = 0; i < v.data.arr_boolean.size; ++i) {
|
||||
fputs(v.data.arr_boolean.arr[i] ? "true" : "false", f);
|
||||
if (i != (v.data.arr_boolean.size - 1)) fputc(',', f);
|
||||
}
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
for (size_t i = 0; i < v.data.arr_double.size; ++i) {
|
||||
fprintf(f, "%g", v.data.arr_double.arr[i]);
|
||||
if (i != (v.data.arr_double.size - 1)) fputc(',', f);
|
||||
}
|
||||
break;
|
||||
case NT_STRING_ARRAY:
|
||||
for (size_t i = 0; i < v.data.arr_double.size; ++i) {
|
||||
write_string(f, make_StringRef(v.data.arr_string.arr[i]));
|
||||
if (i != (v.data.arr_double.size - 1)) fputc(',', f);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// eol
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char*
|
||||
NT_LoadPersistent(const char* filename)
|
||||
{
|
||||
FILE* f = fopen(filename, "rt");
|
||||
if (!f)
|
||||
return "could not open file";
|
||||
const char* NT_LoadPersistent(const char* filename) {
|
||||
FILE* f = fopen(filename, "rt");
|
||||
if (!f) return "could not open file";
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -9,20 +9,14 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace NtImpl;
|
||||
using namespace ntimpl;
|
||||
|
||||
void
|
||||
raw_istream::anchor()
|
||||
{
|
||||
}
|
||||
void raw_istream::anchor() {}
|
||||
|
||||
bool
|
||||
raw_mem_istream::read(void* data, std::size_t len)
|
||||
{
|
||||
if (len > m_left)
|
||||
return false;
|
||||
std::memcpy(data, m_cur, len);
|
||||
m_cur += len;
|
||||
m_left -= len;
|
||||
return true;
|
||||
bool raw_mem_istream::read(void* data, std::size_t len) {
|
||||
if (len > m_left) return false;
|
||||
std::memcpy(data, m_cur, len);
|
||||
m_cur += len;
|
||||
m_left -= len;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,35 +10,33 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
class raw_istream
|
||||
{
|
||||
void anchor();
|
||||
public:
|
||||
raw_istream() {}
|
||||
virtual ~raw_istream() {}
|
||||
virtual bool read(void* data, std::size_t len) = 0;
|
||||
virtual void close() = 0;
|
||||
class raw_istream {
|
||||
void anchor();
|
||||
|
||||
raw_istream(const raw_istream&) = delete;
|
||||
raw_istream& operator= (const raw_istream&) = delete;
|
||||
public:
|
||||
raw_istream() {}
|
||||
virtual ~raw_istream() {}
|
||||
virtual bool read(void* data, std::size_t len) = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
raw_istream(const raw_istream&) = delete;
|
||||
raw_istream& operator=(const raw_istream&) = delete;
|
||||
};
|
||||
|
||||
class raw_mem_istream : public raw_istream
|
||||
{
|
||||
public:
|
||||
raw_mem_istream(const char* mem, std::size_t len)
|
||||
: m_cur(mem), m_left(len)
|
||||
{}
|
||||
virtual ~raw_mem_istream() {}
|
||||
virtual bool read(void* data, std::size_t len);
|
||||
virtual void close() {}
|
||||
private:
|
||||
const char* m_cur;
|
||||
std::size_t m_left;
|
||||
class raw_mem_istream : public raw_istream {
|
||||
public:
|
||||
raw_mem_istream(const char* mem, std::size_t len) : m_cur(mem), m_left(len) {}
|
||||
virtual ~raw_mem_istream() {}
|
||||
virtual bool read(void* data, std::size_t len);
|
||||
virtual void close() {}
|
||||
|
||||
private:
|
||||
const char* m_cur;
|
||||
std::size_t m_left;
|
||||
};
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_RAW_ISTREAM_H_ */
|
||||
#endif // NT_RAW_ISTREAM_H_
|
||||
|
||||
@@ -7,26 +7,24 @@
|
||||
|
||||
#include "nt_seqnum.h"
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
bool operator< (const SequenceNumber& lhs, const SequenceNumber& rhs)
|
||||
{
|
||||
if (lhs.m_val < rhs.m_val)
|
||||
return (rhs.m_val - lhs.m_val) < (1u<<15);
|
||||
else if (lhs.m_val > rhs.m_val)
|
||||
return (lhs.m_val - rhs.m_val) > (1u<<15);
|
||||
else
|
||||
return false;
|
||||
bool operator<(const SequenceNumber& lhs, const SequenceNumber& rhs) {
|
||||
if (lhs.m_val < rhs.m_val)
|
||||
return (rhs.m_val - lhs.m_val) < (1u << 15);
|
||||
else if (lhs.m_val > rhs.m_val)
|
||||
return (lhs.m_val - rhs.m_val) > (1u << 15);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator> (const SequenceNumber& lhs, const SequenceNumber& rhs)
|
||||
{
|
||||
if (lhs.m_val < rhs.m_val)
|
||||
return (rhs.m_val - lhs.m_val) > (1u<<15);
|
||||
else if (lhs.m_val > rhs.m_val)
|
||||
return (lhs.m_val - rhs.m_val) < (1u<<15);
|
||||
else
|
||||
return false;
|
||||
bool operator>(const SequenceNumber& lhs, const SequenceNumber& rhs) {
|
||||
if (lhs.m_val < rhs.m_val)
|
||||
return (rhs.m_val - lhs.m_val) > (1u << 15);
|
||||
else if (lhs.m_val > rhs.m_val)
|
||||
return (lhs.m_val - rhs.m_val) < (1u << 15);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
@@ -8,67 +8,54 @@
|
||||
#ifndef NT_SEQNUM_H_
|
||||
#define NT_SEQNUM_H_
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
class SequenceNumber
|
||||
{
|
||||
public:
|
||||
explicit SequenceNumber(unsigned int val) : m_val(val) {}
|
||||
unsigned int GetVal() const { return m_val; }
|
||||
class SequenceNumber {
|
||||
public:
|
||||
explicit SequenceNumber(unsigned int val) : m_val(val) {}
|
||||
unsigned int GetVal() const { return m_val; }
|
||||
|
||||
SequenceNumber& operator++()
|
||||
{
|
||||
++m_val;
|
||||
if (m_val > 0xffff)
|
||||
m_val = 0;
|
||||
return *this;
|
||||
}
|
||||
SequenceNumber operator++(int)
|
||||
{
|
||||
SequenceNumber tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
SequenceNumber& operator++() {
|
||||
++m_val;
|
||||
if (m_val > 0xffff) m_val = 0;
|
||||
return *this;
|
||||
}
|
||||
SequenceNumber operator++(int) {
|
||||
SequenceNumber tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
friend bool operator< (const SequenceNumber& lhs,
|
||||
const SequenceNumber& rhs);
|
||||
friend bool operator> (const SequenceNumber& lhs,
|
||||
const SequenceNumber& rhs);
|
||||
friend bool operator<= (const SequenceNumber& lhs,
|
||||
const SequenceNumber& rhs);
|
||||
friend bool operator>= (const SequenceNumber& lhs,
|
||||
const SequenceNumber& rhs);
|
||||
friend bool operator== (const SequenceNumber& lhs,
|
||||
const SequenceNumber& rhs);
|
||||
friend bool operator!= (const SequenceNumber& lhs,
|
||||
const SequenceNumber& rhs);
|
||||
private:
|
||||
unsigned int m_val;
|
||||
friend bool operator<(const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
friend bool operator>(const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
friend bool operator<=(const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
friend bool operator>=(const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
friend bool operator==(const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
friend bool operator!=(const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
|
||||
private:
|
||||
unsigned int m_val;
|
||||
};
|
||||
|
||||
bool operator< (const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
bool operator> (const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
bool operator<(const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
bool operator>(const SequenceNumber& lhs, const SequenceNumber& rhs);
|
||||
|
||||
inline bool operator<= (const SequenceNumber& lhs, const SequenceNumber& rhs)
|
||||
{
|
||||
return lhs == rhs || lhs < rhs;
|
||||
inline bool operator<=(const SequenceNumber& lhs, const SequenceNumber& rhs) {
|
||||
return lhs == rhs || lhs < rhs;
|
||||
}
|
||||
|
||||
inline bool operator>= (const SequenceNumber& lhs, const SequenceNumber& rhs)
|
||||
{
|
||||
return lhs == rhs || lhs > rhs;
|
||||
inline bool operator>=(const SequenceNumber& lhs, const SequenceNumber& rhs) {
|
||||
return lhs == rhs || lhs > rhs;
|
||||
}
|
||||
|
||||
inline bool operator== (const SequenceNumber& lhs, const SequenceNumber& rhs)
|
||||
{
|
||||
return lhs.m_val == rhs.m_val;
|
||||
inline bool operator==(const SequenceNumber& lhs, const SequenceNumber& rhs) {
|
||||
return lhs.m_val == rhs.m_val;
|
||||
}
|
||||
|
||||
inline bool operator!= (const SequenceNumber& lhs, const SequenceNumber& rhs)
|
||||
{
|
||||
return lhs.m_val != rhs.m_val;
|
||||
inline bool operator!=(const SequenceNumber& lhs, const SequenceNumber& rhs) {
|
||||
return lhs.m_val != rhs.m_val;
|
||||
}
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_SEQNUM_H_ */
|
||||
#endif // NT_SEQNUM_H_
|
||||
|
||||
@@ -7,14 +7,10 @@
|
||||
|
||||
#include "nt_storage.h"
|
||||
|
||||
using namespace NtImpl;
|
||||
using namespace ntimpl;
|
||||
|
||||
Storage* Storage::m_instance = nullptr;
|
||||
|
||||
Storage::Storage()
|
||||
{
|
||||
}
|
||||
Storage::Storage() {}
|
||||
|
||||
Storage::~Storage()
|
||||
{
|
||||
}
|
||||
Storage::~Storage() {}
|
||||
|
||||
@@ -12,55 +12,46 @@
|
||||
|
||||
#include "llvm/StringMap.h"
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
inline llvm::StringRef
|
||||
make_StringRef(const NT_String& str)
|
||||
{
|
||||
return llvm::StringRef(str.str, str.len);
|
||||
inline llvm::StringRef make_StringRef(const NT_String& str) {
|
||||
return llvm::StringRef(str.str, str.len);
|
||||
}
|
||||
|
||||
class StorageEntry
|
||||
{
|
||||
public:
|
||||
StorageEntry()
|
||||
{
|
||||
NT_InitValue(&value);
|
||||
flags = 0;
|
||||
}
|
||||
~StorageEntry()
|
||||
{
|
||||
NT_DisposeValue(&value);
|
||||
}
|
||||
NT_Value value;
|
||||
unsigned int flags;
|
||||
class StorageEntry {
|
||||
public:
|
||||
StorageEntry() {
|
||||
NT_InitValue(&value);
|
||||
flags = 0;
|
||||
}
|
||||
~StorageEntry() { NT_DisposeValue(&value); }
|
||||
|
||||
StorageEntry(const StorageEntry&) = delete;
|
||||
StorageEntry& operator= (const StorageEntry&) = delete;
|
||||
NT_Value value;
|
||||
unsigned int flags;
|
||||
|
||||
StorageEntry(const StorageEntry&) = delete;
|
||||
StorageEntry& operator=(const StorageEntry&) = delete;
|
||||
};
|
||||
|
||||
class Storage
|
||||
{
|
||||
public:
|
||||
static Storage& GetInstance()
|
||||
{
|
||||
if (!m_instance)
|
||||
m_instance = new Storage;
|
||||
return *m_instance;
|
||||
}
|
||||
class Storage {
|
||||
public:
|
||||
static Storage& GetInstance() {
|
||||
if (!m_instance) m_instance = new Storage;
|
||||
return *m_instance;
|
||||
}
|
||||
|
||||
typedef llvm::StringMap<StorageEntry> EntriesMap;
|
||||
EntriesMap entries;
|
||||
typedef llvm::StringMap<StorageEntry> EntriesMap;
|
||||
EntriesMap entries;
|
||||
|
||||
private:
|
||||
Storage();
|
||||
~Storage();
|
||||
Storage(const Storage&) = delete;
|
||||
Storage& operator= (const Storage&) = delete;
|
||||
private:
|
||||
Storage();
|
||||
~Storage();
|
||||
Storage(const Storage&) = delete;
|
||||
Storage& operator=(const Storage&) = delete;
|
||||
|
||||
static Storage* m_instance;
|
||||
static Storage* m_instance;
|
||||
};
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_STORAGE_H_ */
|
||||
#endif // NT_STORAGE_H_
|
||||
|
||||
@@ -10,67 +10,55 @@
|
||||
|
||||
#include "ntcore.h"
|
||||
|
||||
void
|
||||
NT_DisposeValue(NT_Value *value)
|
||||
{
|
||||
switch (value->type)
|
||||
{
|
||||
void NT_DisposeValue(NT_Value *value) {
|
||||
switch (value->type) {
|
||||
case NT_UNASSIGNED:
|
||||
case NT_BOOLEAN:
|
||||
case NT_DOUBLE:
|
||||
break;
|
||||
break;
|
||||
case NT_STRING:
|
||||
case NT_RAW:
|
||||
case NT_RPC:
|
||||
std::free(value->data.v_string.str);
|
||||
break;
|
||||
std::free(value->data.v_string.str);
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
std::free(value->data.arr_boolean.arr);
|
||||
break;
|
||||
std::free(value->data.arr_boolean.arr);
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
std::free(value->data.arr_double.arr);
|
||||
break;
|
||||
case NT_STRING_ARRAY:
|
||||
{
|
||||
for (size_t i=0; i<value->data.arr_string.size; i++)
|
||||
std::free(value->data.arr_string.arr[i].str);
|
||||
std::free(value->data.arr_string.arr);
|
||||
break;
|
||||
std::free(value->data.arr_double.arr);
|
||||
break;
|
||||
case NT_STRING_ARRAY: {
|
||||
for (size_t i = 0; i < value->data.arr_string.size; i++)
|
||||
std::free(value->data.arr_string.arr[i].str);
|
||||
std::free(value->data.arr_string.arr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0 && "unknown value type");
|
||||
}
|
||||
value->type = NT_UNASSIGNED;
|
||||
value->last_change = 0;
|
||||
assert(0 && "unknown value type");
|
||||
}
|
||||
value->type = NT_UNASSIGNED;
|
||||
value->last_change = 0;
|
||||
}
|
||||
|
||||
void
|
||||
NT_InitValue(NT_Value *value)
|
||||
{
|
||||
value->type = NT_UNASSIGNED;
|
||||
value->last_change = 0;
|
||||
void NT_InitValue(NT_Value *value) {
|
||||
value->type = NT_UNASSIGNED;
|
||||
value->last_change = 0;
|
||||
}
|
||||
|
||||
void
|
||||
NT_DisposeString(NT_String *str)
|
||||
{
|
||||
std::free(str->str);
|
||||
str->str = nullptr;
|
||||
str->len = 0;
|
||||
void NT_DisposeString(NT_String *str) {
|
||||
std::free(str->str);
|
||||
str->str = nullptr;
|
||||
str->len = 0;
|
||||
}
|
||||
|
||||
void
|
||||
NT_InitString(NT_String *str)
|
||||
{
|
||||
str->str = nullptr;
|
||||
str->len = 0;
|
||||
void NT_InitString(NT_String *str) {
|
||||
str->str = nullptr;
|
||||
str->len = 0;
|
||||
}
|
||||
|
||||
void
|
||||
NT_DisposeConnectionInfoArray(NT_ConnectionInfo *arr, size_t count)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i=0; i<count; i++)
|
||||
std::free(arr[i].remote_id.str);
|
||||
std::free(arr);
|
||||
void NT_DisposeConnectionInfoArray(NT_ConnectionInfo *arr, size_t count) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < count; i++)
|
||||
std::free(arr[i].remote_id.str);
|
||||
std::free(arr);
|
||||
}
|
||||
|
||||
@@ -12,56 +12,45 @@
|
||||
|
||||
#include "ntcore.h"
|
||||
|
||||
bool
|
||||
operator== (const NT_Value& lhs, const NT_Value& rhs)
|
||||
{
|
||||
if (lhs.type != rhs.type)
|
||||
return false;
|
||||
switch (lhs.type)
|
||||
{
|
||||
bool operator==(const NT_Value& lhs, const NT_Value& rhs) {
|
||||
if (lhs.type != rhs.type) return false;
|
||||
switch (lhs.type) {
|
||||
case NT_UNASSIGNED:
|
||||
return true; // XXX: is this better being false instead?
|
||||
return true; // XXX: is this better being false instead?
|
||||
case NT_BOOLEAN:
|
||||
return lhs.data.v_boolean == rhs.data.v_boolean;
|
||||
return lhs.data.v_boolean == rhs.data.v_boolean;
|
||||
case NT_DOUBLE:
|
||||
return lhs.data.v_double == rhs.data.v_double;
|
||||
return lhs.data.v_double == rhs.data.v_double;
|
||||
case NT_STRING:
|
||||
case NT_RAW:
|
||||
case NT_RPC:
|
||||
if (lhs.data.v_string.len != rhs.data.v_string.len)
|
||||
return false;
|
||||
return std::memcmp(lhs.data.v_string.str, rhs.data.v_string.str,
|
||||
lhs.data.v_string.len) == 0;
|
||||
if (lhs.data.v_string.len != rhs.data.v_string.len) return false;
|
||||
return std::memcmp(lhs.data.v_string.str, rhs.data.v_string.str,
|
||||
lhs.data.v_string.len) == 0;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
if (lhs.data.arr_boolean.size != rhs.data.arr_boolean.size)
|
||||
return false;
|
||||
return std::memcmp(lhs.data.arr_boolean.arr, rhs.data.arr_boolean.arr,
|
||||
lhs.data.arr_boolean.size *
|
||||
sizeof(lhs.data.arr_boolean.arr[0])) == 0;
|
||||
if (lhs.data.arr_boolean.size != rhs.data.arr_boolean.size) return false;
|
||||
return std::memcmp(lhs.data.arr_boolean.arr, rhs.data.arr_boolean.arr,
|
||||
lhs.data.arr_boolean.size *
|
||||
sizeof(lhs.data.arr_boolean.arr[0])) == 0;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
if (lhs.data.arr_double.size != rhs.data.arr_double.size)
|
||||
return false;
|
||||
return std::memcmp(lhs.data.arr_double.arr, rhs.data.arr_double.arr,
|
||||
lhs.data.arr_double.size *
|
||||
sizeof(lhs.data.arr_double.arr[0])) == 0;
|
||||
case NT_STRING_ARRAY:
|
||||
{
|
||||
if (lhs.data.arr_string.size != rhs.data.arr_string.size)
|
||||
return false;
|
||||
for (size_t i=0; i<lhs.data.arr_string.size; i++)
|
||||
{
|
||||
if (lhs.data.arr_string.arr[i].len !=
|
||||
rhs.data.arr_string.arr[i].len)
|
||||
return false;
|
||||
if (std::memcmp(lhs.data.arr_string.arr[i].str,
|
||||
rhs.data.arr_string.arr[i].str,
|
||||
lhs.data.arr_string.arr[i].len) != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (lhs.data.arr_double.size != rhs.data.arr_double.size) return false;
|
||||
return std::memcmp(lhs.data.arr_double.arr, rhs.data.arr_double.arr,
|
||||
lhs.data.arr_double.size *
|
||||
sizeof(lhs.data.arr_double.arr[0])) == 0;
|
||||
case NT_STRING_ARRAY: {
|
||||
if (lhs.data.arr_string.size != rhs.data.arr_string.size) return false;
|
||||
for (size_t i = 0; i < lhs.data.arr_string.size; i++) {
|
||||
if (lhs.data.arr_string.arr[i].len != rhs.data.arr_string.arr[i].len)
|
||||
return false;
|
||||
if (std::memcmp(lhs.data.arr_string.arr[i].str,
|
||||
rhs.data.arr_string.arr[i].str,
|
||||
lhs.data.arr_string.arr[i].len) != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
//assert(false && "unknown value type");
|
||||
return false;
|
||||
}
|
||||
// assert(false && "unknown value type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,8 @@
|
||||
|
||||
struct NT_Value;
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {} // namespace ntimpl
|
||||
|
||||
} // namespace NtImpl
|
||||
bool operator==(const NT_Value& lhs, const NT_Value& rhs);
|
||||
|
||||
bool operator== (const NT_Value& lhs, const NT_Value& rhs);
|
||||
|
||||
#endif /* NT_VALUE_H_ */
|
||||
#endif // NT_VALUE_H_
|
||||
|
||||
@@ -15,196 +15,191 @@
|
||||
#include "nt_internal.h"
|
||||
#include "nt_leb128.h"
|
||||
|
||||
using namespace NtImpl;
|
||||
using namespace ntimpl;
|
||||
|
||||
static double
|
||||
read_double(char*& buf)
|
||||
{
|
||||
std::uint64_t val = (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; val <<= 8; val |= (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; val <<= 8; val |= (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; val <<= 8; val |= (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; val <<= 8; val |= (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; val <<= 8; val |= (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; val <<= 8; val |= (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; val <<= 8; val |= (*((unsigned char *)buf)) & 0xff;
|
||||
++buf;
|
||||
return *reinterpret_cast<double*>(&val);
|
||||
static double read_double(char*& buf) {
|
||||
std::uint64_t val = (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
val <<= 8;
|
||||
val |= (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
val <<= 8;
|
||||
val |= (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
val <<= 8;
|
||||
val |= (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
val <<= 8;
|
||||
val |= (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
val <<= 8;
|
||||
val |= (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
val <<= 8;
|
||||
val |= (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
val <<= 8;
|
||||
val |= (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
return *reinterpret_cast<double*>(&val);
|
||||
}
|
||||
|
||||
WireDecoder::WireDecoder(raw_istream& is, unsigned int proto_rev)
|
||||
: m_is(is)
|
||||
{
|
||||
m_allocated = 1024;
|
||||
m_buf = (char*)std::malloc(m_allocated);
|
||||
m_proto_rev = proto_rev;
|
||||
m_error = nullptr;
|
||||
WireDecoder::WireDecoder(raw_istream& is, unsigned int proto_rev) : m_is(is) {
|
||||
m_allocated = 1024;
|
||||
m_buf = (char*)std::malloc(m_allocated);
|
||||
m_proto_rev = proto_rev;
|
||||
m_error = nullptr;
|
||||
}
|
||||
|
||||
WireDecoder::~WireDecoder()
|
||||
{
|
||||
std::free(m_buf);
|
||||
WireDecoder::~WireDecoder() { std::free(m_buf); }
|
||||
|
||||
bool WireDecoder::ReadDouble(double* val) {
|
||||
char* buf;
|
||||
if (!Read(&buf, 8)) return false;
|
||||
*val = read_double(buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WireDecoder::ReadDouble(double* val)
|
||||
{
|
||||
char* buf;
|
||||
if (!Read(&buf, 8)) return false;
|
||||
*val = read_double(buf);
|
||||
return true;
|
||||
void WireDecoder::Realloc(std::size_t len) {
|
||||
if (m_allocated >= len) return;
|
||||
std::size_t newlen = m_allocated * 2;
|
||||
while (newlen < len) newlen *= 2;
|
||||
m_buf = (char*)std::realloc(m_buf, newlen);
|
||||
m_allocated = newlen;
|
||||
}
|
||||
|
||||
void
|
||||
WireDecoder::Realloc(std::size_t len)
|
||||
{
|
||||
if (m_allocated >= len)
|
||||
return;
|
||||
std::size_t newlen = m_allocated * 2;
|
||||
while (newlen < len)
|
||||
newlen *= 2;
|
||||
m_buf = (char *)std::realloc(m_buf, newlen);
|
||||
m_allocated = newlen;
|
||||
}
|
||||
|
||||
bool
|
||||
WireDecoder::ReadType(NT_Type* type)
|
||||
{
|
||||
unsigned int itype;
|
||||
if (!Read8(&itype)) return false;
|
||||
switch (itype)
|
||||
{
|
||||
case 0x00: *type = NT_BOOLEAN; break;
|
||||
case 0x01: *type = NT_DOUBLE; break;
|
||||
case 0x02: *type = NT_STRING; break;
|
||||
case 0x03: *type = NT_RAW; break;
|
||||
case 0x10: *type = NT_BOOLEAN_ARRAY; break;
|
||||
case 0x11: *type = NT_DOUBLE_ARRAY; break;
|
||||
case 0x12: *type = NT_STRING_ARRAY; break;
|
||||
case 0x20: *type = NT_RPC; break;
|
||||
bool WireDecoder::ReadType(NT_Type* type) {
|
||||
unsigned int itype;
|
||||
if (!Read8(&itype)) return false;
|
||||
switch (itype) {
|
||||
case 0x00:
|
||||
*type = NT_BOOLEAN;
|
||||
break;
|
||||
case 0x01:
|
||||
*type = NT_DOUBLE;
|
||||
break;
|
||||
case 0x02:
|
||||
*type = NT_STRING;
|
||||
break;
|
||||
case 0x03:
|
||||
*type = NT_RAW;
|
||||
break;
|
||||
case 0x10:
|
||||
*type = NT_BOOLEAN_ARRAY;
|
||||
break;
|
||||
case 0x11:
|
||||
*type = NT_DOUBLE_ARRAY;
|
||||
break;
|
||||
case 0x12:
|
||||
*type = NT_STRING_ARRAY;
|
||||
break;
|
||||
case 0x20:
|
||||
*type = NT_RPC;
|
||||
break;
|
||||
default:
|
||||
m_error = "unrecognized value type";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
m_error = "unrecognized value type";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WireDecoder::ReadValue(NT_Type type, NT_Value* value)
|
||||
{
|
||||
value->type = type;
|
||||
value->last_change = 0;
|
||||
switch (type)
|
||||
{
|
||||
case NT_BOOLEAN:
|
||||
{
|
||||
unsigned int v;
|
||||
if (!Read8(&v)) return false;
|
||||
value->data.v_boolean = v ? 1 : 0;
|
||||
break;
|
||||
bool WireDecoder::ReadValue(NT_Type type, NT_Value* value) {
|
||||
value->type = type;
|
||||
value->last_change = 0;
|
||||
switch (type) {
|
||||
case NT_BOOLEAN: {
|
||||
unsigned int v;
|
||||
if (!Read8(&v)) return false;
|
||||
value->data.v_boolean = v ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
case NT_DOUBLE:
|
||||
{
|
||||
if (!ReadDouble(&value->data.v_double)) return false;
|
||||
break;
|
||||
case NT_DOUBLE: {
|
||||
if (!ReadDouble(&value->data.v_double)) return false;
|
||||
break;
|
||||
}
|
||||
case NT_STRING:
|
||||
if (!ReadString(&value->data.v_string)) return false;
|
||||
break;
|
||||
if (!ReadString(&value->data.v_string)) return false;
|
||||
break;
|
||||
case NT_RAW:
|
||||
case NT_RPC:
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "received raw or RPC value in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
if (!ReadString(&value->data.v_raw)) return false;
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
{
|
||||
// size
|
||||
unsigned int size;
|
||||
if (!Read8(&size)) return false;
|
||||
value->data.arr_boolean.size = size;
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "received raw or RPC value in protocol < 3.0";
|
||||
return false;
|
||||
}
|
||||
if (!ReadString(&value->data.v_raw)) return false;
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY: {
|
||||
// size
|
||||
unsigned int size;
|
||||
if (!Read8(&size)) return false;
|
||||
value->data.arr_boolean.size = size;
|
||||
|
||||
// array values
|
||||
char* buf;
|
||||
if (!Read(&buf, size)) return false;
|
||||
value->data.arr_boolean.arr = (int*)std::malloc(size * sizeof(int));
|
||||
for (unsigned int i=0; i<size; ++i)
|
||||
value->data.arr_boolean.arr[i] = buf[i] ? 1 : 0;
|
||||
break;
|
||||
// array values
|
||||
char* buf;
|
||||
if (!Read(&buf, size)) return false;
|
||||
value->data.arr_boolean.arr = (int*)std::malloc(size * sizeof(int));
|
||||
for (unsigned int i = 0; i < size; ++i)
|
||||
value->data.arr_boolean.arr[i] = buf[i] ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
case NT_DOUBLE_ARRAY:
|
||||
{
|
||||
// size
|
||||
unsigned int size;
|
||||
if (!Read8(&size)) return false;
|
||||
value->data.arr_double.size = size;
|
||||
case NT_DOUBLE_ARRAY: {
|
||||
// size
|
||||
unsigned int size;
|
||||
if (!Read8(&size)) return false;
|
||||
value->data.arr_double.size = size;
|
||||
|
||||
// array values
|
||||
char* buf;
|
||||
if (!Read(&buf, size*8)) return false;
|
||||
value->data.arr_double.arr =
|
||||
(double*)std::malloc(size * sizeof(double));
|
||||
for (unsigned int i=0; i<size; ++i)
|
||||
value->data.arr_double.arr[i] = read_double(buf);
|
||||
break;
|
||||
// array values
|
||||
char* buf;
|
||||
if (!Read(&buf, size * 8)) return false;
|
||||
value->data.arr_double.arr = (double*)std::malloc(size * sizeof(double));
|
||||
for (unsigned int i = 0; i < size; ++i)
|
||||
value->data.arr_double.arr[i] = read_double(buf);
|
||||
break;
|
||||
}
|
||||
case NT_STRING_ARRAY:
|
||||
{
|
||||
// size
|
||||
unsigned int size;
|
||||
if (!Read8(&size)) return false;
|
||||
value->data.arr_string.size = size;
|
||||
case NT_STRING_ARRAY: {
|
||||
// size
|
||||
unsigned int size;
|
||||
if (!Read8(&size)) return false;
|
||||
value->data.arr_string.size = size;
|
||||
|
||||
// array values
|
||||
value->data.arr_string.arr =
|
||||
(NT_String*)std::malloc(size * sizeof(NT_String));
|
||||
for (unsigned int i=0; i<size; ++i)
|
||||
{
|
||||
if (!ReadString(&value->data.arr_string.arr[i]))
|
||||
{
|
||||
// cleanup to avoid memory leaks
|
||||
for (unsigned int j=0; j<i; ++j)
|
||||
{
|
||||
std::free(value->data.arr_string.arr[j].str);
|
||||
}
|
||||
std::free(value->data.arr_string.arr);
|
||||
return false;
|
||||
}
|
||||
// array values
|
||||
value->data.arr_string.arr =
|
||||
(NT_String*)std::malloc(size * sizeof(NT_String));
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
if (!ReadString(&value->data.arr_string.arr[i])) {
|
||||
// cleanup to avoid memory leaks
|
||||
for (unsigned int j = 0; j < i; ++j) {
|
||||
std::free(value->data.arr_string.arr[j].str);
|
||||
}
|
||||
std::free(value->data.arr_string.arr);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
m_error = "invalid type when trying to read value";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
m_error = "invalid type when trying to read value";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WireDecoder::ReadString(NT_String* str)
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
unsigned int v;
|
||||
if (!Read16(&v)) return false;
|
||||
str->len = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long v;
|
||||
if (!ReadULEB128(&v)) return false;
|
||||
str->len = v;
|
||||
}
|
||||
str->str = (char*)std::malloc(str->len + 1);
|
||||
if (!m_is.read(str->str, str->len))
|
||||
{
|
||||
std::free(str->str);
|
||||
str->str = 0;
|
||||
return false;
|
||||
}
|
||||
str->str[str->len] = '\0';
|
||||
return true;
|
||||
bool WireDecoder::ReadString(NT_String* str) {
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
unsigned int v;
|
||||
if (!Read16(&v)) return false;
|
||||
str->len = v;
|
||||
} else {
|
||||
unsigned long v;
|
||||
if (!ReadULEB128(&v)) return false;
|
||||
str->len = v;
|
||||
}
|
||||
str->str = (char*)std::malloc(str->len + 1);
|
||||
if (!m_is.read(str->str, str->len)) {
|
||||
std::free(str->str);
|
||||
str->str = 0;
|
||||
return false;
|
||||
}
|
||||
str->str[str->len] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -14,94 +14,84 @@
|
||||
#include "nt_leb128.h"
|
||||
#include "nt_raw_istream.h"
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
class WireDecoder
|
||||
{
|
||||
public:
|
||||
explicit WireDecoder(raw_istream& is, unsigned int proto_rev);
|
||||
~WireDecoder();
|
||||
class WireDecoder {
|
||||
public:
|
||||
explicit WireDecoder(raw_istream& is, unsigned int proto_rev);
|
||||
~WireDecoder();
|
||||
|
||||
void SetProtocolRev(unsigned int proto_rev)
|
||||
{
|
||||
m_proto_rev = proto_rev;
|
||||
}
|
||||
void SetProtocolRev(unsigned int proto_rev) { m_proto_rev = proto_rev; }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_error = nullptr;
|
||||
}
|
||||
void Reset() { m_error = nullptr; }
|
||||
|
||||
const char* GetError() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
const char* GetError() const { return m_error; }
|
||||
|
||||
bool Read(char** buf, std::size_t len)
|
||||
{
|
||||
if (len > m_allocated)
|
||||
Realloc(len);
|
||||
*buf = m_buf;
|
||||
return m_is.read(m_buf, len);
|
||||
}
|
||||
bool Read(char** buf, std::size_t len) {
|
||||
if (len > m_allocated) Realloc(len);
|
||||
*buf = m_buf;
|
||||
return m_is.read(m_buf, len);
|
||||
}
|
||||
|
||||
bool Read8(unsigned int* val)
|
||||
{
|
||||
char* buf;
|
||||
if (!Read(&buf, 1)) return false;
|
||||
*val = (*((unsigned char *)buf)) & 0xff;
|
||||
return true;
|
||||
}
|
||||
bool Read8(unsigned int* val) {
|
||||
char* buf;
|
||||
if (!Read(&buf, 1)) return false;
|
||||
*val = (*((unsigned char*)buf)) & 0xff;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Read16(unsigned int* val)
|
||||
{
|
||||
char* buf;
|
||||
if (!Read(&buf, 2)) return false;
|
||||
unsigned int v = (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; v <<= 8; v |= (*((unsigned char *)buf)) & 0xff;
|
||||
*val = v;
|
||||
return true;
|
||||
}
|
||||
bool Read16(unsigned int* val) {
|
||||
char* buf;
|
||||
if (!Read(&buf, 2)) return false;
|
||||
unsigned int v = (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
v <<= 8;
|
||||
v |= (*((unsigned char*)buf)) & 0xff;
|
||||
*val = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Read32(unsigned long *val)
|
||||
{
|
||||
char* buf;
|
||||
if (!Read(&buf, 4)) return false;
|
||||
unsigned int v = (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; v <<= 8; v |= (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; v <<= 8; v |= (*((unsigned char *)buf)) & 0xff;
|
||||
++buf; v <<= 8; v |= (*((unsigned char *)buf)) & 0xff;
|
||||
*val = v;
|
||||
return true;
|
||||
}
|
||||
bool Read32(unsigned long* val) {
|
||||
char* buf;
|
||||
if (!Read(&buf, 4)) return false;
|
||||
unsigned int v = (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
v <<= 8;
|
||||
v |= (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
v <<= 8;
|
||||
v |= (*((unsigned char*)buf)) & 0xff;
|
||||
++buf;
|
||||
v <<= 8;
|
||||
v |= (*((unsigned char*)buf)) & 0xff;
|
||||
*val = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadDouble(double* val);
|
||||
bool ReadDouble(double* val);
|
||||
|
||||
bool ReadULEB128(unsigned long* val)
|
||||
{
|
||||
return read_uleb128(m_is, val);
|
||||
}
|
||||
bool ReadULEB128(unsigned long* val) { return read_uleb128(m_is, val); }
|
||||
|
||||
bool ReadType(NT_Type* type);
|
||||
bool ReadValue(NT_Type type, NT_Value* value);
|
||||
bool ReadString(NT_String* str);
|
||||
bool ReadType(NT_Type* type);
|
||||
bool ReadValue(NT_Type type, NT_Value* value);
|
||||
bool ReadString(NT_String* str);
|
||||
|
||||
WireDecoder(const WireDecoder&) = delete;
|
||||
WireDecoder& operator= (const WireDecoder&) = delete;
|
||||
WireDecoder(const WireDecoder&) = delete;
|
||||
WireDecoder& operator=(const WireDecoder&) = delete;
|
||||
|
||||
protected:
|
||||
unsigned int m_proto_rev;
|
||||
const char* m_error;
|
||||
protected:
|
||||
unsigned int m_proto_rev;
|
||||
const char* m_error;
|
||||
|
||||
private:
|
||||
void Realloc(std::size_t len);
|
||||
private:
|
||||
void Realloc(std::size_t len);
|
||||
|
||||
raw_istream& m_is;
|
||||
raw_istream& m_is;
|
||||
|
||||
char* m_buf;
|
||||
std::size_t m_allocated;
|
||||
char* m_buf;
|
||||
std::size_t m_allocated;
|
||||
};
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_WIREDECODER_H_ */
|
||||
#endif // NT_WIREDECODER_H_
|
||||
|
||||
@@ -15,214 +15,186 @@
|
||||
#include "nt_internal.h"
|
||||
#include "nt_leb128.h"
|
||||
|
||||
using namespace NtImpl;
|
||||
using namespace ntimpl;
|
||||
|
||||
WireEncoder::WireEncoder(unsigned int proto_rev)
|
||||
{
|
||||
m_start = m_cur = (char *)std::malloc(1024);
|
||||
m_end = m_start + 1024;
|
||||
m_proto_rev = proto_rev;
|
||||
m_error = nullptr;
|
||||
WireEncoder::WireEncoder(unsigned int proto_rev) {
|
||||
m_start = m_cur = (char*)std::malloc(1024);
|
||||
m_end = m_start + 1024;
|
||||
m_proto_rev = proto_rev;
|
||||
m_error = nullptr;
|
||||
}
|
||||
|
||||
WireEncoder::~WireEncoder()
|
||||
{
|
||||
std::free(m_start);
|
||||
WireEncoder::~WireEncoder() { std::free(m_start); }
|
||||
|
||||
void WireEncoder::WriteDouble(double val) {
|
||||
Reserve(8);
|
||||
std::uint64_t v = *reinterpret_cast<uint64_t*>(&val);
|
||||
*m_cur++ = (char)((v >> 56) & 0xff);
|
||||
*m_cur++ = (char)((v >> 48) & 0xff);
|
||||
*m_cur++ = (char)((v >> 40) & 0xff);
|
||||
*m_cur++ = (char)((v >> 32) & 0xff);
|
||||
*m_cur++ = (char)((v >> 24) & 0xff);
|
||||
*m_cur++ = (char)((v >> 16) & 0xff);
|
||||
*m_cur++ = (char)((v >> 8) & 0xff);
|
||||
*m_cur++ = (char)(v & 0xff);
|
||||
}
|
||||
|
||||
void
|
||||
WireEncoder::WriteDouble(double val)
|
||||
{
|
||||
Reserve(8);
|
||||
std::uint64_t v = *reinterpret_cast<uint64_t*>(&val);
|
||||
*m_cur++ = (char)((v >> 56) & 0xff);
|
||||
*m_cur++ = (char)((v >> 48) & 0xff);
|
||||
*m_cur++ = (char)((v >> 40) & 0xff);
|
||||
*m_cur++ = (char)((v >> 32) & 0xff);
|
||||
*m_cur++ = (char)((v >> 24) & 0xff);
|
||||
*m_cur++ = (char)((v >> 16) & 0xff);
|
||||
*m_cur++ = (char)((v >> 8) & 0xff);
|
||||
*m_cur++ = (char)(v & 0xff);
|
||||
void WireEncoder::ReserveSlow(std::size_t len) {
|
||||
assert(m_end > m_cur);
|
||||
if (static_cast<std::size_t>(m_end - m_cur) >= len) return;
|
||||
std::size_t pos = m_cur - m_start;
|
||||
std::size_t newlen = (m_end - m_start) * 2;
|
||||
while (newlen < (pos + len)) newlen *= 2;
|
||||
m_start = (char*)std::realloc(m_start, newlen);
|
||||
m_cur = m_start + pos;
|
||||
m_end = m_start + newlen;
|
||||
}
|
||||
|
||||
void
|
||||
WireEncoder::ReserveSlow(std::size_t len)
|
||||
{
|
||||
assert(m_end > m_cur);
|
||||
if (static_cast<std::size_t>(m_end - m_cur) >= len)
|
||||
return;
|
||||
std::size_t pos = m_cur - m_start;
|
||||
std::size_t newlen = (m_end - m_start) * 2;
|
||||
while (newlen < (pos + len))
|
||||
newlen *= 2;
|
||||
m_start = (char *)std::realloc(m_start, newlen);
|
||||
m_cur = m_start + pos;
|
||||
m_end = m_start + newlen;
|
||||
void WireEncoder::WriteULEB128(unsigned long val) {
|
||||
Reserve(size_uleb128(val));
|
||||
m_cur += write_uleb128(m_cur, val);
|
||||
}
|
||||
|
||||
void
|
||||
WireEncoder::WriteULEB128(unsigned long val)
|
||||
{
|
||||
Reserve(size_uleb128(val));
|
||||
m_cur += write_uleb128(m_cur, val);
|
||||
}
|
||||
|
||||
void
|
||||
WireEncoder::WriteType(NT_Type type)
|
||||
{
|
||||
Reserve(1);
|
||||
switch (type)
|
||||
{
|
||||
case NT_BOOLEAN: *m_cur = 0x00; break;
|
||||
case NT_DOUBLE: *m_cur = 0x01; break;
|
||||
case NT_STRING: *m_cur = 0x02; break;
|
||||
case NT_RAW:
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "raw type not supported in protocol < 3.0";
|
||||
return;
|
||||
}
|
||||
*m_cur = 0x03;
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY: *m_cur = 0x10; break;
|
||||
case NT_DOUBLE_ARRAY: *m_cur = 0x11; break;
|
||||
case NT_STRING_ARRAY: *m_cur = 0x12; break;
|
||||
case NT_RPC:
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "RPC type not supported in protocol < 3.0";
|
||||
return;
|
||||
}
|
||||
*m_cur = 0x20;
|
||||
break;
|
||||
default:
|
||||
m_error = "unrecognized type";
|
||||
return;
|
||||
}
|
||||
++m_cur;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
WireEncoder::GetValueSize(const NT_Value& value)
|
||||
{
|
||||
switch (value.type)
|
||||
{
|
||||
void WireEncoder::WriteType(NT_Type type) {
|
||||
Reserve(1);
|
||||
switch (type) {
|
||||
case NT_BOOLEAN:
|
||||
return 1;
|
||||
*m_cur = 0x00;
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
return 8;
|
||||
*m_cur = 0x01;
|
||||
break;
|
||||
case NT_STRING:
|
||||
return GetStringSize(value.data.v_string);
|
||||
*m_cur = 0x02;
|
||||
break;
|
||||
case NT_RAW:
|
||||
case NT_RPC:
|
||||
if (m_proto_rev < 0x0300u)
|
||||
return 0;
|
||||
return GetStringSize(value.data.v_raw);
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
return 1 + value.data.arr_boolean.size;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
return 1 + value.data.arr_double.size * 8;
|
||||
case NT_STRING_ARRAY:
|
||||
{
|
||||
size_t len = 1;
|
||||
for (size_t i=0; i<value.data.arr_string.size; ++i)
|
||||
len += GetStringSize(value.data.arr_string.arr[i]);
|
||||
return len;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WireEncoder::WriteValue(const NT_Value& value)
|
||||
{
|
||||
switch (value.type)
|
||||
{
|
||||
case NT_BOOLEAN:
|
||||
Write8(value.data.v_boolean ? 1 : 0);
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
WriteDouble(value.data.v_double);
|
||||
break;
|
||||
case NT_STRING:
|
||||
WriteString(value.data.v_string);
|
||||
break;
|
||||
case NT_RAW:
|
||||
case NT_RPC:
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
m_error = "raw and rpc values not supported in protocol < 3.0";
|
||||
return;
|
||||
}
|
||||
WriteString(value.data.v_raw);
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
{
|
||||
std::size_t size = value.data.arr_boolean.size;
|
||||
if (size > 0xff)
|
||||
size = 0xff;
|
||||
Reserve(1+size);
|
||||
Write8(size);
|
||||
|
||||
for (std::size_t i=0; i<size; ++i)
|
||||
Write8(value.data.arr_boolean.arr[i] ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case NT_DOUBLE_ARRAY:
|
||||
{
|
||||
std::size_t size = value.data.arr_double.size;
|
||||
if (size > 0xff)
|
||||
size = 0xff;
|
||||
Reserve(1+size*8);
|
||||
Write8(size);
|
||||
|
||||
for (std::size_t i=0; i<size; ++i)
|
||||
WriteDouble(value.data.arr_double.arr[i] ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case NT_STRING_ARRAY:
|
||||
{
|
||||
std::size_t size = value.data.arr_string.size;
|
||||
if (size > 0xff)
|
||||
size = 0xff;
|
||||
Write8(size);
|
||||
|
||||
for (std::size_t i=0; i<size; ++i)
|
||||
WriteString(value.data.arr_string.arr[i]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
m_error = "unrecognized type when writing value";
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "raw type not supported in protocol < 3.0";
|
||||
return;
|
||||
}
|
||||
*m_cur = 0x03;
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
*m_cur = 0x10;
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
*m_cur = 0x11;
|
||||
break;
|
||||
case NT_STRING_ARRAY:
|
||||
*m_cur = 0x12;
|
||||
break;
|
||||
case NT_RPC:
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "RPC type not supported in protocol < 3.0";
|
||||
return;
|
||||
}
|
||||
*m_cur = 0x20;
|
||||
break;
|
||||
default:
|
||||
m_error = "unrecognized type";
|
||||
return;
|
||||
}
|
||||
++m_cur;
|
||||
}
|
||||
|
||||
std::size_t WireEncoder::GetValueSize(const NT_Value& value) {
|
||||
switch (value.type) {
|
||||
case NT_BOOLEAN:
|
||||
return 1;
|
||||
case NT_DOUBLE:
|
||||
return 8;
|
||||
case NT_STRING:
|
||||
return GetStringSize(value.data.v_string);
|
||||
case NT_RAW:
|
||||
case NT_RPC:
|
||||
if (m_proto_rev < 0x0300u) return 0;
|
||||
return GetStringSize(value.data.v_raw);
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
return 1 + value.data.arr_boolean.size;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
return 1 + value.data.arr_double.size * 8;
|
||||
case NT_STRING_ARRAY: {
|
||||
size_t len = 1;
|
||||
for (size_t i = 0; i < value.data.arr_string.size; ++i)
|
||||
len += GetStringSize(value.data.arr_string.arr[i]);
|
||||
return len;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t
|
||||
WireEncoder::GetStringSize(const NT_String& str)
|
||||
{
|
||||
if (m_proto_rev < 0x0300u)
|
||||
return 2 + str.len;
|
||||
return size_uleb128(str.len) + str.len;
|
||||
}
|
||||
void WireEncoder::WriteValue(const NT_Value& value) {
|
||||
switch (value.type) {
|
||||
case NT_BOOLEAN:
|
||||
Write8(value.data.v_boolean ? 1 : 0);
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
WriteDouble(value.data.v_double);
|
||||
break;
|
||||
case NT_STRING:
|
||||
WriteString(value.data.v_string);
|
||||
break;
|
||||
case NT_RAW:
|
||||
case NT_RPC:
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
m_error = "raw and rpc values not supported in protocol < 3.0";
|
||||
return;
|
||||
}
|
||||
WriteString(value.data.v_raw);
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY: {
|
||||
std::size_t size = value.data.arr_boolean.size;
|
||||
if (size > 0xff) size = 0xff;
|
||||
Reserve(1 + size);
|
||||
Write8(size);
|
||||
|
||||
void
|
||||
WireEncoder::WriteString(const NT_String& str)
|
||||
{
|
||||
// length
|
||||
std::size_t len = str.len;
|
||||
if (m_proto_rev < 0x0300u)
|
||||
{
|
||||
// Limited to 64K length; truncate if necessary
|
||||
if (len > 0xffff)
|
||||
len = 0xffff;
|
||||
Write16(len);
|
||||
for (std::size_t i = 0; i < size; ++i)
|
||||
Write8(value.data.arr_boolean.arr[i] ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
else
|
||||
WriteULEB128(len);
|
||||
case NT_DOUBLE_ARRAY: {
|
||||
std::size_t size = value.data.arr_double.size;
|
||||
if (size > 0xff) size = 0xff;
|
||||
Reserve(1 + size * 8);
|
||||
Write8(size);
|
||||
|
||||
// contents
|
||||
Reserve(len);
|
||||
std::memcpy(m_cur, str.str, len);
|
||||
m_cur += len;
|
||||
for (std::size_t i = 0; i < size; ++i)
|
||||
WriteDouble(value.data.arr_double.arr[i] ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case NT_STRING_ARRAY: {
|
||||
std::size_t size = value.data.arr_string.size;
|
||||
if (size > 0xff) size = 0xff;
|
||||
Write8(size);
|
||||
|
||||
for (std::size_t i = 0; i < size; ++i)
|
||||
WriteString(value.data.arr_string.arr[i]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
m_error = "unrecognized type when writing value";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t WireEncoder::GetStringSize(const NT_String& str) {
|
||||
if (m_proto_rev < 0x0300u) return 2 + str.len;
|
||||
return size_uleb128(str.len) + str.len;
|
||||
}
|
||||
|
||||
void WireEncoder::WriteString(const NT_String& str) {
|
||||
// length
|
||||
std::size_t len = str.len;
|
||||
if (m_proto_rev < 0x0300u) {
|
||||
// Limited to 64K length; truncate if necessary
|
||||
if (len > 0xffff) len = 0xffff;
|
||||
Write16(len);
|
||||
} else
|
||||
WriteULEB128(len);
|
||||
|
||||
// contents
|
||||
Reserve(len);
|
||||
std::memcpy(m_cur, str.str, len);
|
||||
m_cur += len;
|
||||
}
|
||||
|
||||
@@ -13,94 +13,75 @@
|
||||
|
||||
#include "ntcore.h"
|
||||
|
||||
namespace NtImpl {
|
||||
namespace ntimpl {
|
||||
|
||||
class WireEncoder
|
||||
{
|
||||
public:
|
||||
explicit WireEncoder(unsigned int proto_rev);
|
||||
~WireEncoder();
|
||||
class WireEncoder {
|
||||
public:
|
||||
explicit WireEncoder(unsigned int proto_rev);
|
||||
~WireEncoder();
|
||||
|
||||
void SetProtocolRev(unsigned int proto_rev)
|
||||
{
|
||||
m_proto_rev = proto_rev;
|
||||
}
|
||||
void SetProtocolRev(unsigned int proto_rev) { m_proto_rev = proto_rev; }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_cur = m_start;
|
||||
m_error = nullptr;
|
||||
}
|
||||
void Reset() {
|
||||
m_cur = m_start;
|
||||
m_error = nullptr;
|
||||
}
|
||||
|
||||
const char* GetError() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
const char* GetError() const { return m_error; }
|
||||
|
||||
const char* GetData() const
|
||||
{
|
||||
return m_start;
|
||||
}
|
||||
const char* GetData() const { return m_start; }
|
||||
|
||||
std::size_t GetSize() const
|
||||
{
|
||||
return m_cur - m_start;
|
||||
}
|
||||
std::size_t GetSize() const { return m_cur - m_start; }
|
||||
|
||||
void Reserve(std::size_t len)
|
||||
{
|
||||
//assert(m_end > m_cur);
|
||||
if (static_cast<size_t>(m_end - m_cur) < len)
|
||||
ReserveSlow(len);
|
||||
}
|
||||
void Reserve(std::size_t len) {
|
||||
// assert(m_end > m_cur);
|
||||
if (static_cast<size_t>(m_end - m_cur) < len) ReserveSlow(len);
|
||||
}
|
||||
|
||||
void Write8(unsigned int val)
|
||||
{
|
||||
Reserve(1);
|
||||
*m_cur++ = (char)(val & 0xff);
|
||||
}
|
||||
void Write8(unsigned int val) {
|
||||
Reserve(1);
|
||||
*m_cur++ = (char)(val & 0xff);
|
||||
}
|
||||
|
||||
void Write16(unsigned int val)
|
||||
{
|
||||
Reserve(2);
|
||||
*m_cur++ = (char)((val >> 8) & 0xff);
|
||||
*m_cur++ = (char)(val & 0xff);
|
||||
}
|
||||
void Write16(unsigned int val) {
|
||||
Reserve(2);
|
||||
*m_cur++ = (char)((val >> 8) & 0xff);
|
||||
*m_cur++ = (char)(val & 0xff);
|
||||
}
|
||||
|
||||
void Write32(unsigned long val)
|
||||
{
|
||||
Reserve(4);
|
||||
*m_cur++ = (char)((val >> 24) & 0xff);
|
||||
*m_cur++ = (char)((val >> 16) & 0xff);
|
||||
*m_cur++ = (char)((val >> 8) & 0xff);
|
||||
*m_cur++ = (char)(val & 0xff);
|
||||
}
|
||||
void Write32(unsigned long val) {
|
||||
Reserve(4);
|
||||
*m_cur++ = (char)((val >> 24) & 0xff);
|
||||
*m_cur++ = (char)((val >> 16) & 0xff);
|
||||
*m_cur++ = (char)((val >> 8) & 0xff);
|
||||
*m_cur++ = (char)(val & 0xff);
|
||||
}
|
||||
|
||||
void WriteDouble(double val);
|
||||
void WriteDouble(double val);
|
||||
|
||||
void WriteULEB128(unsigned long val);
|
||||
void WriteType(NT_Type type);
|
||||
void WriteValue(const NT_Value& value);
|
||||
void WriteString(const NT_String& str);
|
||||
void WriteULEB128(unsigned long val);
|
||||
void WriteType(NT_Type type);
|
||||
void WriteValue(const NT_Value& value);
|
||||
void WriteString(const NT_String& str);
|
||||
|
||||
std::size_t GetValueSize(const NT_Value& value);
|
||||
std::size_t GetStringSize(const NT_String& str);
|
||||
std::size_t GetValueSize(const NT_Value& value);
|
||||
std::size_t GetStringSize(const NT_String& str);
|
||||
|
||||
WireEncoder(const WireEncoder&) = delete;
|
||||
WireEncoder& operator= (const WireEncoder&) = delete;
|
||||
WireEncoder(const WireEncoder&) = delete;
|
||||
WireEncoder& operator=(const WireEncoder&) = delete;
|
||||
|
||||
protected:
|
||||
unsigned int m_proto_rev;
|
||||
const char* m_error;
|
||||
protected:
|
||||
unsigned int m_proto_rev;
|
||||
const char* m_error;
|
||||
|
||||
private:
|
||||
void ReserveSlow(std::size_t len);
|
||||
private:
|
||||
void ReserveSlow(std::size_t len);
|
||||
|
||||
char* m_start;
|
||||
char* m_cur;
|
||||
char* m_end;
|
||||
char* m_start;
|
||||
char* m_cur;
|
||||
char* m_end;
|
||||
};
|
||||
|
||||
} // namespace NtImpl
|
||||
} // namespace ntimpl
|
||||
|
||||
#endif /* NT_WIREENCODER_H_ */
|
||||
#endif // NT_WIREENCODER_H_
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
// - see < http://opensource.org/licenses/BSD-2-Clause>
|
||||
//
|
||||
|
||||
#ifndef CONCURRENT_QUEUE_
|
||||
#define CONCURRENT_QUEUE_
|
||||
#ifndef NT_SUPPORT_CONCURRENT_QUEUE_H_
|
||||
#define NT_SUPPORT_CONCURRENT_QUEUE_H_
|
||||
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
@@ -13,56 +13,49 @@
|
||||
#include <condition_variable>
|
||||
|
||||
template <typename T>
|
||||
class ConcurrentQueue
|
||||
{
|
||||
public:
|
||||
T pop()
|
||||
{
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
while (queue_.empty())
|
||||
{
|
||||
cond_.wait(mlock);
|
||||
}
|
||||
auto item = std::move(queue_.front());
|
||||
queue_.pop();
|
||||
return item;
|
||||
class ConcurrentQueue {
|
||||
public:
|
||||
T pop() {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
while (queue_.empty()) {
|
||||
cond_.wait(mlock);
|
||||
}
|
||||
auto item = std::move(queue_.front());
|
||||
queue_.pop();
|
||||
return item;
|
||||
}
|
||||
|
||||
void pop(T& item)
|
||||
{
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
while (queue_.empty())
|
||||
{
|
||||
cond_.wait(mlock);
|
||||
}
|
||||
item = queue_.front();
|
||||
queue_.pop();
|
||||
void pop(T& item) {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
while (queue_.empty()) {
|
||||
cond_.wait(mlock);
|
||||
}
|
||||
item = queue_.front();
|
||||
queue_.pop();
|
||||
}
|
||||
|
||||
void push(const T& item)
|
||||
{
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
queue_.push(item);
|
||||
mlock.unlock();
|
||||
cond_.notify_one();
|
||||
}
|
||||
void push(const T& item) {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
queue_.push(item);
|
||||
mlock.unlock();
|
||||
cond_.notify_one();
|
||||
}
|
||||
|
||||
void push(T&& item)
|
||||
{
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
queue_.push(std::move(item));
|
||||
mlock.unlock();
|
||||
cond_.notify_one();
|
||||
}
|
||||
void push(T&& item) {
|
||||
std::unique_lock<std::mutex> mlock(mutex_);
|
||||
queue_.push(std::move(item));
|
||||
mlock.unlock();
|
||||
cond_.notify_one();
|
||||
}
|
||||
|
||||
ConcurrentQueue() = default;
|
||||
ConcurrentQueue(const ConcurrentQueue&) = delete;
|
||||
ConcurrentQueue& operator=(const ConcurrentQueue&) = delete;
|
||||
|
||||
private:
|
||||
std::queue<T> queue_;
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cond_;
|
||||
ConcurrentQueue() = default;
|
||||
ConcurrentQueue(const ConcurrentQueue&) = delete;
|
||||
ConcurrentQueue& operator=(const ConcurrentQueue&) = delete;
|
||||
|
||||
private:
|
||||
std::queue<T> queue_;
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cond_;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // NT_SUPPORT_CONCURRENT_QUEUE_H_
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#include "timestamp.h"
|
||||
|
||||
#include <cassert>
|
||||
@@ -10,82 +16,74 @@
|
||||
#endif
|
||||
|
||||
// offset in microseconds
|
||||
static unsigned long long
|
||||
zerotime()
|
||||
{
|
||||
static unsigned long long zerotime() {
|
||||
#ifdef _WIN32
|
||||
FILETIME ft;
|
||||
unsigned long long tmpres = 0;
|
||||
// 100-nanosecond intervals since January 1, 1601 (UTC)
|
||||
// which means 0.1 us
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
tmpres |= ft.dwHighDateTime;
|
||||
tmpres <<= 32;
|
||||
tmpres |= ft.dwLowDateTime;
|
||||
// January 1st, 1970 - January 1st, 1601 UTC ~ 369 years
|
||||
// or 116444736000000000 us
|
||||
static const unsigned long long deltaepoch = 116444736000000000ull;
|
||||
tmpres -= deltaepoch;
|
||||
return tmpres;
|
||||
FILETIME ft;
|
||||
unsigned long long tmpres = 0;
|
||||
// 100-nanosecond intervals since January 1, 1601 (UTC)
|
||||
// which means 0.1 us
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
tmpres |= ft.dwHighDateTime;
|
||||
tmpres <<= 32;
|
||||
tmpres |= ft.dwLowDateTime;
|
||||
// January 1st, 1970 - January 1st, 1601 UTC ~ 369 years
|
||||
// or 116444736000000000 us
|
||||
static const unsigned long long deltaepoch = 116444736000000000ull;
|
||||
tmpres -= deltaepoch;
|
||||
return tmpres;
|
||||
#else
|
||||
timespec ts;
|
||||
timespec ts;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
|
||||
// in 100-ns intervals
|
||||
return static_cast<unsigned long long>(ts.tv_sec) * 10000000ull +
|
||||
static_cast<unsigned long long>(ts.tv_nsec) / 100u;
|
||||
// in 100-ns intervals
|
||||
return static_cast<unsigned long long>(ts.tv_sec) * 10000000ull +
|
||||
static_cast<unsigned long long>(ts.tv_nsec) / 100u;
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned long long
|
||||
timestamp()
|
||||
{
|
||||
static unsigned long long timestamp() {
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER li;
|
||||
QueryPerformanceCounter(&li);
|
||||
// there is an imprecision with the initial value,
|
||||
// but what matters is that timestamps are monotonic and consistent
|
||||
return static_cast<unsigned long long>(li.QuadPart);
|
||||
LARGE_INTEGER li;
|
||||
QueryPerformanceCounter(&li);
|
||||
// there is an imprecision with the initial value,
|
||||
// but what matters is that timestamps are monotonic and consistent
|
||||
return static_cast<unsigned long long>(li.QuadPart);
|
||||
#else
|
||||
timespec ts;
|
||||
timespec ts;
|
||||
|
||||
// cannot fail, parameters are correct and we checked earlier we can
|
||||
// access the clock
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
// in ns
|
||||
return static_cast<unsigned long long>(ts.tv_sec) * 1000000000ull +
|
||||
static_cast<unsigned long long>(ts.tv_nsec);
|
||||
// cannot fail, parameters are correct and we checked earlier we can
|
||||
// access the clock
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
// in ns
|
||||
return static_cast<unsigned long long>(ts.tv_sec) * 1000000000ull +
|
||||
static_cast<unsigned long long>(ts.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned long long
|
||||
update_frequency()
|
||||
{
|
||||
static unsigned long long update_frequency() {
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER li;
|
||||
if (!QueryPerformanceFrequency(&li) || !li.QuadPart)
|
||||
{
|
||||
// log something
|
||||
std::terminate();
|
||||
}
|
||||
return static_cast<unsigned long long>(li.QuadPart);
|
||||
LARGE_INTEGER li;
|
||||
if (!QueryPerformanceFrequency(&li) || !li.QuadPart) {
|
||||
// log something
|
||||
std::terminate();
|
||||
}
|
||||
return static_cast<unsigned long long>(li.QuadPart);
|
||||
#else
|
||||
timespec ts;
|
||||
timespec ts;
|
||||
|
||||
if (clock_getres(CLOCK_MONOTONIC, &ts) < 0)
|
||||
{
|
||||
// log error
|
||||
std::terminate();
|
||||
}
|
||||
if (clock_getres(CLOCK_MONOTONIC, &ts) < 0) {
|
||||
// log error
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
assert(!ts.tv_sec);
|
||||
assert(!ts.tv_sec);
|
||||
|
||||
// this is the precision of the clock, we want the number of updates per
|
||||
// second, which is 1 / ts.tv_nsec * 1,000,000,000
|
||||
static const unsigned long long billion = 1000000000ull;
|
||||
// this is the precision of the clock, we want the number of updates per
|
||||
// second, which is 1 / ts.tv_nsec * 1,000,000,000
|
||||
static const unsigned long long billion = 1000000000ull;
|
||||
|
||||
return billion / static_cast<unsigned long long>(ts.tv_nsec);
|
||||
return billion / static_cast<unsigned long long>(ts.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -93,14 +91,12 @@ static const unsigned long long zerotime_val = zerotime();
|
||||
static const unsigned long long offset_val = timestamp();
|
||||
static const unsigned long long frequency_val = update_frequency();
|
||||
|
||||
unsigned long long
|
||||
NT_Now()
|
||||
{
|
||||
assert(offset_val > 0u);
|
||||
assert(frequency_val > 0u);
|
||||
unsigned long long delta = timestamp() - offset_val;
|
||||
// because the frequency is in update per seconds, we have to multiply the
|
||||
// delta by 10,000,000
|
||||
unsigned long long delta_in_us = delta * 10000000ull / frequency_val;
|
||||
return delta_in_us + zerotime_val;
|
||||
unsigned long long NT_Now() {
|
||||
assert(offset_val > 0u);
|
||||
assert(frequency_val > 0u);
|
||||
unsigned long long delta = timestamp() - offset_val;
|
||||
// because the frequency is in update per seconds, we have to multiply the
|
||||
// delta by 10,000,000
|
||||
unsigned long long delta_in_us = delta * 10000000ull / frequency_val;
|
||||
return delta_in_us + zerotime_val;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
#ifndef TIMESTAMP_H_
|
||||
#define TIMESTAMP_H_
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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_SUPPORT_TIMESTAMP_H_
|
||||
#define NT_SUPPORT_TIMESTAMP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
unsigned long long NT_Now(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TIMESTAMP_H_ */
|
||||
#endif // NT_SUPPORT_TIMESTAMP_H_
|
||||
|
||||
Reference in New Issue
Block a user