mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-21 08:14:00 +08:00
Params: python-like interface (#20506)
* rebase master * delete outdated test_params.c * putBool & more robust getBool * putBool(SshEnabled) old-commit-hash: 98e55996f67aaaf715c941d417ae4d3b0187f388
This commit is contained in:
+22
-70
@@ -11,9 +11,6 @@
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <csignal>
|
||||
#include <string.h>
|
||||
|
||||
@@ -83,15 +80,11 @@ Params::Params(bool persistent_param){
|
||||
params_path = persistent_param ? persistent_params_path : default_params_path;
|
||||
}
|
||||
|
||||
Params::Params(std::string path) {
|
||||
Params::Params(const std::string &path) {
|
||||
params_path = path;
|
||||
}
|
||||
|
||||
int Params::write_db_value(std::string key, std::string dat){
|
||||
return write_db_value(key.c_str(), dat.c_str(), dat.length());
|
||||
}
|
||||
|
||||
int Params::write_db_value(const char* key, const char* value, size_t value_size) {
|
||||
int Params::put(const char* key, const char* value, size_t value_size) {
|
||||
// Information about safely and atomically writing a file: https://lwn.net/Articles/457667/
|
||||
// 1) Create temp file
|
||||
// 2) Write data to temp file
|
||||
@@ -213,7 +206,7 @@ cleanup:
|
||||
return result;
|
||||
}
|
||||
|
||||
int Params::delete_db_value(std::string key) {
|
||||
int Params::remove(const char *key) {
|
||||
int lock_fd = -1;
|
||||
int result;
|
||||
std::string path;
|
||||
@@ -230,7 +223,7 @@ int Params::delete_db_value(std::string key) {
|
||||
|
||||
// Delete value.
|
||||
path = params_path + "/d/" + key;
|
||||
result = remove(path.c_str());
|
||||
result = ::remove(path.c_str());
|
||||
if (result != 0) {
|
||||
result = ERR_NO_VALUE;
|
||||
goto cleanup;
|
||||
@@ -251,52 +244,28 @@ cleanup:
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Params::get(std::string key, bool block){
|
||||
char* value;
|
||||
size_t size;
|
||||
int r;
|
||||
|
||||
if (block) {
|
||||
r = read_db_value_blocking((const char*)key.c_str(), &value, &size);
|
||||
std::string Params::get(const char *key, bool block) {
|
||||
std::string path = params_path + "/d/" + key;
|
||||
if (!block) {
|
||||
return util::read_file(path);
|
||||
} else {
|
||||
r = read_db_value((const char*)key.c_str(), &value, &size);
|
||||
}
|
||||
// blocking read until successful
|
||||
params_do_exit = 0;
|
||||
void (*prev_handler_sigint)(int) = std::signal(SIGINT, params_sig_handler);
|
||||
void (*prev_handler_sigterm)(int) = std::signal(SIGTERM, params_sig_handler);
|
||||
|
||||
if (r == 0){
|
||||
std::string s(value, size);
|
||||
free(value);
|
||||
return s;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
int Params::read_db_value(const char* key, char** value, size_t* value_sz) {
|
||||
std::string path = params_path + "/d/" + std::string(key);
|
||||
*value = static_cast<char*>(read_file(path.c_str(), value_sz));
|
||||
if (*value == NULL) {
|
||||
return -22;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Params::read_db_value_blocking(const char* key, char** value, size_t* value_sz) {
|
||||
params_do_exit = 0;
|
||||
void (*prev_handler_sigint)(int) = std::signal(SIGINT, params_sig_handler);
|
||||
void (*prev_handler_sigterm)(int) = std::signal(SIGTERM, params_sig_handler);
|
||||
|
||||
while (!params_do_exit) {
|
||||
const int result = read_db_value(key, value, value_sz);
|
||||
if (result == 0) {
|
||||
break;
|
||||
} else {
|
||||
util::sleep_for(100); // 0.1 s
|
||||
std::string value;
|
||||
while (!params_do_exit) {
|
||||
if (value = util::read_file(path); !value.empty()) {
|
||||
break;
|
||||
}
|
||||
util::sleep_for(100); // 0.1 s
|
||||
}
|
||||
}
|
||||
|
||||
std::signal(SIGINT, prev_handler_sigint);
|
||||
std::signal(SIGTERM, prev_handler_sigterm);
|
||||
return params_do_exit; // Return 0 if we had no interrupt
|
||||
std::signal(SIGINT, prev_handler_sigint);
|
||||
std::signal(SIGTERM, prev_handler_sigterm);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
int Params::read_db_all(std::map<std::string, std::string> *params) {
|
||||
@@ -334,20 +303,3 @@ int Params::read_db_all(std::map<std::string, std::string> *params) {
|
||||
close(lock_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<char> Params::read_db_bytes(const char* param_name) {
|
||||
std::vector<char> bytes;
|
||||
char* value;
|
||||
size_t sz;
|
||||
int result = read_db_value(param_name, &value, &sz);
|
||||
if (result == 0) {
|
||||
bytes.assign(value, value+sz);
|
||||
free(value);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
bool Params::read_db_bool(const char* param_name) {
|
||||
std::vector<char> bytes = read_db_bytes(param_name);
|
||||
return bytes.size() > 0 and bytes[0] == '1';
|
||||
}
|
||||
|
||||
+38
-28
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#define ERR_NO_VALUE -33
|
||||
|
||||
@@ -12,35 +13,44 @@ private:
|
||||
|
||||
public:
|
||||
Params(bool persistent_param = false);
|
||||
Params(std::string path);
|
||||
Params(const std::string &path);
|
||||
|
||||
int write_db_value(std::string key, std::string dat);
|
||||
int write_db_value(const char* key, const char* value, size_t value_size);
|
||||
|
||||
// Reads a value from the params database.
|
||||
// Inputs:
|
||||
// key: The key to read.
|
||||
// value: A pointer where a newly allocated string containing the db value will
|
||||
// be written.
|
||||
// value_sz: A pointer where the size of value will be written. Does not
|
||||
// include the NULL terminator.
|
||||
// persistent_param: Boolean indicating if the param store in the /persist partition is to be used.
|
||||
// e.g. for sensor calibration files. Will not be cleared after wipe or re-install.
|
||||
//
|
||||
// Returns: Negative on failure, otherwise 0.
|
||||
int read_db_value(const char* key, char** value, size_t* value_sz);
|
||||
|
||||
// Delete a value from the params database.
|
||||
// Inputs are the same as read_db_value, without value and value_sz.
|
||||
int delete_db_value(std::string key);
|
||||
|
||||
// Reads a value from the params database, blocking until successful.
|
||||
// Inputs are the same as read_db_value.
|
||||
int read_db_value_blocking(const char* key, char** value, size_t* value_sz);
|
||||
// Delete a value
|
||||
int remove(const char *key);
|
||||
inline int remove(const std::string &key) {
|
||||
return remove (key.c_str());
|
||||
}
|
||||
|
||||
// read all values
|
||||
int read_db_all(std::map<std::string, std::string> *params);
|
||||
std::vector<char> read_db_bytes(const char* param_name);
|
||||
bool read_db_bool(const char* param_name);
|
||||
|
||||
std::string get(std::string key, bool block=false);
|
||||
// read a value
|
||||
std::string get(const char *key, bool block = false);
|
||||
|
||||
inline std::string get(const std::string &key, bool block = false) {
|
||||
return get(key.c_str(), block);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::optional<T> get(const char *key, bool block = false) {
|
||||
std::istringstream iss(get(key, block));
|
||||
T value{};
|
||||
iss >> value;
|
||||
return iss.fail() ? std::nullopt : std::optional(value);
|
||||
}
|
||||
|
||||
inline bool getBool(const char *key) {
|
||||
return get(key) == "1";
|
||||
}
|
||||
|
||||
// write a value
|
||||
int put(const char* key, const char* val, size_t value_size);
|
||||
|
||||
inline int put(const std::string &key, const std::string &val) {
|
||||
return put(key.c_str(), val.data(), val.size());
|
||||
}
|
||||
|
||||
inline int putBool(const char *key, bool val) {
|
||||
return put(key, val ? "1" : "0", 1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
#include "selfdrive/common/params.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char* const kUsage = "%s: read|write|read_block params_path key [value]\n";
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
if (argc < 4) {
|
||||
printf(kUsage, argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* params_path = argv[2];
|
||||
const char* key = argv[3];
|
||||
if (strcmp(argv[1], "read") == 0) {
|
||||
char* value;
|
||||
size_t value_size;
|
||||
int result = read_db_value(params_path, key, &value, &value_size);
|
||||
if (result >= 0) {
|
||||
fprintf(stdout, "Read %zu bytes: ", value_size);
|
||||
fwrite(value, 1, value_size, stdout);
|
||||
fprintf(stdout, "\n");
|
||||
free(value);
|
||||
} else {
|
||||
fprintf(stderr, "Error reading: %d\n", result);
|
||||
return -1;
|
||||
}
|
||||
} else if (strcmp(argv[1], "write") == 0) {
|
||||
if (argc < 5) {
|
||||
fprintf(stderr, "Error: write value required\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* value = argv[4];
|
||||
const size_t value_size = strlen(value);
|
||||
int result = write_db_value(params_path, key, value, value_size);
|
||||
if (result >= 0) {
|
||||
fprintf(stdout, "Wrote %s to %s\n", value, key);
|
||||
} else {
|
||||
fprintf(stderr, "Error writing: %d\n", result);
|
||||
return -1;
|
||||
}
|
||||
} else if (strcmp(argv[1], "read_block") == 0) {
|
||||
char* value;
|
||||
size_t value_size;
|
||||
read_db_value_blocking(params_path, key, &value, &value_size);
|
||||
fprintf(stdout, "Read %zu bytes: ", value_size);
|
||||
fwrite(value, 1, value_size, stdout);
|
||||
fprintf(stdout, "\n");
|
||||
free(value);
|
||||
} else {
|
||||
printf(kUsage, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// BUILD:
|
||||
// $ gcc -I$HOME/one selfdrive/common/test_params.c selfdrive/common/params.c selfdrive/common/util.cc -o ./test_params
|
||||
// $ seq 0 100000 | xargs -P20 -I{} ./test_params write /data/params DongleId {} && sleep 0.1 &
|
||||
// $ while ./test_params read /data/params DongleId; do sleep 0.05; done
|
||||
Reference in New Issue
Block a user