2015-06-21 21:43:05 -07:00
|
|
|
/*----------------------------------------------------------------------------*/
|
2018-01-01 17:29:13 -08:00
|
|
|
/* Copyright (c) FIRST 2015-2018. All Rights Reserved. */
|
2015-06-21 21:43:05 -07:00
|
|
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
|
|
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
|
|
|
/* the project. */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
2017-08-19 23:08:27 -07:00
|
|
|
#ifndef NTCORE_WIREDECODER_H_
|
|
|
|
|
#define NTCORE_WIREDECODER_H_
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
2015-06-21 21:43:05 -07:00
|
|
|
|
|
|
|
|
#include <cstddef>
|
2017-08-19 23:08:27 -07:00
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
2018-04-29 23:33:19 -07:00
|
|
|
#include <wpi/leb128.h>
|
|
|
|
|
#include <wpi/raw_istream.h>
|
2015-06-21 21:43:05 -07:00
|
|
|
|
Implement independent instances.
Previously, most of the classes were implemented as singletons so only one
instance was possible.
This change adds an instance handle-based API. In Java, this API is located
in a different package than the old API (edu.wpi.first.networktables).
Backwards compatibility with ITable and the old NetworkTable API is largely
maintained, but a handful of classes have moved to the new package in Java
(ConnectionInfo and PersistentException), and the old JNI has been completed
replaced.
Also:
- Move SetTeam implementation to Dispatcher.
- Consistently pass time through Java and C++ Value API.
- Rename nt_Value.h to NetworkTableValue.h for consistency with Java.
- Improve documentation
- Make C++ and Java APIs more consistent
- Document RPC functions and support RPC in Java.
- Add polling features for entry and connection listeners and use them to
move callback threads to Java level.
- Remove thread start and stop hooks (as polling is available).
- Make Notifiers, RpcServer, Dispatcher, and Storage mockable.
- Set NOTIFY_NEW on immediate entry notifications.
- Make GetTable("/") and GetTable("") equivalent.
- Generate local notification for flags update when loading persistent file.
And many unit test updates/changes:
- Use InitGoogleMock instead of InitGoogleTest in test main.
- Move test printers to TestPrinter.h/cpp.
- Provide printers for StringRef, EntryNotifier, and Handle.
- StorageTest: Check notifications.
- Add entry notifier unit tests.
- Storage: Add test for incoming entry assignment.
- Update connection listener tests.
- Add entry listener unit tests.
Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
|
|
|
#include "Log.h"
|
2017-08-19 23:08:27 -07:00
|
|
|
#include "networktables/NetworkTableValue.h"
|
2015-06-21 21:43:05 -07:00
|
|
|
|
2015-07-17 07:21:07 -07:00
|
|
|
namespace nt {
|
2015-06-25 22:57:43 -07:00
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Decodes network data into native representation.
|
|
|
|
|
* This class is designed to read from a raw_istream, which provides a blocking
|
|
|
|
|
* read interface. There are no provisions in this class for resuming a read
|
|
|
|
|
* that was interrupted partway. Read functions return false if
|
|
|
|
|
* raw_istream.read() returned false (indicating the end of the input data
|
|
|
|
|
* stream).
|
|
|
|
|
*/
|
2015-06-25 22:57:43 -07:00
|
|
|
class WireDecoder {
|
|
|
|
|
public:
|
Implement independent instances.
Previously, most of the classes were implemented as singletons so only one
instance was possible.
This change adds an instance handle-based API. In Java, this API is located
in a different package than the old API (edu.wpi.first.networktables).
Backwards compatibility with ITable and the old NetworkTable API is largely
maintained, but a handful of classes have moved to the new package in Java
(ConnectionInfo and PersistentException), and the old JNI has been completed
replaced.
Also:
- Move SetTeam implementation to Dispatcher.
- Consistently pass time through Java and C++ Value API.
- Rename nt_Value.h to NetworkTableValue.h for consistency with Java.
- Improve documentation
- Make C++ and Java APIs more consistent
- Document RPC functions and support RPC in Java.
- Add polling features for entry and connection listeners and use them to
move callback threads to Java level.
- Remove thread start and stop hooks (as polling is available).
- Make Notifiers, RpcServer, Dispatcher, and Storage mockable.
- Set NOTIFY_NEW on immediate entry notifications.
- Make GetTable("/") and GetTable("") equivalent.
- Generate local notification for flags update when loading persistent file.
And many unit test updates/changes:
- Use InitGoogleMock instead of InitGoogleTest in test main.
- Move test printers to TestPrinter.h/cpp.
- Provide printers for StringRef, EntryNotifier, and Handle.
- StorageTest: Check notifications.
- Add entry notifier unit tests.
- Storage: Add test for incoming entry assignment.
- Update connection listener tests.
- Add entry listener unit tests.
Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
|
|
|
WireDecoder(wpi::raw_istream& is, unsigned int proto_rev,
|
|
|
|
|
wpi::Logger& logger);
|
2015-06-25 22:57:43 -07:00
|
|
|
~WireDecoder();
|
|
|
|
|
|
2015-06-25 23:25:29 -07:00
|
|
|
void set_proto_rev(unsigned int proto_rev) { m_proto_rev = proto_rev; }
|
2015-06-25 22:57:43 -07:00
|
|
|
|
2015-07-03 22:11:06 -07:00
|
|
|
/* Get the active protocol revision. */
|
|
|
|
|
unsigned int proto_rev() const { return m_proto_rev; }
|
|
|
|
|
|
Implement independent instances.
Previously, most of the classes were implemented as singletons so only one
instance was possible.
This change adds an instance handle-based API. In Java, this API is located
in a different package than the old API (edu.wpi.first.networktables).
Backwards compatibility with ITable and the old NetworkTable API is largely
maintained, but a handful of classes have moved to the new package in Java
(ConnectionInfo and PersistentException), and the old JNI has been completed
replaced.
Also:
- Move SetTeam implementation to Dispatcher.
- Consistently pass time through Java and C++ Value API.
- Rename nt_Value.h to NetworkTableValue.h for consistency with Java.
- Improve documentation
- Make C++ and Java APIs more consistent
- Document RPC functions and support RPC in Java.
- Add polling features for entry and connection listeners and use them to
move callback threads to Java level.
- Remove thread start and stop hooks (as polling is available).
- Make Notifiers, RpcServer, Dispatcher, and Storage mockable.
- Set NOTIFY_NEW on immediate entry notifications.
- Make GetTable("/") and GetTable("") equivalent.
- Generate local notification for flags update when loading persistent file.
And many unit test updates/changes:
- Use InitGoogleMock instead of InitGoogleTest in test main.
- Move test printers to TestPrinter.h/cpp.
- Provide printers for StringRef, EntryNotifier, and Handle.
- StorageTest: Check notifications.
- Add entry notifier unit tests.
- Storage: Add test for incoming entry assignment.
- Update connection listener tests.
- Add entry listener unit tests.
Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
|
|
|
/* Get the logger. */
|
|
|
|
|
wpi::Logger& logger() const { return m_logger; }
|
|
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Clears error indicator. */
|
2015-06-25 22:57:43 -07:00
|
|
|
void Reset() { m_error = nullptr; }
|
|
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Returns error indicator (a string describing the error). Returns nullptr
|
|
|
|
|
* if no error has occurred.
|
|
|
|
|
*/
|
2015-06-25 23:25:29 -07:00
|
|
|
const char* error() const { return m_error; }
|
2015-06-25 22:57:43 -07:00
|
|
|
|
2015-07-12 11:24:34 -07:00
|
|
|
void set_error(const char* error) { m_error = error; }
|
|
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Reads the specified number of bytes.
|
|
|
|
|
* @param buf pointer to read data (output parameter)
|
|
|
|
|
* @param len number of bytes to read
|
2015-07-05 16:15:58 -07:00
|
|
|
* Caution: the buffer is only temporarily valid.
|
2015-06-26 01:23:36 -07:00
|
|
|
*/
|
2017-08-19 23:08:27 -07:00
|
|
|
bool Read(const char** buf, size_t len) {
|
2015-06-25 22:57:43 -07:00
|
|
|
if (len > m_allocated) Realloc(len);
|
|
|
|
|
*buf = m_buf;
|
2016-09-02 20:53:45 -07:00
|
|
|
m_is.read(m_buf, len);
|
2015-11-02 22:06:55 -08:00
|
|
|
#if 0
|
Implement independent instances.
Previously, most of the classes were implemented as singletons so only one
instance was possible.
This change adds an instance handle-based API. In Java, this API is located
in a different package than the old API (edu.wpi.first.networktables).
Backwards compatibility with ITable and the old NetworkTable API is largely
maintained, but a handful of classes have moved to the new package in Java
(ConnectionInfo and PersistentException), and the old JNI has been completed
replaced.
Also:
- Move SetTeam implementation to Dispatcher.
- Consistently pass time through Java and C++ Value API.
- Rename nt_Value.h to NetworkTableValue.h for consistency with Java.
- Improve documentation
- Make C++ and Java APIs more consistent
- Document RPC functions and support RPC in Java.
- Add polling features for entry and connection listeners and use them to
move callback threads to Java level.
- Remove thread start and stop hooks (as polling is available).
- Make Notifiers, RpcServer, Dispatcher, and Storage mockable.
- Set NOTIFY_NEW on immediate entry notifications.
- Make GetTable("/") and GetTable("") equivalent.
- Generate local notification for flags update when loading persistent file.
And many unit test updates/changes:
- Use InitGoogleMock instead of InitGoogleTest in test main.
- Move test printers to TestPrinter.h/cpp.
- Provide printers for StringRef, EntryNotifier, and Handle.
- StorageTest: Check notifications.
- Add entry notifier unit tests.
- Storage: Add test for incoming entry assignment.
- Update connection listener tests.
- Add entry listener unit tests.
Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
|
|
|
if (m_logger.min_level() <= NT_LOG_DEBUG4 && m_logger.HasLogger()) {
|
2015-11-02 22:06:55 -08:00
|
|
|
std::ostringstream oss;
|
|
|
|
|
oss << "read " << len << " bytes:" << std::hex;
|
2017-08-19 23:08:27 -07:00
|
|
|
if (!rv) {
|
2015-11-02 22:06:55 -08:00
|
|
|
oss << "error";
|
2017-08-19 23:08:27 -07:00
|
|
|
} else {
|
|
|
|
|
for (size_t i = 0; i < len; ++i)
|
|
|
|
|
oss << ' ' << static_cast<unsigned int>((*buf)[i]);
|
2015-11-02 22:06:55 -08:00
|
|
|
}
|
Implement independent instances.
Previously, most of the classes were implemented as singletons so only one
instance was possible.
This change adds an instance handle-based API. In Java, this API is located
in a different package than the old API (edu.wpi.first.networktables).
Backwards compatibility with ITable and the old NetworkTable API is largely
maintained, but a handful of classes have moved to the new package in Java
(ConnectionInfo and PersistentException), and the old JNI has been completed
replaced.
Also:
- Move SetTeam implementation to Dispatcher.
- Consistently pass time through Java and C++ Value API.
- Rename nt_Value.h to NetworkTableValue.h for consistency with Java.
- Improve documentation
- Make C++ and Java APIs more consistent
- Document RPC functions and support RPC in Java.
- Add polling features for entry and connection listeners and use them to
move callback threads to Java level.
- Remove thread start and stop hooks (as polling is available).
- Make Notifiers, RpcServer, Dispatcher, and Storage mockable.
- Set NOTIFY_NEW on immediate entry notifications.
- Make GetTable("/") and GetTable("") equivalent.
- Generate local notification for flags update when loading persistent file.
And many unit test updates/changes:
- Use InitGoogleMock instead of InitGoogleTest in test main.
- Move test printers to TestPrinter.h/cpp.
- Provide printers for StringRef, EntryNotifier, and Handle.
- StorageTest: Check notifications.
- Add entry notifier unit tests.
- Storage: Add test for incoming entry assignment.
- Update connection listener tests.
- Add entry listener unit tests.
Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
|
|
|
m_logger.Log(NT_LOG_DEBUG4, __FILE__, __LINE__, oss.str().c_str());
|
2015-11-02 22:06:55 -08:00
|
|
|
}
|
|
|
|
|
#endif
|
2016-09-02 20:53:45 -07:00
|
|
|
return !m_is.has_error();
|
2015-06-25 22:57:43 -07:00
|
|
|
}
|
|
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Reads a single byte. */
|
2015-06-25 22:57:43 -07:00
|
|
|
bool Read8(unsigned int* val) {
|
2015-07-05 16:15:58 -07:00
|
|
|
const char* buf;
|
2015-06-25 22:57:43 -07:00
|
|
|
if (!Read(&buf, 1)) return false;
|
2015-11-28 13:12:30 -08:00
|
|
|
*val = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
|
2015-06-25 22:57:43 -07:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Reads a 16-bit word. */
|
2015-06-25 22:57:43 -07:00
|
|
|
bool Read16(unsigned int* val) {
|
2015-07-05 16:15:58 -07:00
|
|
|
const char* buf;
|
2015-06-25 22:57:43 -07:00
|
|
|
if (!Read(&buf, 2)) return false;
|
2015-11-28 13:12:30 -08:00
|
|
|
unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
|
2015-06-25 22:57:43 -07:00
|
|
|
++buf;
|
|
|
|
|
v <<= 8;
|
2015-11-28 13:12:30 -08:00
|
|
|
v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
|
2015-06-25 22:57:43 -07:00
|
|
|
*val = v;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Reads a 32-bit word. */
|
2017-08-19 23:08:27 -07:00
|
|
|
bool Read32(uint32_t* val) {
|
2015-07-05 16:15:58 -07:00
|
|
|
const char* buf;
|
2015-06-25 22:57:43 -07:00
|
|
|
if (!Read(&buf, 4)) return false;
|
2015-11-28 13:12:30 -08:00
|
|
|
unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
|
2015-06-25 22:57:43 -07:00
|
|
|
++buf;
|
|
|
|
|
v <<= 8;
|
2015-11-28 13:12:30 -08:00
|
|
|
v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
|
2015-06-25 22:57:43 -07:00
|
|
|
++buf;
|
|
|
|
|
v <<= 8;
|
2015-11-28 13:12:30 -08:00
|
|
|
v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
|
2015-06-25 22:57:43 -07:00
|
|
|
++buf;
|
|
|
|
|
v <<= 8;
|
2015-11-28 13:12:30 -08:00
|
|
|
v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
|
2015-06-25 22:57:43 -07:00
|
|
|
*val = v;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Reads a double. */
|
2015-06-25 22:57:43 -07:00
|
|
|
bool ReadDouble(double* val);
|
|
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Reads an ULEB128-encoded unsigned integer. */
|
2017-08-19 23:08:27 -07:00
|
|
|
bool ReadUleb128(uint64_t* val) { return wpi::ReadUleb128(m_is, val); }
|
2015-06-25 22:57:43 -07:00
|
|
|
|
|
|
|
|
bool ReadType(NT_Type* type);
|
2015-07-16 01:38:27 -07:00
|
|
|
bool ReadString(std::string* str);
|
|
|
|
|
std::shared_ptr<Value> ReadValue(NT_Type type);
|
2015-07-04 23:10:59 -07:00
|
|
|
|
2015-06-25 22:57:43 -07:00
|
|
|
WireDecoder(const WireDecoder&) = delete;
|
|
|
|
|
WireDecoder& operator=(const WireDecoder&) = delete;
|
|
|
|
|
|
|
|
|
|
protected:
|
2015-06-26 01:23:36 -07:00
|
|
|
/* The protocol revision. E.g. 0x0200 for version 2.0. */
|
2015-06-25 22:57:43 -07:00
|
|
|
unsigned int m_proto_rev;
|
2015-06-26 01:23:36 -07:00
|
|
|
|
|
|
|
|
/* Error indicator. */
|
2015-06-25 22:57:43 -07:00
|
|
|
const char* m_error;
|
|
|
|
|
|
|
|
|
|
private:
|
2015-06-26 01:23:36 -07:00
|
|
|
/* Reallocate temporary buffer to specified length. */
|
2017-08-19 23:08:27 -07:00
|
|
|
void Realloc(size_t len);
|
2015-06-25 22:57:43 -07:00
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* input stream */
|
2016-07-27 00:39:38 -07:00
|
|
|
wpi::raw_istream& m_is;
|
2015-06-25 22:57:43 -07:00
|
|
|
|
Implement independent instances.
Previously, most of the classes were implemented as singletons so only one
instance was possible.
This change adds an instance handle-based API. In Java, this API is located
in a different package than the old API (edu.wpi.first.networktables).
Backwards compatibility with ITable and the old NetworkTable API is largely
maintained, but a handful of classes have moved to the new package in Java
(ConnectionInfo and PersistentException), and the old JNI has been completed
replaced.
Also:
- Move SetTeam implementation to Dispatcher.
- Consistently pass time through Java and C++ Value API.
- Rename nt_Value.h to NetworkTableValue.h for consistency with Java.
- Improve documentation
- Make C++ and Java APIs more consistent
- Document RPC functions and support RPC in Java.
- Add polling features for entry and connection listeners and use them to
move callback threads to Java level.
- Remove thread start and stop hooks (as polling is available).
- Make Notifiers, RpcServer, Dispatcher, and Storage mockable.
- Set NOTIFY_NEW on immediate entry notifications.
- Make GetTable("/") and GetTable("") equivalent.
- Generate local notification for flags update when loading persistent file.
And many unit test updates/changes:
- Use InitGoogleMock instead of InitGoogleTest in test main.
- Move test printers to TestPrinter.h/cpp.
- Provide printers for StringRef, EntryNotifier, and Handle.
- StorageTest: Check notifications.
- Add entry notifier unit tests.
- Storage: Add test for incoming entry assignment.
- Update connection listener tests.
- Add entry listener unit tests.
Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
|
|
|
/* logger */
|
|
|
|
|
wpi::Logger& m_logger;
|
|
|
|
|
|
2015-06-26 01:23:36 -07:00
|
|
|
/* temporary buffer */
|
2015-06-25 22:57:43 -07:00
|
|
|
char* m_buf;
|
2015-06-26 01:23:36 -07:00
|
|
|
|
|
|
|
|
/* allocated size of temporary buffer */
|
2017-08-19 23:08:27 -07:00
|
|
|
size_t m_allocated;
|
2015-06-21 21:43:05 -07:00
|
|
|
};
|
|
|
|
|
|
2015-07-17 07:21:07 -07:00
|
|
|
} // namespace nt
|
2015-06-21 21:43:05 -07:00
|
|
|
|
2017-08-19 23:08:27 -07:00
|
|
|
#endif // NTCORE_WIREDECODER_H_
|