mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-27 02:01:42 +00:00
Move all C api functions to ntcore.cpp.
Change-Id: I17b4f5fec30ecd684cf04af2bbd6b7346bfcd683
This commit is contained in:
162
src/Storage.cpp
162
src/Storage.cpp
@@ -7,6 +7,12 @@
|
||||
|
||||
#include "Storage.h"
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "llvm/StringExtras.h"
|
||||
#include "base64.h"
|
||||
|
||||
using namespace ntimpl;
|
||||
|
||||
Storage* Storage::m_instance = nullptr;
|
||||
@@ -14,3 +20,159 @@ Storage* Storage::m_instance = nullptr;
|
||||
Storage::Storage() {}
|
||||
|
||||
Storage::~Storage() {}
|
||||
|
||||
static void WriteString(std::ostream& os, llvm::StringRef str) {
|
||||
os << '"';
|
||||
for (auto c : str) {
|
||||
switch (c) {
|
||||
case '\\':
|
||||
os << "\\\\";
|
||||
break;
|
||||
case '\t':
|
||||
os << "\\t";
|
||||
break;
|
||||
case '\n':
|
||||
os << "\\n";
|
||||
break;
|
||||
case '"':
|
||||
os << "\\\"";
|
||||
break;
|
||||
default:
|
||||
if (std::isprint(c)) {
|
||||
os << c;
|
||||
break;
|
||||
}
|
||||
|
||||
// Write out the escaped representation.
|
||||
os << "\\x";
|
||||
os << llvm::hexdigit((c >> 4) & 0xF);
|
||||
os << llvm::hexdigit((c >> 0) & 0xF);
|
||||
}
|
||||
}
|
||||
os << '"';
|
||||
}
|
||||
|
||||
void Storage::SavePersistent(std::ostream& os) const {
|
||||
os << "[NetworkTables Storage 3.0]\n";
|
||||
|
||||
for (auto& i : m_entries) {
|
||||
const StorageEntry& entry = i.getValue();
|
||||
// only write persistent-flagged values
|
||||
if ((entry.flags & NT_PERSISTENT) == 0) continue;
|
||||
|
||||
// type
|
||||
const NT_Value& v = entry.value;
|
||||
switch (v.type) {
|
||||
case NT_BOOLEAN:
|
||||
os << "boolean ";
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
os << "double ";
|
||||
break;
|
||||
case NT_STRING:
|
||||
os << "string ";
|
||||
break;
|
||||
case NT_RAW:
|
||||
os << "raw ";
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
os << "array boolean ";
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
os << "array double ";
|
||||
break;
|
||||
case NT_STRING_ARRAY:
|
||||
os << "array string ";
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// name
|
||||
WriteString(os, i.getKey());
|
||||
|
||||
// =
|
||||
os << '=';
|
||||
|
||||
// value
|
||||
switch (v.type) {
|
||||
case NT_BOOLEAN:
|
||||
os << (v.data.v_boolean ? "true" : "false");
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
os << v.data.v_double;
|
||||
break;
|
||||
case NT_STRING:
|
||||
WriteString(os, MakeStringRef(v.data.v_string));
|
||||
break;
|
||||
case NT_RAW: {
|
||||
char* buf = new char[Base64EncodeLen(v.data.v_raw.len)];
|
||||
Base64Encode(buf,
|
||||
reinterpret_cast<const unsigned char*>(v.data.v_raw.str),
|
||||
v.data.v_raw.len);
|
||||
os << buf;
|
||||
delete[] buf;
|
||||
break;
|
||||
}
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
for (size_t i = 0; i < v.data.arr_boolean.size; ++i) {
|
||||
os << (v.data.arr_boolean.arr[i] ? "true" : "false");
|
||||
if (i != (v.data.arr_boolean.size - 1))
|
||||
os << ',';
|
||||
}
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
for (size_t i = 0; i < v.data.arr_double.size; ++i) {
|
||||
os << v.data.arr_double.arr[i];
|
||||
if (i != (v.data.arr_double.size - 1))
|
||||
os << ',';
|
||||
}
|
||||
break;
|
||||
case NT_STRING_ARRAY:
|
||||
for (size_t i = 0; i < v.data.arr_double.size; ++i) {
|
||||
WriteString(os, MakeStringRef(v.data.arr_string.arr[i]));
|
||||
if (i != (v.data.arr_double.size - 1))
|
||||
os << ',';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// eol
|
||||
os << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void Storage::LoadPersistent(std::istream& is,
|
||||
void (*warn)(std::size_t line, const char* msg)) {
|
||||
std::string line_str;
|
||||
std::size_t line_num = 0;
|
||||
while (std::getline(is, line_str)) {
|
||||
llvm::StringRef line(line_str);
|
||||
++line_num;
|
||||
|
||||
// type
|
||||
llvm::StringRef type_str;
|
||||
std::tie(type_str, line) = line.split(' ');
|
||||
NT_Type type = NT_UNASSIGNED;
|
||||
if (type_str == "boolean") type = NT_BOOLEAN;
|
||||
else if (type_str == "double") type = NT_DOUBLE;
|
||||
else if (type_str == "string") type = NT_STRING;
|
||||
else if (type_str == "raw") type = NT_RAW;
|
||||
else if (type_str == "array") {
|
||||
llvm::StringRef array_str;
|
||||
std::tie(array_str, line) = line.split(' ');
|
||||
if (array_str == "boolean") type = NT_BOOLEAN_ARRAY;
|
||||
else if (array_str == "double") type = NT_DOUBLE_ARRAY;
|
||||
else if (array_str == "string") type = NT_STRING_ARRAY;
|
||||
}
|
||||
if (type == NT_UNASSIGNED) {
|
||||
if (warn) warn(line_num, "unrecognized type");
|
||||
continue;
|
||||
}
|
||||
|
||||
// name
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#ifndef NT_STORAGE_H_
|
||||
#define NT_STORAGE_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <cstddef>
|
||||
|
||||
#include "ntcore.h"
|
||||
|
||||
#include "llvm/StringMap.h"
|
||||
@@ -45,6 +48,10 @@ class Storage {
|
||||
EntriesMap& entries() { return m_entries; }
|
||||
const EntriesMap& entries() const { return m_entries; }
|
||||
|
||||
void SavePersistent(std::ostream& os) const;
|
||||
void LoadPersistent(std::istream& is,
|
||||
void (*warn)(std::size_t line, const char* msg));
|
||||
|
||||
private:
|
||||
Storage();
|
||||
~Storage();
|
||||
|
||||
170
src/ntcore.cpp
Normal file
170
src/ntcore.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "ntcore.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
|
||||
#include "Storage.h"
|
||||
|
||||
using namespace ntimpl;
|
||||
|
||||
/*
|
||||
* Table Functions
|
||||
*/
|
||||
|
||||
void NT_GetEntryValue(const char *name, unsigned int name_len,
|
||||
struct NT_Value *value) {}
|
||||
|
||||
int NT_SetEntryValue(const char *name, unsigned int name_len,
|
||||
const struct NT_Value *value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NT_SetEntryTypeValue(const char *name, unsigned int name_len,
|
||||
const struct NT_Value *value) {}
|
||||
|
||||
void NT_SetEntryFlags(const char *name, size_t name_len, unsigned int flags) {}
|
||||
|
||||
unsigned int NT_GetEntryFlags(const char *name, size_t name_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NT_DeleteEntry(const char *name, unsigned int name_len) {}
|
||||
|
||||
void NT_DeleteAllEntries(void) {}
|
||||
|
||||
struct NT_EntryInfo *NT_GetEntryInfo(const char *prefix,
|
||||
unsigned int prefix_len, int types,
|
||||
unsigned int *count) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NT_Flush(void) {}
|
||||
|
||||
/*
|
||||
* Callback Creation Functions
|
||||
*/
|
||||
|
||||
unsigned int NT_AddEntryListener(const char *prefix, size_t prefix_len,
|
||||
void *data,
|
||||
NT_EntryListenerCallback callback) {
|
||||
return 0;
|
||||
}
|
||||
void NT_RemoveEntryListener(unsigned int entry_listener_uid) {}
|
||||
unsigned int NT_AddConnectionListener(void *data,
|
||||
NT_ConnectionListenerCallback callback) {
|
||||
return 0;
|
||||
}
|
||||
void NT_RemoveConnectionListener(unsigned int conn_listener_uid) {}
|
||||
|
||||
/*
|
||||
* Remote Procedure Call Functions
|
||||
*/
|
||||
|
||||
unsigned int NT_CreateRpc(const char *name, size_t name_len,
|
||||
const NT_RpcDefinition *def, void *data,
|
||||
NT_RpcCallback callback);
|
||||
void NT_DeleteRpc(unsigned int rpc_uid);
|
||||
unsigned int NT_CallRpc(const char *name, size_t name_len,
|
||||
const NT_Value *params, size_t params_len);
|
||||
NT_Value *NT_GetRpcResult(unsigned int result_uid, size_t *results_len);
|
||||
|
||||
/*
|
||||
* Client/Server Functions
|
||||
*/
|
||||
|
||||
void NT_SetNetworkIdentity(const char *name, size_t name_len) {}
|
||||
void NT_StartServer(const char *persist_filename, const char *listen_address,
|
||||
unsigned int port) {}
|
||||
void NT_StopServer(void) {}
|
||||
void NT_StartClient(const char *server_name, unsigned int port) {}
|
||||
void NT_StopClient(void) {}
|
||||
void NT_SetUpdateRate(double interval) {}
|
||||
struct NT_ConnectionInfo *NT_GetConnections(size_t *count) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Persistent Functions
|
||||
*/
|
||||
|
||||
const char *NT_SavePersistent(const char *filename) {
|
||||
const Storage& storage = Storage::GetInstance();
|
||||
std::ofstream os(filename);
|
||||
if (!os) return "could not open file";
|
||||
storage.SavePersistent(os);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *NT_LoadPersistent(const char *filename,
|
||||
void (*warn)(size_t line, const char *msg)) {
|
||||
Storage& storage = Storage::GetInstance();
|
||||
std::ifstream is(filename);
|
||||
if (!is) return "could not open file";
|
||||
storage.LoadPersistent(is, warn);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility Functions
|
||||
*/
|
||||
|
||||
void NT_DisposeValue(NT_Value *value) {
|
||||
switch (value->type) {
|
||||
case NT_UNASSIGNED:
|
||||
case NT_BOOLEAN:
|
||||
case NT_DOUBLE:
|
||||
break;
|
||||
case NT_STRING:
|
||||
case NT_RAW:
|
||||
case NT_RPC:
|
||||
std::free(value->data.v_string.str);
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
std::free(value->data.arr_boolean.arr);
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
std::free(value->data.arr_double.arr);
|
||||
break;
|
||||
case NT_STRING_ARRAY: {
|
||||
for (size_t i = 0; i < value->data.arr_string.size; i++)
|
||||
std::free(value->data.arr_string.arr[i].str);
|
||||
std::free(value->data.arr_string.arr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0 && "unknown value type");
|
||||
}
|
||||
value->type = NT_UNASSIGNED;
|
||||
value->last_change = 0;
|
||||
}
|
||||
|
||||
void NT_InitValue(NT_Value *value) {
|
||||
value->type = NT_UNASSIGNED;
|
||||
value->last_change = 0;
|
||||
}
|
||||
|
||||
void NT_DisposeString(NT_String *str) {
|
||||
std::free(str->str);
|
||||
str->str = nullptr;
|
||||
str->len = 0;
|
||||
}
|
||||
|
||||
void NT_InitString(NT_String *str) {
|
||||
str->str = nullptr;
|
||||
str->len = 0;
|
||||
}
|
||||
|
||||
void NT_DisposeConnectionInfoArray(NT_ConnectionInfo *arr, size_t count) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < count; i++)
|
||||
std::free(arr[i].remote_id.str);
|
||||
std::free(arr);
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "ntcore.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "llvm/StringExtras.h"
|
||||
#include "base64.h"
|
||||
#include "Storage.h"
|
||||
|
||||
using namespace ntimpl;
|
||||
|
||||
static void WriteString(std::ostream& os, llvm::StringRef str) {
|
||||
os << '"';
|
||||
for (auto c : str) {
|
||||
switch (c) {
|
||||
case '\\':
|
||||
os << "\\\\";
|
||||
break;
|
||||
case '\t':
|
||||
os << "\\t";
|
||||
break;
|
||||
case '\n':
|
||||
os << "\\n";
|
||||
break;
|
||||
case '"':
|
||||
os << "\\\"";
|
||||
break;
|
||||
default:
|
||||
if (std::isprint(c)) {
|
||||
os << c;
|
||||
break;
|
||||
}
|
||||
|
||||
// Write out the escaped representation.
|
||||
os << "\\x";
|
||||
os << llvm::hexdigit((c >> 4) & 0xF);
|
||||
os << llvm::hexdigit((c >> 0) & 0xF);
|
||||
}
|
||||
}
|
||||
os << '"';
|
||||
}
|
||||
|
||||
const char* NT_SavePersistent(const char* filename) {
|
||||
std::ofstream os(filename);
|
||||
if (!os) return "could not open file";
|
||||
|
||||
os << "[NetworkTables Storage 3.0]\n";
|
||||
|
||||
const Storage& storage = Storage::GetInstance();
|
||||
for (auto& i : storage.entries()) {
|
||||
const StorageEntry& entry = i.getValue();
|
||||
// only write persistent-flagged values
|
||||
if ((entry.flags & NT_PERSISTENT) == 0) continue;
|
||||
|
||||
// type
|
||||
const NT_Value& v = entry.value;
|
||||
switch (v.type) {
|
||||
case NT_BOOLEAN:
|
||||
os << "boolean ";
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
os << "double ";
|
||||
break;
|
||||
case NT_STRING:
|
||||
os << "string ";
|
||||
break;
|
||||
case NT_RAW:
|
||||
os << "raw ";
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
os << "array boolean ";
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
os << "array double ";
|
||||
break;
|
||||
case NT_STRING_ARRAY:
|
||||
os << "array string ";
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// name
|
||||
WriteString(os, i.getKey());
|
||||
|
||||
// =
|
||||
os << '=';
|
||||
|
||||
// value
|
||||
switch (v.type) {
|
||||
case NT_BOOLEAN:
|
||||
os << (v.data.v_boolean ? "true" : "false");
|
||||
break;
|
||||
case NT_DOUBLE:
|
||||
os << v.data.v_double;
|
||||
break;
|
||||
case NT_STRING:
|
||||
WriteString(os, MakeStringRef(v.data.v_string));
|
||||
break;
|
||||
case NT_RAW: {
|
||||
char* buf = new char[Base64EncodeLen(v.data.v_raw.len)];
|
||||
Base64Encode(buf,
|
||||
reinterpret_cast<const unsigned char*>(v.data.v_raw.str),
|
||||
v.data.v_raw.len);
|
||||
os << buf;
|
||||
delete[] buf;
|
||||
break;
|
||||
}
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
for (size_t i = 0; i < v.data.arr_boolean.size; ++i) {
|
||||
os << (v.data.arr_boolean.arr[i] ? "true" : "false");
|
||||
if (i != (v.data.arr_boolean.size - 1))
|
||||
os << ',';
|
||||
}
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
for (size_t i = 0; i < v.data.arr_double.size; ++i) {
|
||||
os << v.data.arr_double.arr[i];
|
||||
if (i != (v.data.arr_double.size - 1))
|
||||
os << ',';
|
||||
}
|
||||
break;
|
||||
case NT_STRING_ARRAY:
|
||||
for (size_t i = 0; i < v.data.arr_double.size; ++i) {
|
||||
WriteString(os, MakeStringRef(v.data.arr_string.arr[i]));
|
||||
if (i != (v.data.arr_double.size - 1))
|
||||
os << ',';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// eol
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
os.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* NT_LoadPersistent(const char* filename,
|
||||
void (*warn)(size_t line, const char* msg)) {
|
||||
std::ifstream f(filename);
|
||||
if (!f) return "could not open file";
|
||||
|
||||
std::string line_str;
|
||||
std::size_t line_num = 0;
|
||||
while (std::getline(f, line_str)) {
|
||||
llvm::StringRef line(line_str);
|
||||
++line_num;
|
||||
|
||||
// type
|
||||
llvm::StringRef type_str;
|
||||
std::tie(type_str, line) = line.split(' ');
|
||||
NT_Type type = NT_UNASSIGNED;
|
||||
if (type_str == "boolean") type = NT_BOOLEAN;
|
||||
else if (type_str == "double") type = NT_DOUBLE;
|
||||
else if (type_str == "string") type = NT_STRING;
|
||||
else if (type_str == "raw") type = NT_RAW;
|
||||
else if (type_str == "array") {
|
||||
llvm::StringRef array_str;
|
||||
std::tie(array_str, line) = line.split(' ');
|
||||
if (array_str == "boolean") type = NT_BOOLEAN_ARRAY;
|
||||
else if (array_str == "double") type = NT_DOUBLE_ARRAY;
|
||||
else if (array_str == "string") type = NT_STRING_ARRAY;
|
||||
}
|
||||
if (type == NT_UNASSIGNED) {
|
||||
if (warn) warn(line_num, "unrecognized type");
|
||||
continue;
|
||||
}
|
||||
|
||||
// name
|
||||
|
||||
}
|
||||
|
||||
f.close();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "ntcore.h"
|
||||
|
||||
void NT_DisposeValue(NT_Value *value) {
|
||||
switch (value->type) {
|
||||
case NT_UNASSIGNED:
|
||||
case NT_BOOLEAN:
|
||||
case NT_DOUBLE:
|
||||
break;
|
||||
case NT_STRING:
|
||||
case NT_RAW:
|
||||
case NT_RPC:
|
||||
std::free(value->data.v_string.str);
|
||||
break;
|
||||
case NT_BOOLEAN_ARRAY:
|
||||
std::free(value->data.arr_boolean.arr);
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
std::free(value->data.arr_double.arr);
|
||||
break;
|
||||
case NT_STRING_ARRAY: {
|
||||
for (size_t i = 0; i < value->data.arr_string.size; i++)
|
||||
std::free(value->data.arr_string.arr[i].str);
|
||||
std::free(value->data.arr_string.arr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0 && "unknown value type");
|
||||
}
|
||||
value->type = NT_UNASSIGNED;
|
||||
value->last_change = 0;
|
||||
}
|
||||
|
||||
void NT_InitValue(NT_Value *value) {
|
||||
value->type = NT_UNASSIGNED;
|
||||
value->last_change = 0;
|
||||
}
|
||||
|
||||
void NT_DisposeString(NT_String *str) {
|
||||
std::free(str->str);
|
||||
str->str = nullptr;
|
||||
str->len = 0;
|
||||
}
|
||||
|
||||
void NT_InitString(NT_String *str) {
|
||||
str->str = nullptr;
|
||||
str->len = 0;
|
||||
}
|
||||
|
||||
void NT_DisposeConnectionInfoArray(NT_ConnectionInfo *arr, size_t count) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < count; i++)
|
||||
std::free(arr[i].remote_id.str);
|
||||
std::free(arr);
|
||||
}
|
||||
Reference in New Issue
Block a user