Add braces to C++ single-line loops and conditionals (NFC) (#2973)

This makes code easier to read and more consistent between C++ and Java.
Also update clang-format settings to always add a line break (even if no braces are used).
This commit is contained in:
Peter Johnson
2020-12-28 12:58:06 -08:00
committed by GitHub
parent 0291a3ff56
commit 2aed432b4b
634 changed files with 10716 additions and 3938 deletions

View File

@@ -57,7 +57,9 @@ class CallbackThread : public wpi::SafeThread {
~CallbackThread() {
// Wake up any blocked pollers
for (size_t i = 0; i < m_pollers.size(); ++i) {
if (auto poller = m_pollers[i]) poller->Terminate();
if (auto poller = m_pollers[i]) {
poller->Terminate();
}
}
}
@@ -87,9 +89,13 @@ class CallbackThread : public wpi::SafeThread {
// Must be called with m_mutex held
template <typename... Args>
void SendPoller(unsigned int poller_uid, Args&&... args) {
if (poller_uid > m_pollers.size()) return;
if (poller_uid > m_pollers.size()) {
return;
}
auto poller = m_pollers[poller_uid];
if (!poller) return;
if (!poller) {
return;
}
{
std::scoped_lock lock(poller->poll_mutex);
poller->poll_queue.emplace(std::forward<Args>(args)...);
@@ -105,11 +111,15 @@ void CallbackThread<Derived, TUserInfo, TListenerData, TNotifierData>::Main() {
while (m_active) {
while (m_queue.empty()) {
m_cond.wait(lock);
if (!m_active) return;
if (!m_active) {
return;
}
}
while (!m_queue.empty()) {
if (!m_active) return;
if (!m_active) {
return;
}
auto item = std::move(m_queue.front());
if (item.first != UINT_MAX) {
@@ -132,9 +142,12 @@ void CallbackThread<Derived, TUserInfo, TListenerData, TNotifierData>::Main() {
// Use index because iterator might get invalidated.
for (size_t i = 0; i < m_listeners.size(); ++i) {
auto& listener = m_listeners[i];
if (!listener) continue;
if (!static_cast<Derived*>(this)->Matches(listener, item.second))
if (!listener) {
continue;
}
if (!static_cast<Derived*>(this)->Matches(listener, item.second)) {
continue;
}
static_cast<Derived*>(this)->SetListener(&item.second,
static_cast<unsigned>(i));
if (listener.callback) {
@@ -171,7 +184,9 @@ class CallbackManager {
void Remove(unsigned int listener_uid) {
auto thr = m_owner.GetThread();
if (!thr) return;
if (!thr) {
return;
}
thr->m_listeners.erase(listener_uid);
}
@@ -184,37 +199,52 @@ class CallbackManager {
void RemovePoller(unsigned int poller_uid) {
auto thr = m_owner.GetThread();
if (!thr) return;
if (!thr) {
return;
}
// Remove any listeners that are associated with this poller
for (size_t i = 0; i < thr->m_listeners.size(); ++i) {
if (thr->m_listeners[i].poller_uid == poller_uid)
if (thr->m_listeners[i].poller_uid == poller_uid) {
thr->m_listeners.erase(i);
}
}
// Wake up any blocked pollers
if (poller_uid >= thr->m_pollers.size()) return;
if (poller_uid >= thr->m_pollers.size()) {
return;
}
auto poller = thr->m_pollers[poller_uid];
if (!poller) return;
if (!poller) {
return;
}
poller->Terminate();
return thr->m_pollers.erase(poller_uid);
}
bool WaitForQueue(double timeout) {
auto thr = m_owner.GetThread();
if (!thr) return true;
if (!thr) {
return true;
}
auto& lock = thr.GetLock();
auto timeout_time = std::chrono::steady_clock::now() +
std::chrono::duration<double>(timeout);
while (!thr->m_queue.empty()) {
if (!thr->m_active) return true;
if (timeout == 0) return false;
if (!thr->m_active) {
return true;
}
if (timeout == 0) {
return false;
}
if (timeout < 0) {
thr->m_queue_empty.wait(lock);
} else {
auto cond_timed_out = thr->m_queue_empty.wait_until(lock, timeout_time);
if (cond_timed_out == std::cv_status::timeout) return false;
if (cond_timed_out == std::cv_status::timeout) {
return false;
}
}
}
@@ -232,10 +262,16 @@ class CallbackManager {
std::shared_ptr<typename Thread::Poller> poller;
{
auto thr = m_owner.GetThread();
if (!thr) return infos;
if (poller_uid > thr->m_pollers.size()) return infos;
if (!thr) {
return infos;
}
if (poller_uid > thr->m_pollers.size()) {
return infos;
}
poller = thr->m_pollers[poller_uid];
if (!poller) return infos;
if (!poller) {
return infos;
}
}
std::unique_lock lock(poller->poll_mutex);
@@ -243,7 +279,9 @@ class CallbackManager {
std::chrono::duration<double>(timeout);
*timed_out = false;
while (poller->poll_queue.empty()) {
if (poller->terminating) return infos;
if (poller->terminating) {
return infos;
}
if (poller->canceling) {
// Note: this only works if there's a single thread calling this
// function for any particular poller, but that's the intended use.
@@ -276,10 +314,16 @@ class CallbackManager {
std::shared_ptr<typename Thread::Poller> poller;
{
auto thr = m_owner.GetThread();
if (!thr) return;
if (poller_uid > thr->m_pollers.size()) return;
if (!thr) {
return;
}
if (poller_uid > thr->m_pollers.size()) {
return;
}
poller = thr->m_pollers[poller_uid];
if (!poller) return;
if (!poller) {
return;
}
}
{
@@ -305,7 +349,9 @@ class CallbackManager {
template <typename... Args>
void Send(unsigned int only_listener, Args&&... args) {
auto thr = m_owner.GetThread();
if (!thr || thr->m_listeners.empty()) return;
if (!thr || thr->m_listeners.empty()) {
return;
}
thr->m_queue.emplace(std::piecewise_construct,
std::make_tuple(only_listener),
std::forward_as_tuple(std::forward<Args>(args)...));

View File

@@ -8,7 +8,9 @@ using namespace nt;
ConnectionNotifier::ConnectionNotifier(int inst) : m_inst(inst) {}
void ConnectionNotifier::Start() { DoStart(m_inst); }
void ConnectionNotifier::Start() {
DoStart(m_inst);
}
unsigned int ConnectionNotifier::Add(
std::function<void(const ConnectionNotification& event)> callback) {

View File

@@ -38,14 +38,16 @@ void Dispatcher::SetServer(const char* server_name, unsigned int port) {
void Dispatcher::SetServer(
ArrayRef<std::pair<StringRef, unsigned int>> servers) {
wpi::SmallVector<std::pair<std::string, int>, 16> servers_copy;
for (const auto& server : servers)
for (const auto& server : servers) {
servers_copy.emplace_back(std::string{server.first.trim()},
static_cast<int>(server.second));
}
SetConnector([=]() -> std::unique_ptr<wpi::NetworkStream> {
wpi::SmallVector<std::pair<const char*, int>, 16> servers_copy2;
for (const auto& server : servers_copy)
for (const auto& server : servers_copy) {
servers_copy2.emplace_back(server.first.c_str(), server.second);
}
return wpi::TCPConnector::connect_parallel(servers_copy2, m_logger, 1);
});
}
@@ -100,7 +102,9 @@ void Dispatcher::SetServerOverride(const char* server_name, unsigned int port) {
});
}
void Dispatcher::ClearServerOverride() { ClearConnectorOverride(); }
void Dispatcher::ClearServerOverride() {
ClearConnectorOverride();
}
DispatcherBase::DispatcherBase(IStorage& storage, IConnectionNotifier& notifier,
wpi::Logger& logger)
@@ -109,14 +113,20 @@ DispatcherBase::DispatcherBase(IStorage& storage, IConnectionNotifier& notifier,
m_update_rate = 100;
}
DispatcherBase::~DispatcherBase() { Stop(); }
DispatcherBase::~DispatcherBase() {
Stop();
}
unsigned int DispatcherBase::GetNetworkMode() const { return m_networkMode; }
unsigned int DispatcherBase::GetNetworkMode() const {
return m_networkMode;
}
void DispatcherBase::StartLocal() {
{
std::scoped_lock lock(m_user_mutex);
if (m_active) return;
if (m_active) {
return;
}
m_active = true;
}
m_networkMode = NT_NET_MODE_LOCAL;
@@ -128,7 +138,9 @@ void DispatcherBase::StartServer(
std::unique_ptr<wpi::NetworkAcceptor> acceptor) {
{
std::scoped_lock lock(m_user_mutex);
if (m_active) return;
if (m_active) {
return;
}
m_active = true;
}
m_networkMode = NT_NET_MODE_SERVER | NT_NET_MODE_STARTING;
@@ -160,7 +172,9 @@ void DispatcherBase::StartServer(
void DispatcherBase::StartClient() {
{
std::scoped_lock lock(m_user_mutex);
if (m_active) return;
if (m_active) {
return;
}
m_active = true;
}
m_networkMode = NT_NET_MODE_CLIENT | NT_NET_MODE_STARTING;
@@ -184,11 +198,17 @@ void DispatcherBase::Stop() {
ClientReconnect();
// wake up server thread by shutting down the socket
if (m_server_acceptor) m_server_acceptor->shutdown();
if (m_server_acceptor) {
m_server_acceptor->shutdown();
}
// join threads, with timeout
if (m_dispatch_thread.joinable()) m_dispatch_thread.join();
if (m_clientserver_thread.joinable()) m_clientserver_thread.join();
if (m_dispatch_thread.joinable()) {
m_dispatch_thread.join();
}
if (m_clientserver_thread.joinable()) {
m_clientserver_thread.join();
}
std::vector<std::shared_ptr<INetworkConnection>> conns;
{
@@ -202,10 +222,11 @@ void DispatcherBase::Stop() {
void DispatcherBase::SetUpdateRate(double interval) {
// don't allow update rates faster than 5 ms or slower than 1 second
if (interval < 0.005)
if (interval < 0.005) {
interval = 0.005;
else if (interval > 1.0)
} else if (interval > 1.0) {
interval = 1.0;
}
m_update_rate = static_cast<unsigned int>(interval * 1000);
}
@@ -219,7 +240,9 @@ void DispatcherBase::Flush() {
{
std::scoped_lock lock(m_flush_mutex);
// don't allow flushes more often than every 5 ms
if ((now - m_last_flush) < 5000) return;
if ((now - m_last_flush) < 5000) {
return;
}
m_last_flush = now;
m_do_flush = true;
}
@@ -228,11 +251,15 @@ void DispatcherBase::Flush() {
std::vector<ConnectionInfo> DispatcherBase::GetConnections() const {
std::vector<ConnectionInfo> conns;
if (!m_active) return conns;
if (!m_active) {
return conns;
}
std::scoped_lock lock(m_user_mutex);
for (auto& conn : m_connections) {
if (conn->state() != NetworkConnection::kActive) continue;
if (conn->state() != NetworkConnection::kActive) {
continue;
}
conns.emplace_back(conn->info());
}
@@ -240,13 +267,19 @@ std::vector<ConnectionInfo> DispatcherBase::GetConnections() const {
}
bool DispatcherBase::IsConnected() const {
if (!m_active) return false;
if (!m_active) {
return false;
}
if (m_networkMode == NT_NET_MODE_LOCAL) return true;
if (m_networkMode == NT_NET_MODE_LOCAL) {
return true;
}
std::scoped_lock lock(m_user_mutex);
for (auto& conn : m_connections) {
if (conn->state() == NetworkConnection::kActive) return true;
if (conn->state() == NetworkConnection::kActive) {
return true;
}
}
return false;
@@ -260,7 +293,9 @@ unsigned int DispatcherBase::AddListener(
// perform immediate notifications
if (immediate_notify) {
for (auto& conn : m_connections) {
if (conn->state() != NetworkConnection::kActive) continue;
if (conn->state() != NetworkConnection::kActive) {
continue;
}
m_notifier.NotifyConnection(true, conn->info(), uid);
}
}
@@ -274,7 +309,9 @@ unsigned int DispatcherBase::AddPolledListener(unsigned int poller_uid,
// perform immediate notifications
if (immediate_notify) {
for (auto& conn : m_connections) {
if (conn->state() != NetworkConnection::kActive) continue;
if (conn->state() != NetworkConnection::kActive) {
continue;
}
m_notifier.NotifyConnection(true, conn->info(), uid);
}
}
@@ -307,7 +344,9 @@ void DispatcherBase::DispatchThreadMain() {
while (m_active) {
// handle loop taking too long
auto start = std::chrono::steady_clock::now();
if (start > timeout_time) timeout_time = start;
if (start > timeout_time) {
timeout_time = start;
}
// wait for periodic or when flushed
timeout_time += std::chrono::milliseconds(m_update_rate);
@@ -316,16 +355,22 @@ void DispatcherBase::DispatchThreadMain() {
[&] { return !m_active || m_do_flush; });
m_do_flush = false;
flush_lock.unlock();
if (!m_active) break; // in case we were woken up to terminate
if (!m_active) {
break; // in case we were woken up to terminate
}
// perform periodic persistent save
if ((m_networkMode & NT_NET_MODE_SERVER) != 0 &&
!m_persist_filename.empty() && start > next_save_time) {
next_save_time += save_delta_time;
// handle loop taking too long
if (start > next_save_time) next_save_time = start + save_delta_time;
if (start > next_save_time) {
next_save_time = start + save_delta_time;
}
const char* err = m_storage.SavePersistent(m_persist_filename, true);
if (err) WARNING("periodic persistent save: " << err);
if (err) {
WARNING("periodic persistent save: " << err);
}
}
{
@@ -340,13 +385,15 @@ void DispatcherBase::DispatchThreadMain() {
for (auto& conn : m_connections) {
// post outgoing messages if connection is active
// only send keep-alives on client
if (conn->state() == NetworkConnection::kActive)
if (conn->state() == NetworkConnection::kActive) {
conn->PostOutgoing((m_networkMode & NT_NET_MODE_CLIENT) != 0);
}
// if client, reconnect if connection died
if ((m_networkMode & NT_NET_MODE_CLIENT) != 0 &&
conn->state() == NetworkConnection::kDead)
conn->state() == NetworkConnection::kDead) {
reconnect = true;
}
}
// reconnect if we disconnected (and a reconnect is not in progress)
if (reconnect && !m_do_reconnect) {
@@ -362,12 +409,17 @@ void DispatcherBase::QueueOutgoing(std::shared_ptr<Message> msg,
INetworkConnection* except) {
std::scoped_lock user_lock(m_user_mutex);
for (auto& conn : m_connections) {
if (conn.get() == except) continue;
if (only && conn.get() != only) continue;
if (conn.get() == except) {
continue;
}
if (only && conn.get() != only) {
continue;
}
auto state = conn->state();
if (state != NetworkConnection::kSynchronized &&
state != NetworkConnection::kActive)
state != NetworkConnection::kActive) {
continue;
}
conn->QueueOutgoing(msg);
}
}
@@ -412,7 +464,9 @@ void DispatcherBase::ServerThreadMain() {
break;
}
}
if (!placed) m_connections.emplace_back(conn);
if (!placed) {
m_connections.emplace_back(conn);
}
conn->Start();
}
}
@@ -496,16 +550,22 @@ bool DispatcherBase::ClientHandshake(
}
if (msg->Is(Message::kProtoUnsup)) {
if (msg->id() == 0x0200) ClientReconnect(0x0200);
if (msg->id() == 0x0200) {
ClientReconnect(0x0200);
}
return false;
}
bool new_server = true;
if (conn.proto_rev() >= 0x0300) {
// should be server hello; if not, disconnect.
if (!msg->Is(Message::kServerHello)) return false;
if (!msg->Is(Message::kServerHello)) {
return false;
}
conn.set_remote_id(msg->str());
if ((msg->flags() & 1) != 0) new_server = false;
if ((msg->flags() & 1) != 0) {
new_server = false;
}
// get the next message
msg = get_msg();
}
@@ -520,7 +580,9 @@ bool DispatcherBase::ClientHandshake(
}
DEBUG4("received init str=" << msg->str() << " id=" << msg->id()
<< " seq_num=" << msg->seq_num_uid());
if (msg->Is(Message::kServerHelloDone)) break;
if (msg->Is(Message::kServerHelloDone)) {
break;
}
// shouldn't receive a keep alive, but handle gracefully
if (msg->Is(Message::kKeepAlive)) {
msg = get_msg();
@@ -543,10 +605,13 @@ bool DispatcherBase::ClientHandshake(
m_storage.ApplyInitialAssignments(conn, incoming, new_server, &outgoing);
if (conn.proto_rev() >= 0x0300)
if (conn.proto_rev() >= 0x0300) {
outgoing.emplace_back(Message::ClientHelloDone());
}
if (!outgoing.empty()) send_msgs(outgoing);
if (!outgoing.empty()) {
send_msgs(outgoing);
}
INFO("client: CONNECTED to server " << conn.stream().getPeerIP() << " port "
<< conn.stream().getPeerPort());
@@ -575,7 +640,9 @@ bool DispatcherBase::ServerHandshake(
return false;
}
if (proto_rev >= 0x0300) conn.set_remote_id(msg->str());
if (proto_rev >= 0x0300) {
conn.set_remote_id(msg->str());
}
// Set the proto version to the client requested version
DEBUG0("server: client protocol " << proto_rev);
@@ -614,7 +681,9 @@ bool DispatcherBase::ServerHandshake(
DEBUG0("server: disconnected waiting for initial entries");
return false;
}
if (msg->Is(Message::kClientHelloDone)) break;
if (msg->Is(Message::kClientHelloDone)) {
break;
}
// shouldn't receive a keep alive, but handle gracefully
if (msg->Is(Message::kKeepAlive)) {
msg = get_msg();
@@ -631,8 +700,9 @@ bool DispatcherBase::ServerHandshake(
// get the next message (blocks)
msg = get_msg();
}
for (auto& msg : incoming)
for (auto& msg : incoming) {
m_storage.ProcessIncoming(msg, &conn, std::weak_ptr<NetworkConnection>());
}
}
INFO("server: client CONNECTED: " << conn.stream().getPeerIP() << " port "
@@ -641,7 +711,9 @@ bool DispatcherBase::ServerHandshake(
}
void DispatcherBase::ClientReconnect(unsigned int proto_rev) {
if ((m_networkMode & NT_NET_MODE_SERVER) != 0) return;
if ((m_networkMode & NT_NET_MODE_SERVER) != 0) {
return;
}
{
std::scoped_lock lock(m_user_mutex);
m_reconnect_proto_rev = proto_rev;

View File

@@ -32,10 +32,11 @@ DsClient::DsClient(Dispatcher& dispatcher, wpi::Logger& logger)
void DsClient::Start(unsigned int port) {
auto thr = m_owner.GetThread();
if (!thr)
if (!thr) {
m_owner.Start(m_dispatcher, m_logger, port);
else
} else {
thr->m_port = port;
}
}
void DsClient::Stop() {
@@ -44,7 +45,9 @@ void DsClient::Stop() {
auto thr = m_owner.GetThread();
if (thr) {
thr->m_active = false;
if (thr->m_stream) thr->m_stream->close();
if (thr->m_stream) {
thr->m_stream->close();
}
}
}
m_owner.Stop();
@@ -64,12 +67,18 @@ void DsClient::Thread::Main() {
m_cond.wait_until(lock, timeout_time, [&] { return !m_active; });
port = m_port;
}
if (!m_active) goto done;
if (!m_active) {
goto done;
}
// Try to connect to DS on the local machine
m_stream = wpi::TCPConnector::connect("127.0.0.1", 1742, nolog, 1);
if (!m_active) goto done;
if (!m_stream) continue;
if (!m_active) {
goto done;
}
if (!m_stream) {
continue;
}
DEBUG3("connected to DS");
wpi::raw_socket_istream is(*m_stream);
@@ -83,8 +92,12 @@ void DsClient::Thread::Main() {
// Throw away characters until {
do {
is.read(ch);
if (is.has_error()) break;
if (!m_active) goto done;
if (is.has_error()) {
break;
}
if (!m_active) {
goto done;
}
} while (ch != '{');
json += '{';
@@ -96,8 +109,12 @@ void DsClient::Thread::Main() {
// Read characters until }
do {
is.read(ch);
if (is.has_error()) break;
if (!m_active) goto done;
if (is.has_error()) {
break;
}
if (!m_active) {
goto done;
}
json += ch;
} while (ch != '}');
@@ -109,16 +126,22 @@ void DsClient::Thread::Main() {
// Look for "robotIP":12345, and get 12345 portion
size_t pos = json.find("\"robotIP\"");
if (pos == wpi::StringRef::npos) continue; // could not find?
if (pos == wpi::StringRef::npos) {
continue; // could not find?
}
pos += 9;
pos = json.find(':', pos);
if (pos == wpi::StringRef::npos) continue; // could not find?
if (pos == wpi::StringRef::npos) {
continue; // could not find?
}
size_t endpos = json.find_first_not_of("0123456789", pos + 1);
DEBUG3("found robotIP=" << json.slice(pos + 1, endpos));
// Parse into number
unsigned int ip = 0;
if (json.slice(pos + 1, endpos).getAsInteger(10, ip)) continue; // error
if (json.slice(pos + 1, endpos).getAsInteger(10, ip)) {
continue; // error
}
// If zero, clear the server override
if (ip == 0) {
@@ -128,7 +151,9 @@ void DsClient::Thread::Main() {
}
// If unchanged, don't reconnect
if (ip == oldip) continue;
if (ip == oldip) {
continue;
}
oldip = ip;
// Convert number into dotted quad

View File

@@ -13,13 +13,19 @@ EntryNotifier::EntryNotifier(int inst, wpi::Logger& logger)
m_local_notifiers = false;
}
void EntryNotifier::Start() { DoStart(m_inst); }
void EntryNotifier::Start() {
DoStart(m_inst);
}
bool EntryNotifier::local_notifiers() const { return m_local_notifiers; }
bool EntryNotifier::local_notifiers() const {
return m_local_notifiers;
}
bool impl::EntryNotifierThread::Matches(const EntryListenerData& listener,
const EntryNotification& data) {
if (!data.value) return false;
if (!data.value) {
return false;
}
// Flags must be within requested flag set for this listener.
// Because assign messages can result in both a value and flags update,
@@ -29,17 +35,24 @@ bool impl::EntryNotifierThread::Matches(const EntryListenerData& listener,
unsigned int flags = data.flags & ~(NT_NOTIFY_IMMEDIATE | NT_NOTIFY_LOCAL);
unsigned int assign_both = NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS;
if ((flags & assign_both) == assign_both) {
if ((listen_flags & assign_both) == 0) return false;
if ((listen_flags & assign_both) == 0) {
return false;
}
listen_flags &= ~assign_both;
flags &= ~assign_both;
}
if ((flags & ~listen_flags) != 0) return false;
if ((flags & ~listen_flags) != 0) {
return false;
}
// must match local id or prefix
if (listener.entry != 0 && data.entry != listener.entry) return false;
if (listener.entry == 0 &&
!wpi::StringRef(data.name).startswith(listener.prefix))
if (listener.entry != 0 && data.entry != listener.entry) {
return false;
}
if (listener.entry == 0 &&
!wpi::StringRef(data.name).startswith(listener.prefix)) {
return false;
}
return true;
}
@@ -47,28 +60,36 @@ bool impl::EntryNotifierThread::Matches(const EntryListenerData& listener,
unsigned int EntryNotifier::Add(
std::function<void(const EntryNotification& event)> callback,
StringRef prefix, unsigned int flags) {
if ((flags & NT_NOTIFY_LOCAL) != 0) m_local_notifiers = true;
if ((flags & NT_NOTIFY_LOCAL) != 0) {
m_local_notifiers = true;
}
return DoAdd(callback, prefix, flags);
}
unsigned int EntryNotifier::Add(
std::function<void(const EntryNotification& event)> callback,
unsigned int local_id, unsigned int flags) {
if ((flags & NT_NOTIFY_LOCAL) != 0) m_local_notifiers = true;
if ((flags & NT_NOTIFY_LOCAL) != 0) {
m_local_notifiers = true;
}
return DoAdd(callback, Handle(m_inst, local_id, Handle::kEntry), flags);
}
unsigned int EntryNotifier::AddPolled(unsigned int poller_uid,
wpi::StringRef prefix,
unsigned int flags) {
if ((flags & NT_NOTIFY_LOCAL) != 0) m_local_notifiers = true;
if ((flags & NT_NOTIFY_LOCAL) != 0) {
m_local_notifiers = true;
}
return DoAdd(poller_uid, prefix, flags);
}
unsigned int EntryNotifier::AddPolled(unsigned int poller_uid,
unsigned int local_id,
unsigned int flags) {
if ((flags & NT_NOTIFY_LOCAL) != 0) m_local_notifiers = true;
if ((flags & NT_NOTIFY_LOCAL) != 0) {
m_local_notifiers = true;
}
return DoAdd(poller_uid, Handle(m_inst, local_id, Handle::kEntry), flags);
}
@@ -78,7 +99,9 @@ void EntryNotifier::NotifyEntry(unsigned int local_id, StringRef name,
unsigned int only_listener) {
// optimization: don't generate needless local queue entries if we have
// no local listeners (as this is a common case on the server side)
if ((flags & NT_NOTIFY_LOCAL) != 0 && !m_local_notifiers) return;
if ((flags & NT_NOTIFY_LOCAL) != 0 && !m_local_notifiers) {
return;
}
DEBUG0("notifying '" << name << "' (local=" << local_id
<< "), flags=" << flags);
Send(only_listener, 0, Handle(m_inst, local_id, Handle::kEntry).handle(),

View File

@@ -25,18 +25,26 @@ InstanceImpl::InstanceImpl(int inst)
logger.set_min_level(logger_impl.GetMinLevel());
}
InstanceImpl::~InstanceImpl() { logger.SetLogger(nullptr); }
InstanceImpl::~InstanceImpl() {
logger.SetLogger(nullptr);
}
InstanceImpl* InstanceImpl::GetDefault() { return Get(GetDefaultIndex()); }
InstanceImpl* InstanceImpl::GetDefault() {
return Get(GetDefaultIndex());
}
InstanceImpl* InstanceImpl::Get(int inst) {
if (inst < 0) return nullptr;
if (inst < 0) {
return nullptr;
}
// fast path, just an atomic read
if (static_cast<unsigned int>(inst) <
(sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {
InstanceImpl* ptr = s_fast_instances[inst];
if (ptr) return ptr;
if (ptr) {
return ptr;
}
}
// slow path
@@ -60,14 +68,18 @@ InstanceImpl* InstanceImpl::Get(int inst) {
int InstanceImpl::GetDefaultIndex() {
int inst = s_default;
if (inst >= 0) return inst;
if (inst >= 0) {
return inst;
}
// slow path
std::scoped_lock lock(s_mutex);
// double-check
inst = s_default;
if (inst >= 0) return inst;
if (inst >= 0) {
return inst;
}
// alloc and save
inst = AllocImpl();
@@ -94,7 +106,9 @@ int InstanceImpl::AllocImpl() {
void InstanceImpl::Destroy(int inst) {
std::scoped_lock lock(s_mutex);
if (inst < 0 || static_cast<unsigned int>(inst) >= s_instances.size()) return;
if (inst < 0 || static_cast<unsigned int>(inst) >= s_instances.size()) {
return;
}
if (static_cast<unsigned int>(inst) <
(sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {

View File

@@ -22,21 +22,24 @@ static void DefaultLogger(unsigned int level, const char* file,
}
wpi::StringRef levelmsg;
if (level >= 50)
if (level >= 50) {
levelmsg = "CRITICAL: ";
else if (level >= 40)
} else if (level >= 40) {
levelmsg = "ERROR: ";
else if (level >= 30)
} else if (level >= 30) {
levelmsg = "WARNING: ";
else
} else {
return;
}
oss << "NT: " << levelmsg << msg << " (" << file << ':' << line << ")\n";
wpi::errs() << oss.str();
}
LoggerImpl::LoggerImpl(int inst) : m_inst(inst) {}
void LoggerImpl::Start() { DoStart(m_inst); }
void LoggerImpl::Start() {
DoStart(m_inst);
}
unsigned int LoggerImpl::Add(
std::function<void(const LogMessage& msg)> callback, unsigned int min_level,
@@ -52,11 +55,15 @@ unsigned int LoggerImpl::AddPolled(unsigned int poller_uid,
unsigned int LoggerImpl::GetMinLevel() {
auto thr = GetThread();
if (!thr) return NT_LOG_INFO;
if (!thr) {
return NT_LOG_INFO;
}
unsigned int level = NT_LOG_INFO;
for (size_t i = 0; i < thr->m_listeners.size(); ++i) {
const auto& listener = thr->m_listeners[i];
if (listener && listener.min_level < level) level = listener.min_level;
if (listener && listener.min_level < level) {
level = listener.min_level;
}
}
return level;
}
@@ -67,8 +74,9 @@ void LoggerImpl::Log(unsigned int level, const char* file, unsigned int line,
const char* filename = wpi::sys::path::filename(file).data();
{
auto thr = GetThread();
if (!thr || thr->m_listeners.empty())
if (!thr || thr->m_listeners.empty()) {
DefaultLogger(level, filename, line, msg);
}
}
Send(UINT_MAX, 0, level, filename, line, msg);
}

View File

@@ -17,7 +17,9 @@ using namespace nt;
std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
GetEntryTypeFunc get_entry_type) {
unsigned int msg_type = 0;
if (!decoder.Read8(&msg_type)) return nullptr;
if (!decoder.Read8(&msg_type)) {
return nullptr;
}
auto msg =
std::make_shared<Message>(static_cast<MsgType>(msg_type), private_init());
switch (msg_type) {
@@ -25,17 +27,23 @@ std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
break;
case kClientHello: {
unsigned int proto_rev;
if (!decoder.Read16(&proto_rev)) return nullptr;
if (!decoder.Read16(&proto_rev)) {
return nullptr;
}
msg->m_id = proto_rev;
// This intentionally uses the provided proto_rev instead of
// decoder.proto_rev().
if (proto_rev >= 0x0300u) {
if (!decoder.ReadString(&msg->m_str)) return nullptr;
if (!decoder.ReadString(&msg->m_str)) {
return nullptr;
}
}
break;
}
case kProtoUnsup: {
if (!decoder.Read16(&msg->m_id)) return nullptr; // proto rev
if (!decoder.Read16(&msg->m_id)) {
return nullptr; // proto rev
}
break;
}
case kServerHelloDone:
@@ -45,8 +53,12 @@ std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
decoder.set_error("received SERVER_HELLO in protocol < 3.0");
return nullptr;
}
if (!decoder.Read8(&msg->m_flags)) return nullptr;
if (!decoder.ReadString(&msg->m_str)) return nullptr;
if (!decoder.Read8(&msg->m_flags)) {
return nullptr;
}
if (!decoder.ReadString(&msg->m_str)) {
return nullptr;
}
break;
case kClientHelloDone:
if (decoder.proto_rev() < 0x0300u) {
@@ -55,30 +67,50 @@ std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
}
break;
case kEntryAssign: {
if (!decoder.ReadString(&msg->m_str)) return nullptr; // name
if (!decoder.ReadString(&msg->m_str)) {
return nullptr; // name
}
NT_Type type;
if (!decoder.ReadType(&type)) return nullptr; // entry type
if (!decoder.Read16(&msg->m_id)) return nullptr; // id
if (!decoder.Read16(&msg->m_seq_num_uid)) return nullptr; // seq num
if (!decoder.ReadType(&type)) {
return nullptr; // entry type
}
if (!decoder.Read16(&msg->m_id)) {
return nullptr; // id
}
if (!decoder.Read16(&msg->m_seq_num_uid)) {
return nullptr; // seq num
}
if (decoder.proto_rev() >= 0x0300u) {
if (!decoder.Read8(&msg->m_flags)) return nullptr; // flags
if (!decoder.Read8(&msg->m_flags)) {
return nullptr; // flags
}
}
msg->m_value = decoder.ReadValue(type);
if (!msg->m_value) return nullptr;
if (!msg->m_value) {
return nullptr;
}
break;
}
case kEntryUpdate: {
if (!decoder.Read16(&msg->m_id)) return nullptr; // id
if (!decoder.Read16(&msg->m_seq_num_uid)) return nullptr; // seq num
if (!decoder.Read16(&msg->m_id)) {
return nullptr; // id
}
if (!decoder.Read16(&msg->m_seq_num_uid)) {
return nullptr; // seq num
}
NT_Type type;
if (decoder.proto_rev() >= 0x0300u) {
if (!decoder.ReadType(&type)) return nullptr;
if (!decoder.ReadType(&type)) {
return nullptr;
}
} else {
type = get_entry_type(msg->m_id);
}
WPI_DEBUG4(decoder.logger(), "update message data type: " << type);
msg->m_value = decoder.ReadValue(type);
if (!msg->m_value) return nullptr;
if (!msg->m_value) {
return nullptr;
}
break;
}
case kFlagsUpdate: {
@@ -86,8 +118,12 @@ std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
decoder.set_error("received FLAGS_UPDATE in protocol < 3.0");
return nullptr;
}
if (!decoder.Read16(&msg->m_id)) return nullptr;
if (!decoder.Read8(&msg->m_flags)) return nullptr;
if (!decoder.Read16(&msg->m_id)) {
return nullptr;
}
if (!decoder.Read8(&msg->m_flags)) {
return nullptr;
}
break;
}
case kEntryDelete: {
@@ -95,7 +131,9 @@ std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
decoder.set_error("received ENTRY_DELETE in protocol < 3.0");
return nullptr;
}
if (!decoder.Read16(&msg->m_id)) return nullptr;
if (!decoder.Read16(&msg->m_id)) {
return nullptr;
}
break;
}
case kClearEntries: {
@@ -104,7 +142,9 @@ std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
return nullptr;
}
uint32_t magic;
if (!decoder.Read32(&magic)) return nullptr;
if (!decoder.Read32(&magic)) {
return nullptr;
}
if (magic != kClearAllMagic) {
decoder.set_error(
"received incorrect CLEAR_ENTRIES magic value, ignoring");
@@ -117,12 +157,20 @@ std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
decoder.set_error("received EXECUTE_RPC in protocol < 3.0");
return nullptr;
}
if (!decoder.Read16(&msg->m_id)) return nullptr;
if (!decoder.Read16(&msg->m_seq_num_uid)) return nullptr; // uid
if (!decoder.Read16(&msg->m_id)) {
return nullptr;
}
if (!decoder.Read16(&msg->m_seq_num_uid)) {
return nullptr; // uid
}
uint64_t size;
if (!decoder.ReadUleb128(&size)) return nullptr;
if (!decoder.ReadUleb128(&size)) {
return nullptr;
}
const char* params;
if (!decoder.Read(&params, size)) return nullptr;
if (!decoder.Read(&params, size)) {
return nullptr;
}
msg->m_str = wpi::StringRef(params, size);
break;
}
@@ -131,12 +179,20 @@ std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
decoder.set_error("received RPC_RESPONSE in protocol < 3.0");
return nullptr;
}
if (!decoder.Read16(&msg->m_id)) return nullptr;
if (!decoder.Read16(&msg->m_seq_num_uid)) return nullptr; // uid
if (!decoder.Read16(&msg->m_id)) {
return nullptr;
}
if (!decoder.Read16(&msg->m_seq_num_uid)) {
return nullptr; // uid
}
uint64_t size;
if (!decoder.ReadUleb128(&size)) return nullptr;
if (!decoder.ReadUleb128(&size)) {
return nullptr;
}
const char* results;
if (!decoder.Read(&results, size)) return nullptr;
if (!decoder.Read(&results, size)) {
return nullptr;
}
msg->m_str = wpi::StringRef(results, size);
break;
}
@@ -226,7 +282,9 @@ void Message::Write(WireEncoder& encoder) const {
case kClientHello:
encoder.Write8(kClientHello);
encoder.Write16(encoder.proto_rev());
if (encoder.proto_rev() < 0x0300u) return;
if (encoder.proto_rev() < 0x0300u) {
return;
}
encoder.WriteString(m_str);
break;
case kProtoUnsup:
@@ -237,13 +295,17 @@ void Message::Write(WireEncoder& encoder) const {
encoder.Write8(kServerHelloDone);
break;
case kServerHello:
if (encoder.proto_rev() < 0x0300u) return; // new message in version 3.0
if (encoder.proto_rev() < 0x0300u) {
return; // new message in version 3.0
}
encoder.Write8(kServerHello);
encoder.Write8(m_flags);
encoder.WriteString(m_str);
break;
case kClientHelloDone:
if (encoder.proto_rev() < 0x0300u) return; // new message in version 3.0
if (encoder.proto_rev() < 0x0300u) {
return; // new message in version 3.0
}
encoder.Write8(kClientHelloDone);
break;
case kEntryAssign:
@@ -252,41 +314,55 @@ void Message::Write(WireEncoder& encoder) const {
encoder.WriteType(m_value->type());
encoder.Write16(m_id);
encoder.Write16(m_seq_num_uid);
if (encoder.proto_rev() >= 0x0300u) encoder.Write8(m_flags);
if (encoder.proto_rev() >= 0x0300u) {
encoder.Write8(m_flags);
}
encoder.WriteValue(*m_value);
break;
case kEntryUpdate:
encoder.Write8(kEntryUpdate);
encoder.Write16(m_id);
encoder.Write16(m_seq_num_uid);
if (encoder.proto_rev() >= 0x0300u) encoder.WriteType(m_value->type());
if (encoder.proto_rev() >= 0x0300u) {
encoder.WriteType(m_value->type());
}
encoder.WriteValue(*m_value);
break;
case kFlagsUpdate:
if (encoder.proto_rev() < 0x0300u) return; // new message in version 3.0
if (encoder.proto_rev() < 0x0300u) {
return; // new message in version 3.0
}
encoder.Write8(kFlagsUpdate);
encoder.Write16(m_id);
encoder.Write8(m_flags);
break;
case kEntryDelete:
if (encoder.proto_rev() < 0x0300u) return; // new message in version 3.0
if (encoder.proto_rev() < 0x0300u) {
return; // new message in version 3.0
}
encoder.Write8(kEntryDelete);
encoder.Write16(m_id);
break;
case kClearEntries:
if (encoder.proto_rev() < 0x0300u) return; // new message in version 3.0
if (encoder.proto_rev() < 0x0300u) {
return; // new message in version 3.0
}
encoder.Write8(kClearEntries);
encoder.Write32(kClearAllMagic);
break;
case kExecuteRpc:
if (encoder.proto_rev() < 0x0300u) return; // new message in version 3.0
if (encoder.proto_rev() < 0x0300u) {
return; // new message in version 3.0
}
encoder.Write8(kExecuteRpc);
encoder.Write16(m_id);
encoder.Write16(m_seq_num_uid);
encoder.WriteString(m_str);
break;
case kRpcResponse:
if (encoder.proto_rev() < 0x0300u) return; // new message in version 3.0
if (encoder.proto_rev() < 0x0300u) {
return; // new message in version 3.0
}
encoder.Write8(kRpcResponse);
encoder.Write16(m_id);
encoder.Write16(m_seq_num_uid);

View File

@@ -36,14 +36,20 @@ NetworkConnection::NetworkConnection(unsigned int uid,
m_stream->setNoDelay();
}
NetworkConnection::~NetworkConnection() { Stop(); }
NetworkConnection::~NetworkConnection() {
Stop();
}
void NetworkConnection::Start() {
if (m_active) return;
if (m_active) {
return;
}
m_active = true;
set_state(kInit);
// clear queue
while (!m_outgoing.empty()) m_outgoing.pop();
while (!m_outgoing.empty()) {
m_outgoing.pop();
}
// reset shutdown flags
{
std::scoped_lock lock(m_shutdown_mutex);
@@ -60,7 +66,9 @@ void NetworkConnection::Stop() {
set_state(kDead);
m_active = false;
// closing the stream so the read thread terminates
if (m_stream) m_stream->close();
if (m_stream) {
m_stream->close();
}
// send an empty outgoing message set so the write thread terminates
m_outgoing.push(Outgoing());
// wait for threads to terminate, with timeout
@@ -69,23 +77,27 @@ void NetworkConnection::Stop() {
auto timeout_time =
std::chrono::steady_clock::now() + std::chrono::milliseconds(200);
if (m_write_shutdown_cv.wait_until(lock, timeout_time,
[&] { return m_write_shutdown; }))
[&] { return m_write_shutdown; })) {
m_write_thread.join();
else
} else {
m_write_thread.detach(); // timed out, detach it
}
}
if (m_read_thread.joinable()) {
std::unique_lock lock(m_shutdown_mutex);
auto timeout_time =
std::chrono::steady_clock::now() + std::chrono::milliseconds(200);
if (m_read_shutdown_cv.wait_until(lock, timeout_time,
[&] { return m_read_shutdown; }))
[&] { return m_read_shutdown; })) {
m_read_thread.join();
else
} else {
m_read_thread.detach(); // timed out, detach it
}
}
// clear queue
while (!m_outgoing.empty()) m_outgoing.pop();
while (!m_outgoing.empty()) {
m_outgoing.pop();
}
}
ConnectionInfo NetworkConnection::info() const {
@@ -94,7 +106,9 @@ ConnectionInfo NetworkConnection::info() const {
m_last_update, m_proto_rev};
}
unsigned int NetworkConnection::proto_rev() const { return m_proto_rev; }
unsigned int NetworkConnection::proto_rev() const {
return m_proto_rev;
}
void NetworkConnection::set_proto_rev(unsigned int proto_rev) {
m_proto_rev = proto_rev;
@@ -108,12 +122,16 @@ NetworkConnection::State NetworkConnection::state() const {
void NetworkConnection::set_state(State state) {
std::scoped_lock lock(m_state_mutex);
// Don't update state any more once we've died
if (m_state == kDead) return;
if (m_state == kDead) {
return;
}
// One-shot notify state changes
if (m_state != kActive && state == kActive)
if (m_state != kActive && state == kActive) {
m_notifier.NotifyConnection(true, info());
if (m_state != kDead && state == kDead)
}
if (m_state != kDead && state == kDead) {
m_notifier.NotifyConnection(false, info());
}
m_state = state;
}
@@ -137,8 +155,9 @@ void NetworkConnection::ReadThreadMain() {
[&] {
decoder.set_proto_rev(m_proto_rev);
auto msg = Message::Read(decoder, m_get_entry_type);
if (!msg && decoder.error())
if (!msg && decoder.error()) {
DEBUG0("error reading in handshake: " << decoder.error());
}
return msg;
},
[&](wpi::ArrayRef<std::shared_ptr<Message>> msgs) {
@@ -151,14 +170,20 @@ void NetworkConnection::ReadThreadMain() {
set_state(kActive);
while (m_active) {
if (!m_stream) break;
if (!m_stream) {
break;
}
decoder.set_proto_rev(m_proto_rev);
decoder.Reset();
auto msg = Message::Read(decoder, m_get_entry_type);
if (!msg) {
if (decoder.error()) INFO("read error: " << decoder.error());
if (decoder.error()) {
INFO("read error: " << decoder.error());
}
// terminate connection on bad message
if (m_stream) m_stream->close();
if (m_stream) {
m_stream->close();
}
break;
}
DEBUG3("received type=" << msg->type() << " with str=" << msg->str()
@@ -187,7 +212,9 @@ void NetworkConnection::WriteThreadMain() {
while (m_active) {
auto msgs = m_outgoing.pop();
DEBUG4("write thread woke up");
if (msgs.empty()) continue;
if (msgs.empty()) {
continue;
}
encoder.set_proto_rev(m_proto_rev);
encoder.Reset();
DEBUG3("sending " << msgs.size() << " messages");
@@ -200,15 +227,23 @@ void NetworkConnection::WriteThreadMain() {
}
}
wpi::NetworkStream::Error err;
if (!m_stream) break;
if (encoder.size() == 0) continue;
if (m_stream->send(encoder.data(), encoder.size(), &err) == 0) break;
if (!m_stream) {
break;
}
if (encoder.size() == 0) {
continue;
}
if (m_stream->send(encoder.data(), encoder.size(), &err) == 0) {
break;
}
DEBUG4("sent " << encoder.size() << " bytes");
}
DEBUG2("write thread died (" << this << ")");
set_state(kDead);
m_active = false;
if (m_stream) m_stream->close(); // also kill read thread
if (m_stream) {
m_stream->close(); // also kill read thread
}
// use condition variable to signal thread shutdown
{
@@ -246,7 +281,9 @@ void NetworkConnection::QueueOutgoing(std::shared_ptr<Message> msg) {
// new, but remember it
size_t pos = m_pending_outgoing.size();
m_pending_outgoing.push_back(msg);
if (id >= m_pending_update.size()) m_pending_update.resize(id + 1);
if (id >= m_pending_update.size()) {
m_pending_update.resize(id + 1);
}
m_pending_update[id].first = pos + 1;
}
break;
@@ -289,7 +326,9 @@ void NetworkConnection::QueueOutgoing(std::shared_ptr<Message> msg) {
// new, but remember it
size_t pos = m_pending_outgoing.size();
m_pending_outgoing.push_back(msg);
if (id >= m_pending_update.size()) m_pending_update.resize(id + 1);
if (id >= m_pending_update.size()) {
m_pending_update.resize(id + 1);
}
m_pending_update[id].second = pos + 1;
}
break;
@@ -297,12 +336,15 @@ void NetworkConnection::QueueOutgoing(std::shared_ptr<Message> msg) {
case Message::kClearEntries: {
// knock out all previous assigns/updates!
for (auto& i : m_pending_outgoing) {
if (!i) continue;
if (!i) {
continue;
}
auto t = i->type();
if (t == Message::kEntryAssign || t == Message::kEntryUpdate ||
t == Message::kFlagsUpdate || t == Message::kEntryDelete ||
t == Message::kClearEntries)
t == Message::kClearEntries) {
i.reset();
}
}
m_pending_update.resize(0);
m_pending_outgoing.push_back(msg);
@@ -318,9 +360,13 @@ void NetworkConnection::PostOutgoing(bool keep_alive) {
std::scoped_lock lock(m_pending_mutex);
auto now = std::chrono::steady_clock::now();
if (m_pending_outgoing.empty()) {
if (!keep_alive) return;
if (!keep_alive) {
return;
}
// send keep-alives once a second (if no other messages have been sent)
if ((now - m_last_post) < std::chrono::seconds(1)) return;
if ((now - m_last_post) < std::chrono::seconds(1)) {
return;
}
m_outgoing.emplace(Outgoing{Message::KeepAlive()});
} else {
m_outgoing.emplace(std::move(m_pending_outgoing));

View File

@@ -9,7 +9,9 @@ using namespace nt;
RpcServer::RpcServer(int inst, wpi::Logger& logger)
: m_inst(inst), m_logger(logger) {}
void RpcServer::Start() { DoStart(m_inst, m_logger); }
void RpcServer::Start() {
DoStart(m_inst, m_logger);
}
unsigned int RpcServer::Add(
std::function<void(const RpcAnswer& answer)> callback) {
@@ -20,7 +22,9 @@ unsigned int RpcServer::AddPolled(unsigned int poller_uid) {
return DoAdd(poller_uid);
}
void RpcServer::RemoveRpc(unsigned int rpc_uid) { Remove(rpc_uid); }
void RpcServer::RemoveRpc(unsigned int rpc_uid) {
Remove(rpc_uid);
}
void RpcServer::ProcessRpc(unsigned int local_id, unsigned int call_uid,
StringRef name, StringRef params,

View File

@@ -7,21 +7,23 @@
namespace nt {
bool operator<(const SequenceNumber& lhs, const SequenceNumber& rhs) {
if (lhs.m_value < rhs.m_value)
if (lhs.m_value < rhs.m_value) {
return (rhs.m_value - lhs.m_value) < (1u << 15);
else if (lhs.m_value > rhs.m_value)
} else if (lhs.m_value > rhs.m_value) {
return (lhs.m_value - rhs.m_value) > (1u << 15);
else
} else {
return false;
}
}
bool operator>(const SequenceNumber& lhs, const SequenceNumber& rhs) {
if (lhs.m_value < rhs.m_value)
if (lhs.m_value < rhs.m_value) {
return (rhs.m_value - lhs.m_value) > (1u << 15);
else if (lhs.m_value > rhs.m_value)
} else if (lhs.m_value > rhs.m_value) {
return (lhs.m_value - rhs.m_value) < (1u << 15);
else
} else {
return false;
}
}
} // namespace nt

View File

@@ -16,7 +16,9 @@ class SequenceNumber {
SequenceNumber& operator++() {
++m_value;
if (m_value > 0xffff) m_value = 0;
if (m_value > 0xffff) {
m_value = 0;
}
return *this;
}
SequenceNumber operator++(int) {

View File

@@ -32,13 +32,19 @@ void Storage::SetDispatcher(IDispatcher* dispatcher, bool server) {
m_server = server;
}
void Storage::ClearDispatcher() { m_dispatcher = nullptr; }
void Storage::ClearDispatcher() {
m_dispatcher = nullptr;
}
NT_Type Storage::GetMessageEntryType(unsigned int id) const {
std::scoped_lock lock(m_mutex);
if (id >= m_idmap.size()) return NT_UNASSIGNED;
if (id >= m_idmap.size()) {
return NT_UNASSIGNED;
}
Entry* entry = m_idmap[id];
if (!entry || !entry->value) return NT_UNASSIGNED;
if (!entry || !entry->value) {
return NT_UNASSIGNED;
}
return entry->value->type();
}
@@ -96,7 +102,9 @@ void Storage::ProcessIncomingEntryAssign(std::shared_ptr<Message> msg,
if (id == 0xffff) {
entry = GetOrNew(name);
// see if it was already assigned; ignore if so.
if (entry->id != 0xffff) return;
if (entry->id != 0xffff) {
return;
}
entry->flags = msg->flags();
entry->seq_num = seq_num;
@@ -118,7 +126,9 @@ void Storage::ProcessIncomingEntryAssign(std::shared_ptr<Message> msg,
DEBUG0("client: received entry assignment request?");
return;
}
if (id >= m_idmap.size()) m_idmap.resize(id + 1);
if (id >= m_idmap.size()) {
m_idmap.resize(id + 1);
}
entry = m_idmap[id];
if (!entry) {
// create local
@@ -178,15 +188,19 @@ void Storage::ProcessIncomingEntryAssign(std::shared_ptr<Message> msg,
// don't update flags if this is a server response to a client id request
if (!may_need_update && conn->proto_rev() >= 0x0300) {
// update persistent dirty flag if persistent flag changed
if ((entry->flags & NT_PERSISTENT) != (msg->flags() & NT_PERSISTENT))
if ((entry->flags & NT_PERSISTENT) != (msg->flags() & NT_PERSISTENT)) {
m_persistent_dirty = true;
if (entry->flags != msg->flags()) notify_flags |= NT_NOTIFY_FLAGS;
}
if (entry->flags != msg->flags()) {
notify_flags |= NT_NOTIFY_FLAGS;
}
entry->flags = msg->flags();
}
// update persistent dirty flag if the value changed and it's persistent
if (entry->IsPersistent() && *entry->value != *msg->value())
if (entry->IsPersistent() && *entry->value != *msg->value()) {
m_persistent_dirty = true;
}
// update local
entry->value = msg->value();
@@ -221,14 +235,18 @@ void Storage::ProcessIncomingEntryUpdate(std::shared_ptr<Message> msg,
// ignore if sequence number not higher than local
SequenceNumber seq_num(msg->seq_num_uid());
if (seq_num <= entry->seq_num) return;
if (seq_num <= entry->seq_num) {
return;
}
// update local
entry->value = msg->value();
entry->seq_num = seq_num;
// update persistent dirty flag if it's a persistent value
if (entry->IsPersistent()) m_persistent_dirty = true;
if (entry->IsPersistent()) {
m_persistent_dirty = true;
}
// notify
m_notifier.NotifyEntry(entry->local_id, entry->name, entry->value,
@@ -310,7 +328,9 @@ void Storage::ProcessIncomingExecuteRpc(
std::shared_ptr<Message> msg, INetworkConnection* /*conn*/,
std::weak_ptr<INetworkConnection> conn_weak) {
std::unique_lock lock(m_mutex);
if (!m_server) return; // only process on server
if (!m_server) {
return; // only process on server
}
unsigned int id = msg->id();
if (id >= m_idmap.size() || !m_idmap[id]) {
// ignore call to non-existent RPC
@@ -341,7 +361,9 @@ void Storage::ProcessIncomingExecuteRpc(
entry->local_id, call_uid, entry->name, msg->str(), conn_info,
[=](StringRef result) {
auto c = conn_weak.lock();
if (c) c->QueueOutgoing(Message::RpcResponse(id, call_uid, result));
if (c) {
c->QueueOutgoing(Message::RpcResponse(id, call_uid, result));
}
},
entry->rpc_uid);
}
@@ -349,7 +371,9 @@ void Storage::ProcessIncomingExecuteRpc(
void Storage::ProcessIncomingRpcResponse(std::shared_ptr<Message> msg,
INetworkConnection* /*conn*/) {
std::unique_lock lock(m_mutex);
if (m_server) return; // only process on client
if (m_server) {
return; // only process on client
}
unsigned int id = msg->id();
if (id >= m_idmap.size() || !m_idmap[id]) {
// ignore response to non-existent RPC
@@ -375,7 +399,9 @@ void Storage::GetInitialAssignments(
conn.set_state(INetworkConnection::kSynchronized);
for (auto& i : m_entries) {
Entry* entry = i.getValue();
if (!entry->value) continue;
if (!entry->value) {
continue;
}
msgs->emplace_back(Message::EntryAssign(i.getKey(), entry->id,
entry->seq_num.value(),
entry->value, entry->flags));
@@ -386,14 +412,18 @@ void Storage::ApplyInitialAssignments(
INetworkConnection& conn, wpi::ArrayRef<std::shared_ptr<Message>> msgs,
bool /*new_server*/, std::vector<std::shared_ptr<Message>>* out_msgs) {
std::unique_lock lock(m_mutex);
if (m_server) return; // should not do this on server
if (m_server) {
return; // should not do this on server
}
conn.set_state(INetworkConnection::kSynchronized);
std::vector<std::shared_ptr<Message>> update_msgs;
// clear existing id's
for (auto& i : m_entries) i.getValue()->id = 0xffff;
for (auto& i : m_entries) {
i.getValue()->id = 0xffff;
}
// clear existing idmap
m_idmap.resize(0);
@@ -437,7 +467,9 @@ void Storage::ApplyInitialAssignments(
unsigned int notify_flags = NT_NOTIFY_UPDATE;
// don't update flags from a <3.0 remote (not part of message)
if (conn.proto_rev() >= 0x0300) {
if (entry->flags != msg->flags()) notify_flags |= NT_NOTIFY_FLAGS;
if (entry->flags != msg->flags()) {
notify_flags |= NT_NOTIFY_FLAGS;
}
entry->flags = msg->flags();
}
// notify
@@ -447,14 +479,18 @@ void Storage::ApplyInitialAssignments(
}
// save to idmap
if (id >= m_idmap.size()) m_idmap.resize(id + 1);
if (id >= m_idmap.size()) {
m_idmap.resize(id + 1);
}
m_idmap[id] = entry;
}
// delete or generate assign messages for unassigned local entries
DeleteAllEntriesImpl(false, [&](Entry* entry) -> bool {
// was assigned by the server, don't delete
if (entry->id != 0xffff) return false;
if (entry->id != 0xffff) {
return false;
}
// if we have written the value locally, we send an assign message to the
// server instead of deleting
if (entry->local_write) {
@@ -468,32 +504,43 @@ void Storage::ApplyInitialAssignments(
});
auto dispatcher = m_dispatcher;
lock.unlock();
for (auto& msg : update_msgs)
for (auto& msg : update_msgs) {
dispatcher->QueueOutgoing(msg, nullptr, nullptr);
}
}
std::shared_ptr<Value> Storage::GetEntryValue(StringRef name) const {
std::scoped_lock lock(m_mutex);
auto i = m_entries.find(name);
if (i == m_entries.end()) return nullptr;
if (i == m_entries.end()) {
return nullptr;
}
return i->getValue()->value;
}
std::shared_ptr<Value> Storage::GetEntryValue(unsigned int local_id) const {
std::scoped_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return nullptr;
if (local_id >= m_localmap.size()) {
return nullptr;
}
return m_localmap[local_id]->value;
}
bool Storage::SetDefaultEntryValue(StringRef name,
std::shared_ptr<Value> value) {
if (name.empty()) return false;
if (!value) return false;
if (name.empty()) {
return false;
}
if (!value) {
return false;
}
std::unique_lock lock(m_mutex);
Entry* entry = GetOrNew(name);
// we return early if value already exists; if types match return true
if (entry->value) return entry->value->type() == value->type();
if (entry->value) {
return entry->value->type() == value->type();
}
SetEntryValueImpl(entry, value, lock, true);
return true;
@@ -501,26 +548,37 @@ bool Storage::SetDefaultEntryValue(StringRef name,
bool Storage::SetDefaultEntryValue(unsigned int local_id,
std::shared_ptr<Value> value) {
if (!value) return false;
if (!value) {
return false;
}
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return false;
if (local_id >= m_localmap.size()) {
return false;
}
Entry* entry = m_localmap[local_id].get();
// we return early if value already exists; if types match return true
if (entry->value) return entry->value->type() == value->type();
if (entry->value) {
return entry->value->type() == value->type();
}
SetEntryValueImpl(entry, value, lock, true);
return true;
}
bool Storage::SetEntryValue(StringRef name, std::shared_ptr<Value> value) {
if (name.empty()) return true;
if (!value) return true;
if (name.empty()) {
return true;
}
if (!value) {
return true;
}
std::unique_lock lock(m_mutex);
Entry* entry = GetOrNew(name);
if (entry->value && entry->value->type() != value->type())
if (entry->value && entry->value->type() != value->type()) {
return false; // error on type mismatch
}
SetEntryValueImpl(entry, value, lock, true);
return true;
@@ -528,13 +586,18 @@ bool Storage::SetEntryValue(StringRef name, std::shared_ptr<Value> value) {
bool Storage::SetEntryValue(unsigned int local_id,
std::shared_ptr<Value> value) {
if (!value) return true;
if (!value) {
return true;
}
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return true;
if (local_id >= m_localmap.size()) {
return true;
}
Entry* entry = m_localmap[local_id].get();
if (entry->value && entry->value->type() != value->type())
if (entry->value && entry->value->type() != value->type()) {
return false; // error on type mismatch
}
SetEntryValueImpl(entry, value, lock, true);
return true;
@@ -543,7 +606,9 @@ bool Storage::SetEntryValue(unsigned int local_id,
void Storage::SetEntryValueImpl(Entry* entry, std::shared_ptr<Value> value,
std::unique_lock<wpi::mutex>& lock,
bool local) {
if (!value) return;
if (!value) {
return;
}
auto old_value = entry->value;
entry->value = value;
@@ -555,31 +620,41 @@ void Storage::SetEntryValueImpl(Entry* entry, std::shared_ptr<Value> value,
}
// update persistent dirty flag if value changed and it's persistent
if (entry->IsPersistent() && (!old_value || *old_value != *value))
if (entry->IsPersistent() && (!old_value || *old_value != *value)) {
m_persistent_dirty = true;
}
// notify
if (!old_value)
if (!old_value) {
m_notifier.NotifyEntry(entry->local_id, entry->name, value,
NT_NOTIFY_NEW | (local ? NT_NOTIFY_LOCAL : 0));
else if (*old_value != *value)
} else if (*old_value != *value) {
m_notifier.NotifyEntry(entry->local_id, entry->name, value,
NT_NOTIFY_UPDATE | (local ? NT_NOTIFY_LOCAL : 0));
}
// remember local changes
if (local) entry->local_write = true;
if (local) {
entry->local_write = true;
}
// generate message
if (!m_dispatcher || (!local && !m_server)) return;
if (!m_dispatcher || (!local && !m_server)) {
return;
}
auto dispatcher = m_dispatcher;
if (!old_value || old_value->type() != value->type()) {
if (local) ++entry->seq_num;
if (local) {
++entry->seq_num;
}
auto msg = Message::EntryAssign(
entry->name, entry->id, entry->seq_num.value(), value, entry->flags);
lock.unlock();
dispatcher->QueueOutgoing(msg, nullptr, nullptr);
} else if (*old_value != *value) {
if (local) ++entry->seq_num;
if (local) {
++entry->seq_num;
}
// don't send an update if we don't have an assigned id yet
if (entry->id != 0xffff) {
auto msg = Message::EntryUpdate(entry->id, entry->seq_num.value(), value);
@@ -590,8 +665,12 @@ void Storage::SetEntryValueImpl(Entry* entry, std::shared_ptr<Value> value,
}
void Storage::SetEntryTypeValue(StringRef name, std::shared_ptr<Value> value) {
if (name.empty()) return;
if (!value) return;
if (name.empty()) {
return;
}
if (!value) {
return;
}
std::unique_lock lock(m_mutex);
Entry* entry = GetOrNew(name);
@@ -600,37 +679,52 @@ void Storage::SetEntryTypeValue(StringRef name, std::shared_ptr<Value> value) {
void Storage::SetEntryTypeValue(unsigned int local_id,
std::shared_ptr<Value> value) {
if (!value) return;
if (!value) {
return;
}
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return;
if (local_id >= m_localmap.size()) {
return;
}
Entry* entry = m_localmap[local_id].get();
if (!entry) return;
if (!entry) {
return;
}
SetEntryValueImpl(entry, value, lock, true);
}
void Storage::SetEntryFlags(StringRef name, unsigned int flags) {
if (name.empty()) return;
if (name.empty()) {
return;
}
std::unique_lock lock(m_mutex);
auto i = m_entries.find(name);
if (i == m_entries.end()) return;
if (i == m_entries.end()) {
return;
}
SetEntryFlagsImpl(i->getValue(), flags, lock, true);
}
void Storage::SetEntryFlags(unsigned int id_local, unsigned int flags) {
std::unique_lock lock(m_mutex);
if (id_local >= m_localmap.size()) return;
if (id_local >= m_localmap.size()) {
return;
}
SetEntryFlagsImpl(m_localmap[id_local].get(), flags, lock, true);
}
void Storage::SetEntryFlagsImpl(Entry* entry, unsigned int flags,
std::unique_lock<wpi::mutex>& lock,
bool local) {
if (!entry->value || entry->flags == flags) return;
if (!entry->value || entry->flags == flags) {
return;
}
// update persistent dirty flag if persistent flag changed
if ((entry->flags & NT_PERSISTENT) != (flags & NT_PERSISTENT))
if ((entry->flags & NT_PERSISTENT) != (flags & NT_PERSISTENT)) {
m_persistent_dirty = true;
}
entry->flags = flags;
@@ -639,7 +733,9 @@ void Storage::SetEntryFlagsImpl(Entry* entry, unsigned int flags,
NT_NOTIFY_FLAGS | (local ? NT_NOTIFY_LOCAL : 0));
// generate message
if (!local || !m_dispatcher) return;
if (!local || !m_dispatcher) {
return;
}
auto dispatcher = m_dispatcher;
unsigned int id = entry->id;
// don't send an update if we don't have an assigned id yet
@@ -653,26 +749,34 @@ void Storage::SetEntryFlagsImpl(Entry* entry, unsigned int flags,
unsigned int Storage::GetEntryFlags(StringRef name) const {
std::scoped_lock lock(m_mutex);
auto i = m_entries.find(name);
if (i == m_entries.end()) return 0;
if (i == m_entries.end()) {
return 0;
}
return i->getValue()->flags;
}
unsigned int Storage::GetEntryFlags(unsigned int local_id) const {
std::scoped_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return 0;
if (local_id >= m_localmap.size()) {
return 0;
}
return m_localmap[local_id]->flags;
}
void Storage::DeleteEntry(StringRef name) {
std::unique_lock lock(m_mutex);
auto i = m_entries.find(name);
if (i == m_entries.end()) return;
if (i == m_entries.end()) {
return;
}
DeleteEntryImpl(i->getValue(), lock, true);
}
void Storage::DeleteEntry(unsigned int local_id) {
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return;
if (local_id >= m_localmap.size()) {
return;
}
DeleteEntryImpl(m_localmap[local_id].get(), lock, true);
}
@@ -681,7 +785,9 @@ void Storage::DeleteEntryImpl(Entry* entry, std::unique_lock<wpi::mutex>& lock,
unsigned int id = entry->id;
// Erase entry from id mapping.
if (id < m_idmap.size()) m_idmap[id] = nullptr;
if (id < m_idmap.size()) {
m_idmap[id] = nullptr;
}
// empty the value and reset id and local_write flag
std::shared_ptr<Value> old_value;
@@ -696,12 +802,16 @@ void Storage::DeleteEntryImpl(Entry* entry, std::unique_lock<wpi::mutex>& lock,
}
// update persistent dirty flag if it's a persistent value
if (entry->IsPersistent()) m_persistent_dirty = true;
if (entry->IsPersistent()) {
m_persistent_dirty = true;
}
// reset flags
entry->flags = 0;
if (!old_value) return; // was not previously assigned
if (!old_value) {
return; // was not previously assigned
}
// notify
m_notifier.NotifyEntry(entry->local_id, entry->name, old_value,
@@ -710,7 +820,9 @@ void Storage::DeleteEntryImpl(Entry* entry, std::unique_lock<wpi::mutex>& lock,
// if it had a value, generate message
// don't send an update if we don't have an assigned id yet
if (local && id != 0xffff) {
if (!m_dispatcher) return;
if (!m_dispatcher) {
return;
}
auto dispatcher = m_dispatcher;
lock.unlock();
dispatcher->QueueOutgoing(Message::EntryDelete(id), nullptr, nullptr);
@@ -726,7 +838,9 @@ void Storage::DeleteAllEntriesImpl(bool local, F should_delete) {
m_notifier.NotifyEntry(entry->local_id, i.getKey(), entry->value,
NT_NOTIFY_DELETE | (local ? NT_NOTIFY_LOCAL : 0));
// remove it from idmap
if (entry->id < m_idmap.size()) m_idmap[entry->id] = nullptr;
if (entry->id < m_idmap.size()) {
m_idmap[entry->id] = nullptr;
}
entry->id = 0xffff;
entry->local_write = false;
entry->value.reset();
@@ -743,12 +857,16 @@ void Storage::DeleteAllEntriesImpl(bool local) {
void Storage::DeleteAllEntries() {
std::unique_lock lock(m_mutex);
if (m_entries.empty()) return;
if (m_entries.empty()) {
return;
}
DeleteAllEntriesImpl(true);
// generate message
if (!m_dispatcher) return;
if (!m_dispatcher) {
return;
}
auto dispatcher = m_dispatcher;
lock.unlock();
dispatcher->QueueOutgoing(Message::ClearEntries(), nullptr, nullptr);
@@ -768,8 +886,9 @@ Storage::Entry* Storage::GetOrNew(const Twine& name) {
unsigned int Storage::GetEntry(const Twine& name) {
if (name.isTriviallyEmpty() ||
(name.isSingleStringRef() && name.getSingleStringRef().empty()))
(name.isSingleStringRef() && name.getSingleStringRef().empty())) {
return UINT_MAX;
}
std::unique_lock lock(m_mutex);
return GetOrNew(name)->local_id;
}
@@ -783,8 +902,12 @@ std::vector<unsigned int> Storage::GetEntries(const Twine& prefix,
for (auto& i : m_entries) {
Entry* entry = i.getValue();
auto value = entry->value.get();
if (!value || !i.getKey().startswith(prefixStr)) continue;
if (types != 0 && (types & value->type()) == 0) continue;
if (!value || !i.getKey().startswith(prefixStr)) {
continue;
}
if (types != 0 && (types & value->type()) == 0) {
continue;
}
ids.push_back(entry->local_id);
}
return ids;
@@ -798,9 +921,13 @@ EntryInfo Storage::GetEntryInfo(int inst, unsigned int local_id) const {
info.last_change = 0;
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return info;
if (local_id >= m_localmap.size()) {
return info;
}
Entry* entry = m_localmap[local_id].get();
if (!entry->value) return info;
if (!entry->value) {
return info;
}
info.entry = Handle(inst, local_id, Handle::kEntry);
info.name = entry->name;
@@ -812,23 +939,33 @@ EntryInfo Storage::GetEntryInfo(int inst, unsigned int local_id) const {
std::string Storage::GetEntryName(unsigned int local_id) const {
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return std::string{};
if (local_id >= m_localmap.size()) {
return {};
}
return m_localmap[local_id]->name;
}
NT_Type Storage::GetEntryType(unsigned int local_id) const {
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return NT_UNASSIGNED;
if (local_id >= m_localmap.size()) {
return NT_UNASSIGNED;
}
Entry* entry = m_localmap[local_id].get();
if (!entry->value) return NT_UNASSIGNED;
if (!entry->value) {
return NT_UNASSIGNED;
}
return entry->value->type();
}
uint64_t Storage::GetEntryLastChange(unsigned int local_id) const {
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return 0;
if (local_id >= m_localmap.size()) {
return 0;
}
Entry* entry = m_localmap[local_id].get();
if (!entry->value) return 0;
if (!entry->value) {
return 0;
}
return entry->value->last_change();
}
@@ -841,8 +978,12 @@ std::vector<EntryInfo> Storage::GetEntryInfo(int inst, const Twine& prefix,
for (auto& i : m_entries) {
Entry* entry = i.getValue();
auto value = entry->value.get();
if (!value || !i.getKey().startswith(prefixStr)) continue;
if (types != 0 && (types & value->type()) == 0) continue;
if (!value || !i.getKey().startswith(prefixStr)) {
continue;
}
if (types != 0 && (types & value->type()) == 0) {
continue;
}
EntryInfo info;
info.entry = Handle(inst, entry->local_id, Handle::kEntry);
info.name = i.getKey();
@@ -866,7 +1007,9 @@ unsigned int Storage::AddListener(
if ((flags & NT_NOTIFY_IMMEDIATE) != 0 && (flags & NT_NOTIFY_NEW) != 0) {
for (auto& i : m_entries) {
Entry* entry = i.getValue();
if (!entry->value || !i.getKey().startswith(prefixStr)) continue;
if (!entry->value || !i.getKey().startswith(prefixStr)) {
continue;
}
m_notifier.NotifyEntry(entry->local_id, i.getKey(), entry->value,
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW, uid);
}
@@ -902,9 +1045,13 @@ unsigned int Storage::AddPolledListener(unsigned int poller,
// perform immediate notifications
if ((flags & NT_NOTIFY_IMMEDIATE) != 0 && (flags & NT_NOTIFY_NEW) != 0) {
for (auto& i : m_entries) {
if (!i.getKey().startswith(prefixStr)) continue;
if (!i.getKey().startswith(prefixStr)) {
continue;
}
Entry* entry = i.getValue();
if (!entry->value) continue;
if (!entry->value) {
continue;
}
m_notifier.NotifyEntry(entry->local_id, i.getKey(), entry->value,
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW, uid);
}
@@ -938,13 +1085,17 @@ bool Storage::GetPersistentEntries(
{
std::scoped_lock lock(m_mutex);
// for periodic, don't re-save unless something has changed
if (periodic && !m_persistent_dirty) return false;
if (periodic && !m_persistent_dirty) {
return false;
}
m_persistent_dirty = false;
entries->reserve(m_entries.size());
for (auto& i : m_entries) {
Entry* entry = i.getValue();
// only write persistent-flagged values
if (!entry->value || !entry->IsPersistent()) continue;
if (!entry->value || !entry->IsPersistent()) {
continue;
}
entries->emplace_back(i.getKey(), entry->value);
}
}
@@ -971,7 +1122,9 @@ bool Storage::GetEntries(
for (auto& i : m_entries) {
Entry* entry = i.getValue();
// only write values with given prefix
if (!entry->value || !i.getKey().startswith(prefixStr)) continue;
if (!entry->value || !i.getKey().startswith(prefixStr)) {
continue;
}
entries->emplace_back(i.getKey(), entry->value);
}
}
@@ -988,7 +1141,9 @@ bool Storage::GetEntries(
void Storage::CreateRpc(unsigned int local_id, StringRef def,
unsigned int rpc_uid) {
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return;
if (local_id >= m_localmap.size()) {
return;
}
Entry* entry = m_localmap[local_id].get();
auto old_value = entry->value;
@@ -998,7 +1153,9 @@ void Storage::CreateRpc(unsigned int local_id, StringRef def,
// set up the RPC info
entry->rpc_uid = rpc_uid;
if (old_value && *old_value == *value) return;
if (old_value && *old_value == *value) {
return;
}
// assign an id if it doesn't have one
if (entry->id == 0xffff) {
@@ -1008,7 +1165,9 @@ void Storage::CreateRpc(unsigned int local_id, StringRef def,
}
// generate message
if (!m_dispatcher) return;
if (!m_dispatcher) {
return;
}
auto dispatcher = m_dispatcher;
if (!old_value || old_value->type() != value->type()) {
++entry->seq_num;
@@ -1026,13 +1185,19 @@ void Storage::CreateRpc(unsigned int local_id, StringRef def,
unsigned int Storage::CallRpc(unsigned int local_id, StringRef params) {
std::unique_lock lock(m_mutex);
if (local_id >= m_localmap.size()) return 0;
if (local_id >= m_localmap.size()) {
return 0;
}
Entry* entry = m_localmap[local_id].get();
if (!entry->value || !entry->value->IsRpc()) return 0;
if (!entry->value || !entry->value->IsRpc()) {
return 0;
}
++entry->rpc_call_uid;
if (entry->rpc_call_uid > 0xffff) entry->rpc_call_uid = 0;
if (entry->rpc_call_uid > 0xffff) {
entry->rpc_call_uid = 0;
}
unsigned int call_uid = entry->rpc_call_uid;
auto msg = Message::ExecuteRpc(entry->id, call_uid, params);
@@ -1081,7 +1246,9 @@ bool Storage::GetRpcResult(unsigned int local_id, unsigned int call_uid,
RpcIdPair call_pair{local_id, call_uid};
// only allow one blocking call per rpc call uid
if (!m_rpc_blocking_calls.insert(call_pair).second) return false;
if (!m_rpc_blocking_calls.insert(call_pair).second) {
return false;
}
auto timeout_time =
std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);

View File

@@ -43,7 +43,9 @@ class LoadPersistentImpl {
std::shared_ptr<Value> ReadStringArrayValue();
void Warn(const char* msg) {
if (m_warn) m_warn(m_line_num, msg);
if (m_warn) {
m_warn(m_line_num, msg);
}
}
wpi::raw_istream& m_is;
@@ -71,8 +73,9 @@ class LoadPersistentImpl {
static std::pair<wpi::StringRef, wpi::StringRef> ReadStringToken(
wpi::StringRef source) {
// Match opening quote
if (source.empty() || source.front() != '"')
if (source.empty() || source.front() != '"') {
return std::make_pair(wpi::StringRef(), source);
}
// Scan for ending double quote, checking for escaped as we go.
size_t size = source.size();
@@ -87,12 +90,13 @@ static std::pair<wpi::StringRef, wpi::StringRef> ReadStringToken(
}
static int fromxdigit(char ch) {
if (ch >= 'a' && ch <= 'f')
if (ch >= 'a' && ch <= 'f') {
return (ch - 'a' + 10);
else if (ch >= 'A' && ch <= 'F')
} else if (ch >= 'A' && ch <= 'F') {
return (ch - 'A' + 10);
else
} else {
return ch - '0';
}
}
static wpi::StringRef UnescapeString(wpi::StringRef source,
@@ -134,7 +138,9 @@ static wpi::StringRef UnescapeString(wpi::StringRef source,
}
bool LoadPersistentImpl::Load(StringRef prefix, std::vector<Entry>* entries) {
if (!ReadHeader()) return false; // header
if (!ReadHeader()) {
return false; // header
}
while (ReadLine()) {
// type
@@ -147,7 +153,9 @@ bool LoadPersistentImpl::Load(StringRef prefix, std::vector<Entry>* entries) {
// name
wpi::SmallString<128> buf;
wpi::StringRef name = ReadName(buf);
if (name.empty() || !name.startswith(prefix)) continue;
if (name.empty() || !name.startswith(prefix)) {
continue;
}
// =
m_line = m_line.ltrim(" \t");
@@ -161,7 +169,9 @@ bool LoadPersistentImpl::Load(StringRef prefix, std::vector<Entry>* entries) {
auto value = ReadValue(type);
// move to entries
if (value) entries->emplace_back(name, std::move(value));
if (value) {
entries->emplace_back(name, std::move(value));
}
}
return true;
}
@@ -171,8 +181,9 @@ bool LoadPersistentImpl::ReadLine() {
while (!m_is.has_error()) {
++m_line_num;
m_line = m_is.getline(m_line_buf, INT_MAX).trim();
if (!m_line.empty() && m_line.front() != ';' && m_line.front() != '#')
if (!m_line.empty() && m_line.front() != ';' && m_line.front() != '#') {
return true;
}
}
return false;
}
@@ -200,12 +211,13 @@ NT_Type LoadPersistentImpl::ReadType() {
} else if (tok == "array") {
wpi::StringRef array_tok;
std::tie(array_tok, m_line) = m_line.split(' ');
if (array_tok == "boolean")
if (array_tok == "boolean") {
return NT_BOOLEAN_ARRAY;
else if (array_tok == "double")
} else if (array_tok == "double") {
return NT_DOUBLE_ARRAY;
else if (array_tok == "string")
} else if (array_tok == "string") {
return NT_STRING_ARRAY;
}
}
return NT_UNASSIGNED;
}
@@ -247,8 +259,12 @@ std::shared_ptr<Value> LoadPersistentImpl::ReadValue(NT_Type type) {
std::shared_ptr<Value> LoadPersistentImpl::ReadBooleanValue() {
// only true or false is accepted
if (m_line == "true") return Value::MakeBoolean(true);
if (m_line == "false") return Value::MakeBoolean(false);
if (m_line == "true") {
return Value::MakeBoolean(true);
}
if (m_line == "false") {
return Value::MakeBoolean(false);
}
Warn("unrecognized boolean value, not 'true' or 'false'");
return nullptr;
}
@@ -342,7 +358,9 @@ std::shared_ptr<Value> LoadPersistentImpl::ReadStringArrayValue() {
m_buf_string_array.push_back(UnescapeString(tok, buf));
m_line = m_line.ltrim(" \t");
if (m_line.empty()) break;
if (m_line.empty()) {
break;
}
if (m_line.front() != ',') {
Warn("expected comma between strings");
return nullptr;
@@ -363,7 +381,9 @@ bool Storage::LoadEntries(
std::vector<LoadPersistentImpl::Entry> entries;
// load file
if (!LoadPersistentImpl(is, warn).Load(prefixStr, &entries)) return false;
if (!LoadPersistentImpl(is, warn).Load(prefixStr, &entries)) {
return false;
}
// copy values into storage as quickly as possible so lock isn't held
std::vector<std::shared_ptr<Message>> msgs;
@@ -373,7 +393,9 @@ bool Storage::LoadEntries(
auto old_value = entry->value;
entry->value = i.second;
bool was_persist = entry->IsPersistent();
if (!was_persist && persistent) entry->flags |= NT_PERSISTENT;
if (!was_persist && persistent) {
entry->flags |= NT_PERSISTENT;
}
// if we're the server, assign an id if it doesn't have one
if (m_server && entry->id == 0xffff) {
@@ -389,7 +411,9 @@ bool Storage::LoadEntries(
NT_NOTIFY_NEW | NT_NOTIFY_LOCAL);
} else if (*old_value != *i.second) {
unsigned int notify_flags = NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL;
if (!was_persist && persistent) notify_flags |= NT_NOTIFY_FLAGS;
if (!was_persist && persistent) {
notify_flags |= NT_NOTIFY_FLAGS;
}
m_notifier.NotifyEntry(entry->local_id, i.first, i.second,
notify_flags);
} else if (!was_persist && persistent) {
@@ -398,7 +422,9 @@ bool Storage::LoadEntries(
}
}
if (!m_dispatcher) continue; // shortcut
if (!m_dispatcher) {
continue; // shortcut
}
++entry->seq_num;
// put on update queue
@@ -407,19 +433,22 @@ bool Storage::LoadEntries(
i.first, entry->id, entry->seq_num.value(), i.second, entry->flags));
} else if (entry->id != 0xffff) {
// don't send an update if we don't have an assigned id yet
if (*old_value != *i.second)
if (*old_value != *i.second) {
msgs.emplace_back(
Message::EntryUpdate(entry->id, entry->seq_num.value(), i.second));
if (!was_persist)
}
if (!was_persist) {
msgs.emplace_back(Message::FlagsUpdate(entry->id, entry->flags));
}
}
}
if (m_dispatcher) {
auto dispatcher = m_dispatcher;
lock.unlock();
for (auto& msg : msgs)
for (auto& msg : msgs) {
dispatcher->QueueOutgoing(std::move(msg), nullptr, nullptr);
}
}
return true;
@@ -430,8 +459,12 @@ const char* Storage::LoadPersistent(
std::function<void(size_t line, const char* msg)> warn) {
std::error_code ec;
wpi::raw_fd_istream is(filename, ec);
if (ec.value() != 0) return "could not open file";
if (!LoadEntries(is, "", true, warn)) return "error reading file";
if (ec.value() != 0) {
return "could not open file";
}
if (!LoadEntries(is, "", true, warn)) {
return "error reading file";
}
return nullptr;
}
@@ -440,7 +473,11 @@ const char* Storage::LoadEntries(
std::function<void(size_t line, const char* msg)> warn) {
std::error_code ec;
wpi::raw_fd_istream is(filename, ec);
if (ec.value() != 0) return "could not open file";
if (!LoadEntries(is, prefix, false, warn)) return "error reading file";
if (ec.value() != 0) {
return "could not open file";
}
if (!LoadEntries(is, prefix, false, warn)) {
return "error reading file";
}
return nullptr;
}

View File

@@ -83,17 +83,21 @@ void SavePersistentImpl::WriteHeader() {
void SavePersistentImpl::WriteEntries(wpi::ArrayRef<Entry> entries) {
for (auto& i : entries) {
if (!i.second) continue;
if (!i.second) {
continue;
}
WriteEntry(i.first, *i.second);
}
}
void SavePersistentImpl::WriteEntry(wpi::StringRef name, const Value& value) {
if (!WriteType(value.type())) return; // type
WriteString(name); // name
m_os << '='; // '='
WriteValue(value); // value
m_os << '\n'; // eol
if (!WriteType(value.type())) {
return; // type
}
WriteString(name); // name
m_os << '='; // '='
WriteValue(value); // value
m_os << '\n'; // eol
}
bool SavePersistentImpl::WriteType(NT_Type type) {
@@ -143,7 +147,9 @@ void SavePersistentImpl::WriteValue(const Value& value) {
case NT_BOOLEAN_ARRAY: {
bool first = true;
for (auto elem : value.GetBooleanArray()) {
if (!first) m_os << ',';
if (!first) {
m_os << ',';
}
first = false;
m_os << (elem ? "true" : "false");
}
@@ -152,7 +158,9 @@ void SavePersistentImpl::WriteValue(const Value& value) {
case NT_DOUBLE_ARRAY: {
bool first = true;
for (auto elem : value.GetDoubleArray()) {
if (!first) m_os << ',';
if (!first) {
m_os << ',';
}
first = false;
m_os << wpi::format("%g", elem);
}
@@ -161,7 +169,9 @@ void SavePersistentImpl::WriteValue(const Value& value) {
case NT_STRING_ARRAY: {
bool first = true;
for (auto& elem : value.GetStringArray()) {
if (!first) m_os << ',';
if (!first) {
m_os << ',';
}
first = false;
WriteString(elem);
}
@@ -174,7 +184,9 @@ void SavePersistentImpl::WriteValue(const Value& value) {
void Storage::SavePersistent(wpi::raw_ostream& os, bool periodic) const {
std::vector<SavePersistentImpl::Entry> entries;
if (!GetPersistentEntries(periodic, &entries)) return;
if (!GetPersistentEntries(periodic, &entries)) {
return;
}
SavePersistentImpl(os).Save(entries);
}
@@ -189,7 +201,9 @@ const char* Storage::SavePersistent(const Twine& filename,
// Get entries before creating file
std::vector<SavePersistentImpl::Entry> entries;
if (!GetPersistentEntries(periodic, &entries)) return nullptr;
if (!GetPersistentEntries(periodic, &entries)) {
return nullptr;
}
const char* err = nullptr;
@@ -220,13 +234,17 @@ const char* Storage::SavePersistent(const Twine& filename,
done:
// try again if there was an error
if (err && periodic) m_persistent_dirty = true;
if (err && periodic) {
m_persistent_dirty = true;
}
return err;
}
void Storage::SaveEntries(wpi::raw_ostream& os, const Twine& prefix) const {
std::vector<SavePersistentImpl::Entry> entries;
if (!GetEntries(prefix, &entries)) return;
if (!GetEntries(prefix, &entries)) {
return;
}
SavePersistentImpl(os).Save(entries);
}
@@ -241,7 +259,9 @@ const char* Storage::SaveEntries(const Twine& filename,
// Get entries before creating file
std::vector<SavePersistentImpl::Entry> entries;
if (!GetEntries(prefix, &entries)) return nullptr;
if (!GetEntries(prefix, &entries)) {
return nullptr;
}
// start by writing to temporary file
std::error_code ec;

View File

@@ -19,25 +19,28 @@ Value::Value() {
Value::Value(NT_Type type, uint64_t time, const private_init&) {
m_val.type = type;
if (time == 0)
if (time == 0) {
m_val.last_change = wpi::Now();
else
} else {
m_val.last_change = time;
if (m_val.type == NT_BOOLEAN_ARRAY)
}
if (m_val.type == NT_BOOLEAN_ARRAY) {
m_val.data.arr_boolean.arr = nullptr;
else if (m_val.type == NT_DOUBLE_ARRAY)
} else if (m_val.type == NT_DOUBLE_ARRAY) {
m_val.data.arr_double.arr = nullptr;
else if (m_val.type == NT_STRING_ARRAY)
} else if (m_val.type == NT_STRING_ARRAY) {
m_val.data.arr_string.arr = nullptr;
}
}
Value::~Value() {
if (m_val.type == NT_BOOLEAN_ARRAY)
if (m_val.type == NT_BOOLEAN_ARRAY) {
delete[] m_val.data.arr_boolean.arr;
else if (m_val.type == NT_DOUBLE_ARRAY)
} else if (m_val.type == NT_DOUBLE_ARRAY) {
delete[] m_val.data.arr_double.arr;
else if (m_val.type == NT_STRING_ARRAY)
} else if (m_val.type == NT_STRING_ARRAY) {
delete[] m_val.data.arr_string.arr;
}
}
std::shared_ptr<Value> Value::MakeBooleanArray(wpi::ArrayRef<bool> value,
@@ -137,8 +140,9 @@ void nt::ConvertToC(const Value& in, NT_Value* out) {
auto v = in.GetStringArray();
out->data.arr_string.arr = static_cast<NT_String*>(
wpi::safe_malloc(v.size() * sizeof(NT_String)));
for (size_t i = 0; i < v.size(); ++i)
for (size_t i = 0; i < v.size(); ++i) {
ConvertToC(v[i], &out->data.arr_string.arr[i]);
}
out->data.arr_string.size = v.size();
break;
}
@@ -179,8 +183,9 @@ std::shared_ptr<Value> nt::ConvertFromC(const NT_Value& value) {
case NT_STRING_ARRAY: {
std::vector<std::string> v;
v.reserve(value.data.arr_string.size);
for (size_t i = 0; i < value.data.arr_string.size; ++i)
for (size_t i = 0; i < value.data.arr_string.size; ++i) {
v.push_back(ConvertFromC(value.data.arr_string.arr[i]));
}
return Value::MakeStringArray(std::move(v));
}
default:
@@ -190,7 +195,9 @@ std::shared_ptr<Value> nt::ConvertFromC(const NT_Value& value) {
}
bool nt::operator==(const Value& lhs, const Value& rhs) {
if (lhs.type() != rhs.type()) return false;
if (lhs.type() != rhs.type()) {
return false;
}
switch (lhs.type()) {
case NT_UNASSIGNED:
return true; // XXX: is this better being false instead?
@@ -203,15 +210,17 @@ bool nt::operator==(const Value& lhs, const Value& rhs) {
case NT_RPC:
return lhs.m_string == rhs.m_string;
case NT_BOOLEAN_ARRAY:
if (lhs.m_val.data.arr_boolean.size != rhs.m_val.data.arr_boolean.size)
if (lhs.m_val.data.arr_boolean.size != rhs.m_val.data.arr_boolean.size) {
return false;
}
return std::memcmp(lhs.m_val.data.arr_boolean.arr,
rhs.m_val.data.arr_boolean.arr,
lhs.m_val.data.arr_boolean.size *
sizeof(lhs.m_val.data.arr_boolean.arr[0])) == 0;
case NT_DOUBLE_ARRAY:
if (lhs.m_val.data.arr_double.size != rhs.m_val.data.arr_double.size)
if (lhs.m_val.data.arr_double.size != rhs.m_val.data.arr_double.size) {
return false;
}
return std::memcmp(lhs.m_val.data.arr_double.arr,
rhs.m_val.data.arr_double.arr,
lhs.m_val.data.arr_double.size *

View File

@@ -55,27 +55,37 @@ WireDecoder::WireDecoder(wpi::raw_istream& is, unsigned int proto_rev,
m_error = nullptr;
}
WireDecoder::~WireDecoder() { std::free(m_buf); }
WireDecoder::~WireDecoder() {
std::free(m_buf);
}
bool WireDecoder::ReadDouble(double* val) {
const char* buf;
if (!Read(&buf, 8)) return false;
if (!Read(&buf, 8)) {
return false;
}
*val = ::ReadDouble(buf);
return true;
}
void WireDecoder::Realloc(size_t len) {
// Double current buffer size until we have enough space.
if (m_allocated >= len) return;
if (m_allocated >= len) {
return;
}
size_t newlen = m_allocated * 2;
while (newlen < len) newlen *= 2;
while (newlen < len) {
newlen *= 2;
}
m_buf = static_cast<char*>(wpi::safe_realloc(m_buf, newlen));
m_allocated = newlen;
}
bool WireDecoder::ReadType(NT_Type* type) {
unsigned int itype;
if (!Read8(&itype)) return false;
if (!Read8(&itype)) {
return false;
}
// Convert from byte value to enum
switch (itype) {
case 0x00:
@@ -114,17 +124,23 @@ std::shared_ptr<Value> WireDecoder::ReadValue(NT_Type type) {
switch (type) {
case NT_BOOLEAN: {
unsigned int v;
if (!Read8(&v)) return nullptr;
if (!Read8(&v)) {
return nullptr;
}
return Value::MakeBoolean(v != 0);
}
case NT_DOUBLE: {
double v;
if (!ReadDouble(&v)) return nullptr;
if (!ReadDouble(&v)) {
return nullptr;
}
return Value::MakeDouble(v);
}
case NT_STRING: {
std::string v;
if (!ReadString(&v)) return nullptr;
if (!ReadString(&v)) {
return nullptr;
}
return Value::MakeString(std::move(v));
}
case NT_RAW: {
@@ -133,7 +149,9 @@ std::shared_ptr<Value> WireDecoder::ReadValue(NT_Type type) {
return nullptr;
}
std::string v;
if (!ReadString(&v)) return nullptr;
if (!ReadString(&v)) {
return nullptr;
}
return Value::MakeRaw(std::move(v));
}
case NT_RPC: {
@@ -142,42 +160,60 @@ std::shared_ptr<Value> WireDecoder::ReadValue(NT_Type type) {
return nullptr;
}
std::string v;
if (!ReadString(&v)) return nullptr;
if (!ReadString(&v)) {
return nullptr;
}
return Value::MakeRpc(std::move(v));
}
case NT_BOOLEAN_ARRAY: {
// size
unsigned int size;
if (!Read8(&size)) return nullptr;
if (!Read8(&size)) {
return nullptr;
}
// array values
const char* buf;
if (!Read(&buf, size)) return nullptr;
if (!Read(&buf, size)) {
return nullptr;
}
std::vector<int> v(size);
for (unsigned int i = 0; i < size; ++i) v[i] = buf[i] ? 1 : 0;
for (unsigned int i = 0; i < size; ++i) {
v[i] = buf[i] ? 1 : 0;
}
return Value::MakeBooleanArray(std::move(v));
}
case NT_DOUBLE_ARRAY: {
// size
unsigned int size;
if (!Read8(&size)) return nullptr;
if (!Read8(&size)) {
return nullptr;
}
// array values
const char* buf;
if (!Read(&buf, size * 8)) return nullptr;
if (!Read(&buf, size * 8)) {
return nullptr;
}
std::vector<double> v(size);
for (unsigned int i = 0; i < size; ++i) v[i] = ::ReadDouble(buf);
for (unsigned int i = 0; i < size; ++i) {
v[i] = ::ReadDouble(buf);
}
return Value::MakeDoubleArray(std::move(v));
}
case NT_STRING_ARRAY: {
// size
unsigned int size;
if (!Read8(&size)) return nullptr;
if (!Read8(&size)) {
return nullptr;
}
// array values
std::vector<std::string> v(size);
for (unsigned int i = 0; i < size; ++i) {
if (!ReadString(&v[i])) return nullptr;
if (!ReadString(&v[i])) {
return nullptr;
}
}
return Value::MakeStringArray(std::move(v));
}
@@ -191,15 +227,21 @@ bool WireDecoder::ReadString(std::string* str) {
size_t len;
if (m_proto_rev < 0x0300u) {
unsigned int v;
if (!Read16(&v)) return false;
if (!Read16(&v)) {
return false;
}
len = v;
} else {
uint64_t v;
if (!ReadUleb128(&v)) return false;
if (!ReadUleb128(&v)) {
return false;
}
len = v;
}
const char* buf;
if (!Read(&buf, len)) return false;
if (!Read(&buf, len)) {
return false;
}
*str = wpi::StringRef(buf, len);
return true;
}

View File

@@ -56,7 +56,9 @@ class WireDecoder {
* Caution: the buffer is only temporarily valid.
*/
bool Read(const char** buf, size_t len) {
if (len > m_allocated) Realloc(len);
if (len > m_allocated) {
Realloc(len);
}
*buf = m_buf;
m_is.read(m_buf, len);
#if 0
@@ -78,7 +80,9 @@ class WireDecoder {
/* Reads a single byte. */
bool Read8(unsigned int* val) {
const char* buf;
if (!Read(&buf, 1)) return false;
if (!Read(&buf, 1)) {
return false;
}
*val = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
return true;
}
@@ -86,7 +90,9 @@ class WireDecoder {
/* Reads a 16-bit word. */
bool Read16(unsigned int* val) {
const char* buf;
if (!Read(&buf, 2)) return false;
if (!Read(&buf, 2)) {
return false;
}
unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
++buf;
v <<= 8;
@@ -98,7 +104,9 @@ class WireDecoder {
/* Reads a 32-bit word. */
bool Read32(uint32_t* val) {
const char* buf;
if (!Read(&buf, 4)) return false;
if (!Read(&buf, 4)) {
return false;
}
unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
++buf;
v <<= 8;

View File

@@ -30,7 +30,9 @@ void WireEncoder::WriteDouble(double val) {
static_cast<char>((v >> 8) & 0xff), static_cast<char>(v & 0xff)});
}
void WireEncoder::WriteUleb128(uint32_t val) { wpi::WriteUleb128(m_data, val); }
void WireEncoder::WriteUleb128(uint32_t val) {
wpi::WriteUleb128(m_data, val);
}
void WireEncoder::WriteType(NT_Type type) {
char ch;
@@ -84,29 +86,41 @@ size_t WireEncoder::GetValueSize(const Value& value) const {
case NT_STRING:
return GetStringSize(value.GetString());
case NT_RAW:
if (m_proto_rev < 0x0300u) return 0;
if (m_proto_rev < 0x0300u) {
return 0;
}
return GetStringSize(value.GetRaw());
case NT_RPC:
if (m_proto_rev < 0x0300u) return 0;
if (m_proto_rev < 0x0300u) {
return 0;
}
return GetStringSize(value.GetRpc());
case NT_BOOLEAN_ARRAY: {
// 1-byte size, 1 byte per element
size_t size = value.GetBooleanArray().size();
if (size > 0xff) size = 0xff; // size is only 1 byte, truncate
if (size > 0xff) {
size = 0xff; // size is only 1 byte, truncate
}
return 1 + size;
}
case NT_DOUBLE_ARRAY: {
// 1-byte size, 8 bytes per element
size_t size = value.GetDoubleArray().size();
if (size > 0xff) size = 0xff; // size is only 1 byte, truncate
if (size > 0xff) {
size = 0xff; // size is only 1 byte, truncate
}
return 1 + size * 8;
}
case NT_STRING_ARRAY: {
auto v = value.GetStringArray();
size_t size = v.size();
if (size > 0xff) size = 0xff; // size is only 1 byte, truncate
size_t len = 1; // 1-byte size
for (size_t i = 0; i < size; ++i) len += GetStringSize(v[i]);
if (size > 0xff) {
size = 0xff; // size is only 1 byte, truncate
}
size_t len = 1; // 1-byte size
for (size_t i = 0; i < size; ++i) {
len += GetStringSize(v[i]);
}
return len;
}
default:
@@ -142,28 +156,40 @@ void WireEncoder::WriteValue(const Value& value) {
case NT_BOOLEAN_ARRAY: {
auto v = value.GetBooleanArray();
size_t size = v.size();
if (size > 0xff) size = 0xff; // size is only 1 byte, truncate
if (size > 0xff) {
size = 0xff; // size is only 1 byte, truncate
}
Write8(size);
for (size_t i = 0; i < size; ++i) Write8(v[i] ? 1 : 0);
for (size_t i = 0; i < size; ++i) {
Write8(v[i] ? 1 : 0);
}
break;
}
case NT_DOUBLE_ARRAY: {
auto v = value.GetDoubleArray();
size_t size = v.size();
if (size > 0xff) size = 0xff; // size is only 1 byte, truncate
if (size > 0xff) {
size = 0xff; // size is only 1 byte, truncate
}
Write8(size);
for (size_t i = 0; i < size; ++i) WriteDouble(v[i]);
for (size_t i = 0; i < size; ++i) {
WriteDouble(v[i]);
}
break;
}
case NT_STRING_ARRAY: {
auto v = value.GetStringArray();
size_t size = v.size();
if (size > 0xff) size = 0xff; // size is only 1 byte, truncate
if (size > 0xff) {
size = 0xff; // size is only 1 byte, truncate
}
Write8(size);
for (size_t i = 0; i < size; ++i) WriteString(v[i]);
for (size_t i = 0; i < size; ++i) {
WriteString(v[i]);
}
break;
}
default:
@@ -175,7 +201,9 @@ void WireEncoder::WriteValue(const Value& value) {
size_t WireEncoder::GetStringSize(wpi::StringRef str) const {
if (m_proto_rev < 0x0300u) {
size_t len = str.size();
if (len > 0xffff) len = 0xffff; // Limited to 64K length; truncate
if (len > 0xffff) {
len = 0xffff; // Limited to 64K length; truncate
}
return 2 + len;
}
return wpi::SizeUleb128(str.size()) + str.size();
@@ -185,7 +213,9 @@ void WireEncoder::WriteString(wpi::StringRef str) {
// length
size_t len = str.size();
if (m_proto_rev < 0x0300u) {
if (len > 0xffff) len = 0xffff; // Limited to 64K length; truncate
if (len > 0xffff) {
len = 0xffff; // Limited to 64K length; truncate
}
Write16(len);
} else {
WriteUleb128(len);

View File

@@ -64,18 +64,23 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
jvm = vm;
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
// Cache references to classes
for (auto& c : classes) {
*c.cls = JClass(env, c.name);
if (!*c.cls) return JNI_ERR;
if (!*c.cls) {
return JNI_ERR;
}
}
for (auto& c : exceptions) {
*c.cls = JException(env, c.name);
if (!*c.cls) return JNI_ERR;
if (!*c.cls) {
return JNI_ERR;
}
}
return JNI_VERSION_1_6;
@@ -83,8 +88,9 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return;
}
// Delete global references
for (auto& c : classes) {
c.cls->free(env);
@@ -104,40 +110,52 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) {
inline std::shared_ptr<nt::Value> FromJavaRaw(JNIEnv* env, jbyteArray jarr,
jlong time) {
CriticalJByteArrayRef ref{env, jarr};
if (!ref) return nullptr;
if (!ref) {
return nullptr;
}
return nt::Value::MakeRaw(ref, time);
}
inline std::shared_ptr<nt::Value> FromJavaRawBB(JNIEnv* env, jobject jbb,
int len, jlong time) {
JByteArrayRef ref{env, jbb, len};
if (!ref) return nullptr;
if (!ref) {
return nullptr;
}
return nt::Value::MakeRaw(ref.str(), time);
}
inline std::shared_ptr<nt::Value> FromJavaRpc(JNIEnv* env, jbyteArray jarr,
jlong time) {
CriticalJByteArrayRef ref{env, jarr};
if (!ref) return nullptr;
if (!ref) {
return nullptr;
}
return nt::Value::MakeRpc(ref.str(), time);
}
std::shared_ptr<nt::Value> FromJavaBooleanArray(JNIEnv* env, jbooleanArray jarr,
jlong time) {
CriticalJBooleanArrayRef ref{env, jarr};
if (!ref) return nullptr;
if (!ref) {
return nullptr;
}
wpi::ArrayRef<jboolean> elements{ref};
size_t len = elements.size();
std::vector<int> arr;
arr.reserve(len);
for (size_t i = 0; i < len; ++i) arr.push_back(elements[i]);
for (size_t i = 0; i < len; ++i) {
arr.push_back(elements[i]);
}
return nt::Value::MakeBooleanArray(arr, time);
}
std::shared_ptr<nt::Value> FromJavaDoubleArray(JNIEnv* env, jdoubleArray jarr,
jlong time) {
CriticalJDoubleArrayRef ref{env, jarr};
if (!ref) return nullptr;
if (!ref) {
return nullptr;
}
return nt::Value::MakeDoubleArray(ref, time);
}
@@ -149,7 +167,9 @@ std::shared_ptr<nt::Value> FromJavaStringArray(JNIEnv* env, jobjectArray jarr,
for (size_t i = 0; i < len; ++i) {
JLocal<jstring> elem{
env, static_cast<jstring>(env->GetObjectArrayElement(jarr, i))};
if (!elem) return nullptr;
if (!elem) {
return nullptr;
}
arr.push_back(JStringRef{env, elem}.str());
}
return nt::Value::MakeStringArray(std::move(arr), time);
@@ -162,10 +182,12 @@ std::shared_ptr<nt::Value> FromJavaStringArray(JNIEnv* env, jobjectArray jarr,
static jobject MakeJObject(JNIEnv* env, const nt::Value& value) {
static jmethodID booleanConstructor = nullptr;
static jmethodID doubleConstructor = nullptr;
if (!booleanConstructor)
if (!booleanConstructor) {
booleanConstructor = env->GetMethodID(booleanCls, "<init>", "(Z)V");
if (!doubleConstructor)
}
if (!doubleConstructor) {
doubleConstructor = env->GetMethodID(doubleCls, "<init>", "(D)V");
}
switch (value.type()) {
case NT_BOOLEAN:
@@ -194,9 +216,10 @@ static jobject MakeJObject(JNIEnv* env, const nt::Value& value) {
static jobject MakeJValue(JNIEnv* env, const nt::Value* value) {
static jmethodID constructor =
env->GetMethodID(valueCls, "<init>", "(ILjava/lang/Object;J)V");
if (!value)
if (!value) {
return env->NewObject(valueCls, constructor, (jint)NT_UNASSIGNED, nullptr,
(jlong)0);
}
return env->NewObject(valueCls, constructor, (jint)value->type(),
MakeJObject(env, *value), (jlong)value->time());
}
@@ -281,7 +304,9 @@ static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
wpi::ArrayRef<nt::ConnectionNotification> arr) {
jobjectArray jarr =
env->NewObjectArray(arr.size(), connectionNotificationCls, nullptr);
if (!jarr) return nullptr;
if (!jarr) {
return nullptr;
}
for (size_t i = 0; i < arr.size(); ++i) {
JLocal<jobject> elem{env, MakeJObject(env, inst, arr[i])};
env->SetObjectArrayElement(jarr, i, elem.obj());
@@ -293,7 +318,9 @@ static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
wpi::ArrayRef<nt::EntryNotification> arr) {
jobjectArray jarr =
env->NewObjectArray(arr.size(), entryNotificationCls, nullptr);
if (!jarr) return nullptr;
if (!jarr) {
return nullptr;
}
for (size_t i = 0; i < arr.size(); ++i) {
JLocal<jobject> elem{env, MakeJObject(env, inst, arr[i])};
env->SetObjectArrayElement(jarr, i, elem.obj());
@@ -304,7 +331,9 @@ static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
wpi::ArrayRef<nt::LogMessage> arr) {
jobjectArray jarr = env->NewObjectArray(arr.size(), logMessageCls, nullptr);
if (!jarr) return nullptr;
if (!jarr) {
return nullptr;
}
for (size_t i = 0; i < arr.size(); ++i) {
JLocal<jobject> elem{env, MakeJObject(env, inst, arr[i])};
env->SetObjectArrayElement(jarr, i, elem.obj());
@@ -315,7 +344,9 @@ static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
wpi::ArrayRef<nt::RpcAnswer> arr) {
jobjectArray jarr = env->NewObjectArray(arr.size(), rpcAnswerCls, nullptr);
if (!jarr) return nullptr;
if (!jarr) {
return nullptr;
}
for (size_t i = 0; i < arr.size(); ++i) {
JLocal<jobject> elem{env, MakeJObject(env, inst, arr[i])};
env->SetObjectArrayElement(jarr, i, elem.obj());
@@ -513,7 +544,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setRaw__IJ_3BZ
return false;
}
auto v = FromJavaRaw(env, value, time);
if (!v) return false;
if (!v) {
return false;
}
if (force) {
nt::SetEntryTypeValue(entry, v);
return JNI_TRUE;
@@ -536,7 +569,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setRaw__IJLjava_nio_ByteBuffer
return false;
}
auto v = FromJavaRawBB(env, value, len, time);
if (!v) return false;
if (!v) {
return false;
}
if (force) {
nt::SetEntryTypeValue(entry, v);
return JNI_TRUE;
@@ -559,7 +594,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setBooleanArray
return false;
}
auto v = FromJavaBooleanArray(env, value, time);
if (!v) return false;
if (!v) {
return false;
}
if (force) {
nt::SetEntryTypeValue(entry, v);
return JNI_TRUE;
@@ -582,7 +619,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setDoubleArray
return false;
}
auto v = FromJavaDoubleArray(env, value, time);
if (!v) return false;
if (!v) {
return false;
}
if (force) {
nt::SetEntryTypeValue(entry, v);
return JNI_TRUE;
@@ -605,7 +644,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setStringArray
return false;
}
auto v = FromJavaStringArray(env, value, time);
if (!v) return false;
if (!v) {
return false;
}
if (force) {
nt::SetEntryTypeValue(entry, v);
return JNI_TRUE;
@@ -636,7 +677,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getBoolean
(JNIEnv*, jclass, jint entry, jboolean defaultValue)
{
auto val = nt::GetEntryValue(entry);
if (!val || !val->IsBoolean()) return defaultValue;
if (!val || !val->IsBoolean()) {
return defaultValue;
}
return val->GetBoolean();
}
@@ -650,7 +693,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getDouble
(JNIEnv*, jclass, jint entry, jdouble defaultValue)
{
auto val = nt::GetEntryValue(entry);
if (!val || !val->IsDouble()) return defaultValue;
if (!val || !val->IsDouble()) {
return defaultValue;
}
return val->GetDouble();
}
@@ -664,7 +709,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getString
(JNIEnv* env, jclass, jint entry, jstring defaultValue)
{
auto val = nt::GetEntryValue(entry);
if (!val || !val->IsString()) return defaultValue;
if (!val || !val->IsString()) {
return defaultValue;
}
return MakeJString(env, val->GetString());
}
@@ -678,7 +725,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getRaw
(JNIEnv* env, jclass, jint entry, jbyteArray defaultValue)
{
auto val = nt::GetEntryValue(entry);
if (!val || !val->IsRaw()) return defaultValue;
if (!val || !val->IsRaw()) {
return defaultValue;
}
return MakeJByteArray(env, val->GetRaw());
}
@@ -692,7 +741,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getBooleanArray
(JNIEnv* env, jclass, jint entry, jbooleanArray defaultValue)
{
auto val = nt::GetEntryValue(entry);
if (!val || !val->IsBooleanArray()) return defaultValue;
if (!val || !val->IsBooleanArray()) {
return defaultValue;
}
return MakeJBooleanArray(env, val->GetBooleanArray());
}
@@ -706,7 +757,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getDoubleArray
(JNIEnv* env, jclass, jint entry, jdoubleArray defaultValue)
{
auto val = nt::GetEntryValue(entry);
if (!val || !val->IsDoubleArray()) return defaultValue;
if (!val || !val->IsDoubleArray()) {
return defaultValue;
}
return MakeJDoubleArray(env, val->GetDoubleArray());
}
@@ -720,7 +773,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getStringArray
(JNIEnv* env, jclass, jint entry, jobjectArray defaultValue)
{
auto val = nt::GetEntryValue(entry);
if (!val || !val->IsStringArray()) return defaultValue;
if (!val || !val->IsStringArray()) {
return defaultValue;
}
return MakeJStringArray(env, val->GetStringArray());
}
@@ -911,7 +966,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntryInfo
}
auto arr = nt::GetEntryInfo(inst, JStringRef{env, prefix}.str(), types);
jobjectArray jarr = env->NewObjectArray(arr.size(), entryInfoCls, nullptr);
if (!jarr) return nullptr;
if (!jarr) {
return nullptr;
}
for (size_t i = 0; i < arr.size(); ++i) {
JLocal<jobject> jelem{env, MakeJObject(env, instObject, arr[i])};
env->SetObjectArrayElement(jarr, i, jelem);
@@ -1291,7 +1348,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getRpcResult__II
(JNIEnv* env, jclass, jint entry, jint call)
{
std::string result;
if (!nt::GetRpcResult(entry, call, &result)) return nullptr;
if (!nt::GetRpcResult(entry, call, &result)) {
return nullptr;
}
return MakeJByteArray(env, result);
}
@@ -1306,8 +1365,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getRpcResult__IID
{
std::string result;
bool timed_out = false;
if (!nt::GetRpcResult(entry, call, &result, timeout, &timed_out))
if (!nt::GetRpcResult(entry, call, &result, timeout, &timed_out)) {
return nullptr;
}
return MakeJByteArray(env, result);
}
@@ -1333,7 +1393,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getRpc
(JNIEnv* env, jclass, jint entry, jbyteArray defaultValue)
{
auto val = nt::GetEntryValue(entry);
if (!val || !val->IsRpc()) return defaultValue;
if (!val || !val->IsRpc()) {
return defaultValue;
}
return MakeJByteArray(env, val->GetRpc());
}
@@ -1475,7 +1537,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_startClient__I_3Ljava_lang_Str
return;
}
jint* portInts = env->GetIntArrayElements(ports, nullptr);
if (!portInts) return;
if (!portInts) {
return;
}
std::vector<std::string> names;
std::vector<std::pair<nt::StringRef, unsigned int>> servers;
@@ -1560,7 +1624,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setServer__I_3Ljava_lang_Strin
return;
}
jint* portInts = env->GetIntArrayElements(ports, nullptr);
if (!portInts) return;
if (!portInts) {
return;
}
std::vector<std::string> names;
std::vector<std::pair<nt::StringRef, unsigned int>> servers;
@@ -1653,7 +1719,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_getConnections
auto arr = nt::GetConnections(inst);
jobjectArray jarr =
env->NewObjectArray(arr.size(), connectionInfoCls, nullptr);
if (!jarr) return nullptr;
if (!jarr) {
return nullptr;
}
for (size_t i = 0; i < arr.size(); ++i) {
JLocal<jobject> jelem{env, MakeJObject(env, arr[i])};
env->SetObjectArrayElement(jarr, i, jelem);
@@ -1687,7 +1755,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_savePersistent
return;
}
const char* err = nt::SavePersistent(inst, JStringRef{env, filename}.str());
if (err) persistentEx.Throw(env, err);
if (err) {
persistentEx.Throw(env, err);
}
}
/*
@@ -1737,7 +1807,9 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_saveEntries
}
const char* err = nt::SaveEntries(inst, JStringRef{env, filename}.str(),
JStringRef{env, prefix}.str());
if (err) persistentEx.Throw(env, err);
if (err) {
persistentEx.Throw(env, err);
}
}
/*

View File

@@ -31,7 +31,9 @@ unsigned int NetworkTable::s_port = NT_DEFAULT_PORT;
StringRef NetworkTable::BasenameKey(StringRef key) {
size_t slash = key.rfind(PATH_SEPARATOR_CHAR);
if (slash == StringRef::npos) return key;
if (slash == StringRef::npos) {
return key;
}
return key.substr(slash + 1);
}
@@ -45,7 +47,9 @@ StringRef NetworkTable::NormalizeKey(const Twine& key,
wpi::SmallVectorImpl<char>& buf,
bool withLeadingSlash) {
buf.clear();
if (withLeadingSlash) buf.push_back(PATH_SEPARATOR_CHAR);
if (withLeadingSlash) {
buf.push_back(PATH_SEPARATOR_CHAR);
}
// for each path element, add it with a slash following
wpi::SmallString<128> keyBuf;
StringRef keyStr = key.toStringRef(keyBuf);
@@ -56,7 +60,9 @@ StringRef NetworkTable::NormalizeKey(const Twine& key,
buf.push_back(PATH_SEPARATOR_CHAR);
}
// remove trailing slash if the input key didn't have one
if (!keyStr.empty() && keyStr.back() != PATH_SEPARATOR_CHAR) buf.pop_back();
if (!keyStr.empty() && keyStr.back() != PATH_SEPARATOR_CHAR) {
buf.pop_back();
}
return StringRef(buf.data(), buf.size());
}
@@ -85,11 +91,15 @@ std::vector<std::string> NetworkTable::GetHierarchy(const Twine& key) {
}
void NetworkTable::Initialize() {
if (s_running) Shutdown();
if (s_running) {
Shutdown();
}
auto inst = NetworkTableInstance::GetDefault();
if (s_client) {
inst.StartClient();
if (s_enable_ds) inst.StartDSClient(s_port);
if (s_enable_ds) {
inst.StartDSClient(s_port);
}
} else {
inst.StartServer(s_persistent_filename, "", s_port);
}
@@ -97,7 +107,9 @@ void NetworkTable::Initialize() {
}
void NetworkTable::Shutdown() {
if (!s_running) return;
if (!s_running) {
return;
}
auto inst = NetworkTableInstance::GetDefault();
if (s_client) {
inst.StopDSClient();
@@ -108,14 +120,20 @@ void NetworkTable::Shutdown() {
s_running = false;
}
void NetworkTable::SetClientMode() { s_client = true; }
void NetworkTable::SetClientMode() {
s_client = true;
}
void NetworkTable::SetServerMode() { s_client = false; }
void NetworkTable::SetServerMode() {
s_client = false;
}
void NetworkTable::SetTeam(int team) {
auto inst = NetworkTableInstance::GetDefault();
inst.SetServerTeam(team, s_port);
if (s_enable_ds) inst.StartDSClient(s_port);
if (s_enable_ds) {
inst.StartDSClient(s_port);
}
}
void NetworkTable::SetIPAddress(StringRef address) {
@@ -124,35 +142,42 @@ void NetworkTable::SetIPAddress(StringRef address) {
inst.SetServer(addr_copy.c_str(), s_port);
// Stop the DS client if we're explicitly connecting to localhost
if (address == "localhost" || address == "127.0.0.1")
if (address == "localhost" || address == "127.0.0.1") {
inst.StopDSClient();
else if (s_enable_ds)
} else if (s_enable_ds) {
inst.StartDSClient(s_port);
}
}
void NetworkTable::SetIPAddress(ArrayRef<std::string> addresses) {
auto inst = NetworkTableInstance::GetDefault();
wpi::SmallVector<StringRef, 8> servers;
for (const auto& ip_address : addresses) servers.emplace_back(ip_address);
for (const auto& ip_address : addresses) {
servers.emplace_back(ip_address);
}
inst.SetServer(servers, s_port);
// Stop the DS client if we're explicitly connecting to localhost
if (!addresses.empty() &&
(addresses[0] == "localhost" || addresses[0] == "127.0.0.1"))
(addresses[0] == "localhost" || addresses[0] == "127.0.0.1")) {
inst.StopDSClient();
else if (s_enable_ds)
} else if (s_enable_ds) {
inst.StartDSClient(s_port);
}
}
void NetworkTable::SetPort(unsigned int port) { s_port = port; }
void NetworkTable::SetPort(unsigned int port) {
s_port = port;
}
void NetworkTable::SetDSClientEnabled(bool enabled) {
auto inst = NetworkTableInstance::GetDefault();
s_enable_ds = enabled;
if (s_enable_ds)
if (s_enable_ds) {
inst.StartDSClient(s_port);
else
} else {
inst.StopDSClient();
}
}
void NetworkTable::SetPersistentFilename(StringRef filename) {
@@ -167,7 +192,9 @@ void NetworkTable::GlobalDeleteAll() {
NetworkTableInstance::GetDefault().DeleteAllEntries();
}
void NetworkTable::Flush() { NetworkTableInstance::GetDefault().Flush(); }
void NetworkTable::Flush() {
NetworkTableInstance::GetDefault().Flush();
}
void NetworkTable::SetUpdateRate(double interval) {
NetworkTableInstance::GetDefault().SetUpdateRate(interval);
@@ -184,7 +211,9 @@ const char* NetworkTable::LoadPersistent(
}
std::shared_ptr<NetworkTable> NetworkTable::GetTable(StringRef key) {
if (!s_running) Initialize();
if (!s_running) {
Initialize();
}
return NetworkTableInstance::GetDefault().GetTable(key);
}
@@ -192,8 +221,12 @@ NetworkTable::NetworkTable(NT_Inst inst, const Twine& path, const private_init&)
: m_inst(inst), m_path(path.str()) {}
NetworkTable::~NetworkTable() {
for (auto& i : m_listeners) RemoveEntryListener(i.second);
for (auto i : m_lambdaListeners) RemoveEntryListener(i);
for (auto& i : m_listeners) {
RemoveEntryListener(i.second);
}
for (auto i : m_lambdaListeners) {
RemoveEntryListener(i);
}
}
NetworkTableInstance NetworkTable::GetInstance() const {
@@ -218,7 +251,9 @@ NT_EntryListener NetworkTable::AddEntryListener(TableEntryListener listener,
m_inst, m_path + Twine(PATH_SEPARATOR_CHAR),
[=](const EntryNotification& event) {
StringRef relative_key = event.name.substr(prefix_len);
if (relative_key.find(PATH_SEPARATOR_CHAR) != StringRef::npos) return;
if (relative_key.find(PATH_SEPARATOR_CHAR) != StringRef::npos) {
return;
}
listener(const_cast<NetworkTable*>(this), relative_key,
NetworkTableEntry{event.entry}, event.value, event.flags);
},
@@ -250,7 +285,9 @@ void NetworkTable::AddTableListener(ITableListener* listener) {
void NetworkTable::AddTableListener(ITableListener* listener,
bool immediateNotify) {
unsigned int flags = NT_NOTIFY_NEW | NT_NOTIFY_UPDATE;
if (immediateNotify) flags |= NT_NOTIFY_IMMEDIATE;
if (immediateNotify) {
flags |= NT_NOTIFY_IMMEDIATE;
}
AddTableListenerEx(listener, flags);
}
@@ -264,7 +301,9 @@ void NetworkTable::AddTableListenerEx(ITableListener* listener,
m_inst, path,
[=](const EntryNotification& event) {
StringRef relative_key = event.name.substr(prefix_len);
if (relative_key.find(PATH_SEPARATOR_CHAR) != StringRef::npos) return;
if (relative_key.find(PATH_SEPARATOR_CHAR) != StringRef::npos) {
return;
}
listener->ValueChangedEx(this, relative_key, event.value, event.flags);
},
flags);
@@ -274,7 +313,9 @@ void NetworkTable::AddTableListenerEx(ITableListener* listener,
void NetworkTable::AddTableListener(StringRef key, ITableListener* listener,
bool immediateNotify) {
unsigned int flags = NT_NOTIFY_NEW | NT_NOTIFY_UPDATE;
if (immediateNotify) flags |= NT_NOTIFY_IMMEDIATE;
if (immediateNotify) {
flags |= NT_NOTIFY_IMMEDIATE;
}
AddTableListenerEx(key, listener, flags);
}
@@ -306,16 +347,21 @@ NT_EntryListener NetworkTable::AddSubTableListener(TableListener listener,
auto notified_tables = std::make_shared<wpi::StringMap<char>>();
unsigned int flags = NT_NOTIFY_NEW | NT_NOTIFY_IMMEDIATE;
if (localNotify) flags |= NT_NOTIFY_LOCAL;
if (localNotify) {
flags |= NT_NOTIFY_LOCAL;
}
NT_EntryListener id = nt::AddEntryListener(
m_inst, m_path + Twine(PATH_SEPARATOR_CHAR),
[=](const EntryNotification& event) {
StringRef relative_key = event.name.substr(prefix_len);
auto end_sub_table = relative_key.find(PATH_SEPARATOR_CHAR);
if (end_sub_table == StringRef::npos) return;
StringRef sub_table_key = relative_key.substr(0, end_sub_table);
if (notified_tables->find(sub_table_key) == notified_tables->end())
if (end_sub_table == StringRef::npos) {
return;
}
StringRef sub_table_key = relative_key.substr(0, end_sub_table);
if (notified_tables->find(sub_table_key) == notified_tables->end()) {
return;
}
notified_tables->insert(std::make_pair(sub_table_key, '\0'));
listener(this, sub_table_key, this->GetSubTable(sub_table_key));
},
@@ -341,16 +387,21 @@ void NetworkTable::AddSubTableListener(ITableListener* listener,
auto notified_tables = std::make_shared<wpi::StringMap<char>>();
unsigned int flags = NT_NOTIFY_NEW | NT_NOTIFY_IMMEDIATE;
if (localNotify) flags |= NT_NOTIFY_LOCAL;
if (localNotify) {
flags |= NT_NOTIFY_LOCAL;
}
NT_EntryListener id = nt::AddEntryListener(
m_inst, m_path + Twine(PATH_SEPARATOR_CHAR),
[=](const EntryNotification& event) {
StringRef relative_key = event.name.substr(prefix_len);
auto end_sub_table = relative_key.find(PATH_SEPARATOR_CHAR);
if (end_sub_table == StringRef::npos) return;
StringRef sub_table_key = relative_key.substr(0, end_sub_table);
if (notified_tables->find(sub_table_key) == notified_tables->end())
if (end_sub_table == StringRef::npos) {
return;
}
StringRef sub_table_key = relative_key.substr(0, end_sub_table);
if (notified_tables->find(sub_table_key) == notified_tables->end()) {
return;
}
notified_tables->insert(std::make_pair(sub_table_key, '\0'));
listener->ValueChangedEx(this, sub_table_key, nullptr, event.flags);
},
@@ -364,8 +415,9 @@ void NetworkTable::RemoveTableListener(ITableListener* listener) {
std::remove_if(m_listeners.begin(), m_listeners.end(),
[=](const Listener& x) { return x.first == listener; });
for (auto i = matches_begin; i != m_listeners.end(); ++i)
for (auto i = matches_begin; i != m_listeners.end(); ++i) {
RemoveEntryListener(i->second);
}
m_listeners.erase(matches_begin, m_listeners.end());
}
@@ -377,8 +429,9 @@ std::shared_ptr<NetworkTable> NetworkTable::GetSubTable(
bool NetworkTable::ContainsKey(const Twine& key) const {
if (key.isTriviallyEmpty() ||
(key.isSingleStringRef() && key.getSingleStringRef().empty()))
(key.isSingleStringRef() && key.getSingleStringRef().empty())) {
return false;
}
return GetEntry(key).Exists();
}
@@ -397,7 +450,9 @@ std::vector<std::string> NetworkTable::GetKeys(int types) const {
std::scoped_lock lock(m_mutex);
for (auto& info : infos) {
auto relative_key = StringRef(info.name).substr(prefix_len);
if (relative_key.find(PATH_SEPARATOR_CHAR) != StringRef::npos) continue;
if (relative_key.find(PATH_SEPARATOR_CHAR) != StringRef::npos) {
continue;
}
keys.push_back(relative_key);
m_entries[relative_key] = info.entry;
}
@@ -411,7 +466,9 @@ std::vector<std::string> NetworkTable::GetSubTables() const {
GetEntryInfo(m_inst, m_path + Twine(PATH_SEPARATOR_CHAR), 0)) {
auto relative_key = StringRef(entry.name).substr(prefix_len);
size_t end_subtable = relative_key.find(PATH_SEPARATOR_CHAR);
if (end_subtable == StringRef::npos) continue;
if (end_subtable == StringRef::npos) {
continue;
}
keys.push_back(relative_key.substr(0, end_subtable));
}
return keys;
@@ -441,7 +498,9 @@ unsigned int NetworkTable::GetFlags(StringRef key) const {
return GetEntry(key).GetFlags();
}
void NetworkTable::Delete(const Twine& key) { GetEntry(key).Delete(); }
void NetworkTable::Delete(const Twine& key) {
GetEntry(key).Delete();
}
bool NetworkTable::PutNumber(StringRef key, double value) {
return GetEntry(key).SetDouble(value);
@@ -547,7 +606,9 @@ std::shared_ptr<Value> NetworkTable::GetValue(const Twine& key) const {
return GetEntry(key).GetValue();
}
StringRef NetworkTable::GetPath() const { return m_path; }
StringRef NetworkTable::GetPath() const {
return m_path;
}
const char* NetworkTable::SaveEntries(const Twine& filename) const {
return nt::SaveEntries(m_inst, filename, m_path + Twine(PATH_SEPARATOR_CHAR));

View File

@@ -12,7 +12,9 @@ std::shared_ptr<NetworkTable> NetworkTableInstance::GetTable(
const Twine& key) const {
StringRef simple;
bool isSimple = key.isSingleStringRef();
if (isSimple) simple = key.getSingleStringRef();
if (isSimple) {
simple = key.getSingleStringRef();
}
if (isSimple && (simple.empty() || simple == "/")) {
return std::make_shared<NetworkTable>(m_handle, "",
NetworkTable::private_init{});
@@ -29,16 +31,18 @@ std::shared_ptr<NetworkTable> NetworkTableInstance::GetTable(
void NetworkTableInstance::StartClient(ArrayRef<StringRef> servers,
unsigned int port) {
wpi::SmallVector<std::pair<StringRef, unsigned int>, 8> server_ports;
for (const auto& server : servers)
for (const auto& server : servers) {
server_ports.emplace_back(std::make_pair(server, port));
}
StartClient(server_ports);
}
void NetworkTableInstance::SetServer(ArrayRef<StringRef> servers,
unsigned int port) {
wpi::SmallVector<std::pair<StringRef, unsigned int>, 8> server_ports;
for (const auto& server : servers)
for (const auto& server : servers) {
server_ports.emplace_back(std::make_pair(server, port));
}
SetServer(server_ports);
}

View File

@@ -56,14 +56,16 @@ static void ConvertToC(const RpcDefinition& in, NT_RpcDefinition* out) {
out->num_params = in.params.size();
out->params = static_cast<NT_RpcParamDef*>(
wpi::safe_malloc(in.params.size() * sizeof(NT_RpcParamDef)));
for (size_t i = 0; i < in.params.size(); ++i)
for (size_t i = 0; i < in.params.size(); ++i) {
ConvertToC(in.params[i], &out->params[i]);
}
out->num_results = in.results.size();
out->results = static_cast<NT_RpcResultDef*>(
wpi::safe_malloc(in.results.size() * sizeof(NT_RpcResultDef)));
for (size_t i = 0; i < in.results.size(); ++i)
for (size_t i = 0; i < in.results.size(); ++i) {
ConvertToC(in.results[i], &out->results[i]);
}
}
static void ConvertToC(const RpcAnswer& in, NT_RpcAnswer* out) {
@@ -99,11 +101,17 @@ static void ConvertToC(const LogMessage& in, NT_LogMessage* out) {
template <typename O, typename I>
static O* ConvertToC(const std::vector<I>& in, size_t* out_len) {
if (!out_len) return nullptr;
if (!out_len) {
return nullptr;
}
*out_len = in.size();
if (in.empty()) return nullptr;
if (in.empty()) {
return nullptr;
}
O* out = static_cast<O*>(wpi::safe_malloc(sizeof(O) * in.size()));
for (size_t i = 0; i < in.size(); ++i) ConvertToC(in[i], &out[i]);
for (size_t i = 0; i < in.size(); ++i) {
ConvertToC(in[i], &out[i]);
}
return out;
}
@@ -112,7 +120,9 @@ static void DisposeConnectionInfo(NT_ConnectionInfo* info) {
std::free(info->remote_ip.str);
}
static void DisposeEntryInfo(NT_EntryInfo* info) { std::free(info->name.str); }
static void DisposeEntryInfo(NT_EntryInfo* info) {
std::free(info->name.str);
}
static void DisposeEntryNotification(NT_EntryNotification* info) {
std::free(info->name.str);
@@ -143,12 +153,14 @@ static RpcDefinition ConvertFromC(const NT_RpcDefinition& in) {
out.name = ConvertFromC(in.name);
out.params.reserve(in.num_params);
for (size_t i = 0; i < in.num_params; ++i)
for (size_t i = 0; i < in.num_params; ++i) {
out.params.push_back(ConvertFromC(in.params[i]));
}
out.results.reserve(in.num_results);
for (size_t i = 0; i < in.num_results; ++i)
for (size_t i = 0; i < in.num_results; ++i) {
out.results.push_back(ConvertFromC(in.results[i]));
}
return out;
}
@@ -159,11 +171,17 @@ extern "C" {
* Instance Functions
*/
NT_Inst NT_GetDefaultInstance(void) { return nt::GetDefaultInstance(); }
NT_Inst NT_GetDefaultInstance(void) {
return nt::GetDefaultInstance();
}
NT_Inst NT_CreateInstance(void) { return nt::CreateInstance(); }
NT_Inst NT_CreateInstance(void) {
return nt::CreateInstance();
}
void NT_DestroyInstance(NT_Inst inst) { return nt::DestroyInstance(inst); }
void NT_DestroyInstance(NT_Inst inst) {
return nt::DestroyInstance(inst);
}
NT_Inst NT_GetInstanceFromHandle(NT_Handle handle) {
return nt::GetInstanceFromHandle(handle);
@@ -181,7 +199,9 @@ NT_Entry* NT_GetEntries(NT_Inst inst, const char* prefix, size_t prefix_len,
unsigned int types, size_t* count) {
auto info_v = nt::GetEntries(inst, StringRef(prefix, prefix_len), types);
*count = info_v.size();
if (info_v.size() == 0) return nullptr;
if (info_v.size() == 0) {
return nullptr;
}
// create array and copy into it
NT_Entry* info = static_cast<NT_Entry*>(
@@ -197,7 +217,9 @@ char* NT_GetEntryName(NT_Entry entry, size_t* name_len) {
return v_name.str;
}
enum NT_Type NT_GetEntryType(NT_Entry entry) { return nt::GetEntryType(entry); }
enum NT_Type NT_GetEntryType(NT_Entry entry) {
return nt::GetEntryType(entry);
}
uint64_t NT_GetEntryLastChange(NT_Entry entry) {
return nt::GetEntryLastChange(entry);
@@ -206,7 +228,9 @@ uint64_t NT_GetEntryLastChange(NT_Entry entry) {
void NT_GetEntryValue(NT_Entry entry, struct NT_Value* value) {
NT_InitValue(value);
auto v = nt::GetEntryValue(entry);
if (!v) return;
if (!v) {
return;
}
ConvertToC(*v, value);
}
@@ -231,9 +255,13 @@ unsigned int NT_GetEntryFlags(NT_Entry entry) {
return nt::GetEntryFlags(entry);
}
void NT_DeleteEntry(NT_Entry entry) { nt::DeleteEntry(entry); }
void NT_DeleteEntry(NT_Entry entry) {
nt::DeleteEntry(entry);
}
void NT_DeleteAllEntries(NT_Inst inst) { nt::DeleteAllEntries(inst); }
void NT_DeleteAllEntries(NT_Inst inst) {
nt::DeleteAllEntries(inst);
}
struct NT_EntryInfo* NT_GetEntryInfo(NT_Inst inst, const char* prefix,
size_t prefix_len, unsigned int types,
@@ -244,7 +272,9 @@ struct NT_EntryInfo* NT_GetEntryInfo(NT_Inst inst, const char* prefix,
NT_Bool NT_GetEntryInfoHandle(NT_Entry entry, struct NT_EntryInfo* info) {
auto info_v = nt::GetEntryInfo(entry);
if (info_v.name.empty()) return false;
if (info_v.name.empty()) {
return false;
}
ConvertToC(info_v, info);
return true;
}
@@ -425,7 +455,9 @@ NT_RpcAnswer* NT_PollRpcTimeout(NT_RpcCallPoller poller, size_t* len,
return ConvertToC<NT_RpcAnswer>(arr_cpp, len);
}
void NT_CancelPollRpc(NT_RpcCallPoller poller) { nt::CancelPollRpc(poller); }
void NT_CancelPollRpc(NT_RpcCallPoller poller) {
nt::CancelPollRpc(poller);
}
NT_Bool NT_WaitForRpcCallQueue(NT_Inst inst, double timeout) {
return nt::WaitForRpcCallQueue(inst, timeout);
@@ -442,7 +474,9 @@ NT_RpcCall NT_CallRpc(NT_Entry entry, const char* params, size_t params_len) {
char* NT_GetRpcResult(NT_Entry entry, NT_RpcCall call, size_t* result_len) {
std::string result;
if (!nt::GetRpcResult(entry, call, &result)) return nullptr;
if (!nt::GetRpcResult(entry, call, &result)) {
return nullptr;
}
// convert result
*result_len = result.size();
@@ -486,7 +520,9 @@ char* NT_PackRpcDefinition(const NT_RpcDefinition* def, size_t* packed_len) {
NT_Bool NT_UnpackRpcDefinition(const char* packed, size_t packed_len,
NT_RpcDefinition* def) {
nt::RpcDefinition def_v;
if (!nt::UnpackRpcDefinition(StringRef(packed, packed_len), &def_v)) return 0;
if (!nt::UnpackRpcDefinition(StringRef(packed, packed_len), &def_v)) {
return 0;
}
// convert result
ConvertToC(def_v, def);
@@ -498,8 +534,9 @@ char* NT_PackRpcValues(const NT_Value** values, size_t values_len,
// create input vector
std::vector<std::shared_ptr<Value>> values_v;
values_v.reserve(values_len);
for (size_t i = 0; i < values_len; ++i)
for (size_t i = 0; i < values_len; ++i) {
values_v.push_back(ConvertFromC(*values[i]));
}
// make the call
auto packed = nt::PackRpcValues(values_v);
@@ -515,7 +552,9 @@ NT_Value** NT_UnpackRpcValues(const char* packed, size_t packed_len,
const NT_Type* types, size_t types_len) {
auto values_v = nt::UnpackRpcValues(StringRef(packed, packed_len),
ArrayRef<NT_Type>(types, types_len));
if (values_v.size() == 0) return nullptr;
if (values_v.size() == 0) {
return nullptr;
}
// create array and copy into it
NT_Value** values = static_cast<NT_Value**>(
@@ -539,18 +578,26 @@ unsigned int NT_GetNetworkMode(NT_Inst inst) {
return nt::GetNetworkMode(inst);
}
void NT_StartLocal(NT_Inst inst) { nt::StartLocal(inst); }
void NT_StartLocal(NT_Inst inst) {
nt::StartLocal(inst);
}
void NT_StopLocal(NT_Inst inst) { nt::StopLocal(inst); }
void NT_StopLocal(NT_Inst inst) {
nt::StopLocal(inst);
}
void NT_StartServer(NT_Inst inst, const char* persist_filename,
const char* listen_address, unsigned int port) {
nt::StartServer(inst, persist_filename, listen_address, port);
}
void NT_StopServer(NT_Inst inst) { nt::StopServer(inst); }
void NT_StopServer(NT_Inst inst) {
nt::StopServer(inst);
}
void NT_StartClientNone(NT_Inst inst) { nt::StartClient(inst); }
void NT_StartClientNone(NT_Inst inst) {
nt::StartClient(inst);
}
void NT_StartClient(NT_Inst inst, const char* server_name, unsigned int port) {
nt::StartClient(inst, server_name, port);
@@ -560,8 +607,9 @@ void NT_StartClientMulti(NT_Inst inst, size_t count, const char** server_names,
const unsigned int* ports) {
std::vector<std::pair<StringRef, unsigned int>> servers;
servers.reserve(count);
for (size_t i = 0; i < count; ++i)
for (size_t i = 0; i < count; ++i) {
servers.emplace_back(std::make_pair(server_names[i], ports[i]));
}
nt::StartClient(inst, servers);
}
@@ -569,7 +617,9 @@ void NT_StartClientTeam(NT_Inst inst, unsigned int team, unsigned int port) {
nt::StartClientTeam(inst, team, port);
}
void NT_StopClient(NT_Inst inst) { nt::StopClient(inst); }
void NT_StopClient(NT_Inst inst) {
nt::StopClient(inst);
}
void NT_SetServer(NT_Inst inst, const char* server_name, unsigned int port) {
nt::SetServer(inst, server_name, port);
@@ -579,8 +629,9 @@ void NT_SetServerMulti(NT_Inst inst, size_t count, const char** server_names,
const unsigned int* ports) {
std::vector<std::pair<StringRef, unsigned int>> servers;
servers.reserve(count);
for (size_t i = 0; i < count; ++i)
for (size_t i = 0; i < count; ++i) {
servers.emplace_back(std::make_pair(server_names[i], ports[i]));
}
nt::SetServer(inst, servers);
}
@@ -592,15 +643,21 @@ void NT_StartDSClient(NT_Inst inst, unsigned int port) {
nt::StartDSClient(inst, port);
}
void NT_StopDSClient(NT_Inst inst) { nt::StopDSClient(inst); }
void NT_StopDSClient(NT_Inst inst) {
nt::StopDSClient(inst);
}
void NT_SetUpdateRate(NT_Inst inst, double interval) {
nt::SetUpdateRate(inst, interval);
}
void NT_Flush(NT_Inst inst) { nt::Flush(inst); }
void NT_Flush(NT_Inst inst) {
nt::Flush(inst);
}
NT_Bool NT_IsConnected(NT_Inst inst) { return nt::IsConnected(inst); }
NT_Bool NT_IsConnected(NT_Inst inst) {
return nt::IsConnected(inst);
}
struct NT_ConnectionInfo* NT_GetConnections(NT_Inst inst, size_t* count) {
auto conn_v = nt::GetConnections(inst);
@@ -635,7 +692,9 @@ const char* NT_LoadEntries(NT_Inst inst, const char* filename,
* Utility Functions
*/
uint64_t NT_Now(void) { return wpi::Now(); }
uint64_t NT_Now(void) {
return wpi::Now();
}
NT_Logger NT_AddLogger(NT_Inst inst, void* data, NT_LogFunc func,
unsigned int min_level, unsigned int max_level) {
@@ -680,7 +739,9 @@ void NT_CancelPollLogger(NT_LoggerPoller poller) {
nt::CancelPollLogger(poller);
}
void NT_RemoveLogger(NT_Logger logger) { nt::RemoveLogger(logger); }
void NT_RemoveLogger(NT_Logger logger) {
nt::RemoveLogger(logger);
}
NT_Bool NT_WaitForLoggerQueue(NT_Inst inst, double timeout) {
return nt::WaitForLoggerQueue(inst, timeout);
@@ -704,8 +765,9 @@ void NT_DisposeValue(NT_Value* value) {
std::free(value->data.arr_double.arr);
break;
case NT_STRING_ARRAY: {
for (size_t i = 0; i < value->data.arr_string.size; i++)
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;
}
@@ -732,22 +794,32 @@ void NT_InitString(NT_String* str) {
str->len = 0;
}
void NT_DisposeEntryArray(NT_Entry* arr, size_t /*count*/) { std::free(arr); }
void NT_DisposeEntryArray(NT_Entry* arr, size_t /*count*/) {
std::free(arr);
}
void NT_DisposeConnectionInfoArray(NT_ConnectionInfo* arr, size_t count) {
for (size_t i = 0; i < count; i++) DisposeConnectionInfo(&arr[i]);
for (size_t i = 0; i < count; i++) {
DisposeConnectionInfo(&arr[i]);
}
std::free(arr);
}
void NT_DisposeEntryInfoArray(NT_EntryInfo* arr, size_t count) {
for (size_t i = 0; i < count; i++) DisposeEntryInfo(&arr[i]);
for (size_t i = 0; i < count; i++) {
DisposeEntryInfo(&arr[i]);
}
std::free(arr);
}
void NT_DisposeEntryInfo(NT_EntryInfo* info) { DisposeEntryInfo(info); }
void NT_DisposeEntryInfo(NT_EntryInfo* info) {
DisposeEntryInfo(info);
}
void NT_DisposeEntryNotificationArray(NT_EntryNotification* arr, size_t count) {
for (size_t i = 0; i < count; i++) DisposeEntryNotification(&arr[i]);
for (size_t i = 0; i < count; i++) {
DisposeEntryNotification(&arr[i]);
}
std::free(arr);
}
@@ -757,7 +829,9 @@ void NT_DisposeEntryNotification(NT_EntryNotification* info) {
void NT_DisposeConnectionNotificationArray(NT_ConnectionNotification* arr,
size_t count) {
for (size_t i = 0; i < count; i++) DisposeConnectionNotification(&arr[i]);
for (size_t i = 0; i < count; i++) {
DisposeConnectionNotification(&arr[i]);
}
std::free(arr);
}
@@ -766,11 +840,15 @@ void NT_DisposeConnectionNotification(NT_ConnectionNotification* info) {
}
void NT_DisposeLogMessageArray(NT_LogMessage* arr, size_t count) {
for (size_t i = 0; i < count; i++) NT_DisposeLogMessage(&arr[i]);
for (size_t i = 0; i < count; i++) {
NT_DisposeLogMessage(&arr[i]);
}
std::free(arr);
}
void NT_DisposeLogMessage(NT_LogMessage* info) { std::free(info->message); }
void NT_DisposeLogMessage(NT_LogMessage* info) {
std::free(info->message);
}
void NT_DisposeRpcDefinition(NT_RpcDefinition* def) {
NT_DisposeString(&def->name);
@@ -783,15 +861,18 @@ void NT_DisposeRpcDefinition(NT_RpcDefinition* def) {
def->params = nullptr;
def->num_params = 0;
for (size_t i = 0; i < def->num_results; ++i)
for (size_t i = 0; i < def->num_results; ++i) {
NT_DisposeString(&def->results[i].name);
}
std::free(def->results);
def->results = nullptr;
def->num_results = 0;
}
void NT_DisposeRpcAnswerArray(NT_RpcAnswer* arr, size_t count) {
for (size_t i = 0; i < count; i++) NT_DisposeRpcAnswer(&arr[i]);
for (size_t i = 0; i < count; i++) {
NT_DisposeRpcAnswer(&arr[i]);
}
std::free(arr);
}
@@ -831,11 +912,19 @@ struct NT_String* NT_AllocateStringArray(size_t size) {
return retVal;
}
void NT_FreeCharArray(char* v_char) { std::free(v_char); }
void NT_FreeDoubleArray(double* v_double) { std::free(v_double); }
void NT_FreeBooleanArray(int* v_boolean) { std::free(v_boolean); }
void NT_FreeCharArray(char* v_char) {
std::free(v_char);
}
void NT_FreeDoubleArray(double* v_double) {
std::free(v_double);
}
void NT_FreeBooleanArray(int* v_boolean) {
std::free(v_boolean);
}
void NT_FreeStringArray(struct NT_String* v_string, size_t arr_size) {
for (size_t i = 0; i < arr_size; i++) std::free(v_string[i].str);
for (size_t i = 0; i < arr_size; i++) {
std::free(v_string[i].str);
}
std::free(v_string);
}
@@ -912,7 +1001,9 @@ NT_Bool NT_SetEntryStringArray(NT_Entry entry, uint64_t time,
NT_Bool force) {
std::vector<std::string> v;
v.reserve(size);
for (size_t i = 0; i < size; ++i) v.push_back(ConvertFromC(arr[i]));
for (size_t i = 0; i < size; ++i) {
v.push_back(ConvertFromC(arr[i]));
}
if (force != 0) {
nt::SetEntryTypeValue(entry, Value::MakeStringArray(std::move(v), time));
@@ -923,13 +1014,17 @@ NT_Bool NT_SetEntryStringArray(NT_Entry entry, uint64_t time,
}
enum NT_Type NT_GetValueType(const struct NT_Value* value) {
if (!value) return NT_Type::NT_UNASSIGNED;
if (!value) {
return NT_Type::NT_UNASSIGNED;
}
return value->type;
}
NT_Bool NT_GetValueBoolean(const struct NT_Value* value, uint64_t* last_change,
NT_Bool* v_boolean) {
if (!value || value->type != NT_Type::NT_BOOLEAN) return 0;
if (!value || value->type != NT_Type::NT_BOOLEAN) {
return 0;
}
*v_boolean = value->data.v_boolean;
*last_change = value->last_change;
return 1;
@@ -937,7 +1032,9 @@ NT_Bool NT_GetValueBoolean(const struct NT_Value* value, uint64_t* last_change,
NT_Bool NT_GetValueDouble(const struct NT_Value* value, uint64_t* last_change,
double* v_double) {
if (!value || value->type != NT_Type::NT_DOUBLE) return 0;
if (!value || value->type != NT_Type::NT_DOUBLE) {
return 0;
}
*last_change = value->last_change;
*v_double = value->data.v_double;
return 1;
@@ -945,7 +1042,9 @@ NT_Bool NT_GetValueDouble(const struct NT_Value* value, uint64_t* last_change,
char* NT_GetValueString(const struct NT_Value* value, uint64_t* last_change,
size_t* str_len) {
if (!value || value->type != NT_Type::NT_STRING) return nullptr;
if (!value || value->type != NT_Type::NT_STRING) {
return nullptr;
}
*last_change = value->last_change;
*str_len = value->data.v_string.len;
char* str =
@@ -956,7 +1055,9 @@ char* NT_GetValueString(const struct NT_Value* value, uint64_t* last_change,
char* NT_GetValueRaw(const struct NT_Value* value, uint64_t* last_change,
size_t* raw_len) {
if (!value || value->type != NT_Type::NT_RAW) return nullptr;
if (!value || value->type != NT_Type::NT_RAW) {
return nullptr;
}
*last_change = value->last_change;
*raw_len = value->data.v_string.len;
char* raw =
@@ -967,7 +1068,9 @@ char* NT_GetValueRaw(const struct NT_Value* value, uint64_t* last_change,
NT_Bool* NT_GetValueBooleanArray(const struct NT_Value* value,
uint64_t* last_change, size_t* arr_size) {
if (!value || value->type != NT_Type::NT_BOOLEAN_ARRAY) return nullptr;
if (!value || value->type != NT_Type::NT_BOOLEAN_ARRAY) {
return nullptr;
}
*last_change = value->last_change;
*arr_size = value->data.arr_boolean.size;
NT_Bool* arr = static_cast<int*>(
@@ -979,7 +1082,9 @@ NT_Bool* NT_GetValueBooleanArray(const struct NT_Value* value,
double* NT_GetValueDoubleArray(const struct NT_Value* value,
uint64_t* last_change, size_t* arr_size) {
if (!value || value->type != NT_Type::NT_DOUBLE_ARRAY) return nullptr;
if (!value || value->type != NT_Type::NT_DOUBLE_ARRAY) {
return nullptr;
}
*last_change = value->last_change;
*arr_size = value->data.arr_double.size;
double* arr = static_cast<double*>(
@@ -991,7 +1096,9 @@ double* NT_GetValueDoubleArray(const struct NT_Value* value,
NT_String* NT_GetValueStringArray(const struct NT_Value* value,
uint64_t* last_change, size_t* arr_size) {
if (!value || value->type != NT_Type::NT_STRING_ARRAY) return nullptr;
if (!value || value->type != NT_Type::NT_STRING_ARRAY) {
return nullptr;
}
*last_change = value->last_change;
*arr_size = value->data.arr_string.size;
NT_String* arr = static_cast<NT_String*>(
@@ -1051,8 +1158,9 @@ NT_Bool NT_SetDefaultEntryStringArray(NT_Entry entry, uint64_t time,
size_t default_size) {
std::vector<std::string> vec;
vec.reserve(default_size);
for (size_t i = 0; i < default_size; ++i)
for (size_t i = 0; i < default_size; ++i) {
vec.push_back(ConvertFromC(default_value[i]));
}
return nt::SetDefaultEntryValue(entry,
Value::MakeStringArray(std::move(vec), time));
@@ -1061,7 +1169,9 @@ NT_Bool NT_SetDefaultEntryStringArray(NT_Entry entry, uint64_t time,
NT_Bool NT_GetEntryBoolean(NT_Entry entry, uint64_t* last_change,
NT_Bool* v_boolean) {
auto v = nt::GetEntryValue(entry);
if (!v || !v->IsBoolean()) return 0;
if (!v || !v->IsBoolean()) {
return 0;
}
*v_boolean = v->GetBoolean();
*last_change = v->last_change();
return 1;
@@ -1070,7 +1180,9 @@ NT_Bool NT_GetEntryBoolean(NT_Entry entry, uint64_t* last_change,
NT_Bool NT_GetEntryDouble(NT_Entry entry, uint64_t* last_change,
double* v_double) {
auto v = nt::GetEntryValue(entry);
if (!v || !v->IsDouble()) return 0;
if (!v || !v->IsDouble()) {
return 0;
}
*last_change = v->last_change();
*v_double = v->GetDouble();
return 1;
@@ -1079,7 +1191,9 @@ NT_Bool NT_GetEntryDouble(NT_Entry entry, uint64_t* last_change,
char* NT_GetEntryString(NT_Entry entry, uint64_t* last_change,
size_t* str_len) {
auto v = nt::GetEntryValue(entry);
if (!v || !v->IsString()) return nullptr;
if (!v || !v->IsString()) {
return nullptr;
}
*last_change = v->last_change();
struct NT_String v_string;
nt::ConvertToC(v->GetString(), &v_string);
@@ -1089,7 +1203,9 @@ char* NT_GetEntryString(NT_Entry entry, uint64_t* last_change,
char* NT_GetEntryRaw(NT_Entry entry, uint64_t* last_change, size_t* raw_len) {
auto v = nt::GetEntryValue(entry);
if (!v || !v->IsRaw()) return nullptr;
if (!v || !v->IsRaw()) {
return nullptr;
}
*last_change = v->last_change();
struct NT_String v_raw;
nt::ConvertToC(v->GetRaw(), &v_raw);
@@ -1100,7 +1216,9 @@ char* NT_GetEntryRaw(NT_Entry entry, uint64_t* last_change, size_t* raw_len) {
NT_Bool* NT_GetEntryBooleanArray(NT_Entry entry, uint64_t* last_change,
size_t* arr_size) {
auto v = nt::GetEntryValue(entry);
if (!v || !v->IsBooleanArray()) return nullptr;
if (!v || !v->IsBooleanArray()) {
return nullptr;
}
*last_change = v->last_change();
auto vArr = v->GetBooleanArray();
NT_Bool* arr =
@@ -1113,7 +1231,9 @@ NT_Bool* NT_GetEntryBooleanArray(NT_Entry entry, uint64_t* last_change,
double* NT_GetEntryDoubleArray(NT_Entry entry, uint64_t* last_change,
size_t* arr_size) {
auto v = nt::GetEntryValue(entry);
if (!v || !v->IsDoubleArray()) return nullptr;
if (!v || !v->IsDoubleArray()) {
return nullptr;
}
*last_change = v->last_change();
auto vArr = v->GetDoubleArray();
double* arr =
@@ -1126,7 +1246,9 @@ double* NT_GetEntryDoubleArray(NT_Entry entry, uint64_t* last_change,
NT_String* NT_GetEntryStringArray(NT_Entry entry, uint64_t* last_change,
size_t* arr_size) {
auto v = nt::GetEntryValue(entry);
if (!v || !v->IsStringArray()) return nullptr;
if (!v || !v->IsStringArray()) {
return nullptr;
}
*last_change = v->last_change();
auto vArr = v->GetStringArray();
NT_String* arr = static_cast<NT_String*>(

File diff suppressed because it is too large Load Diff