tcp-server and tcp-client added

This commit is contained in:
2021-10-31 09:53:48 +01:00
parent 80d7935974
commit 159845bb9b
11 changed files with 235 additions and 14 deletions

58
ml.cpp
View File

@@ -9,6 +9,7 @@
#include "clib/csvparser.h"
#include "clib/sslclient.h"
#include "clib/tcpnet.h"
#include "clib/json11.h"
#include "clib/printf.h"
@@ -58,6 +59,11 @@
#define LIST_TYPE "list"
std::mutex register_mutex;
std::vector<std::thread> threads_register;
std::mutex interpreter_mutex;
// Is this character a valid lisp symbol character
bool is_symbol(char ch) {
return (isalpha(ch) || ispunct(ch)) && ch != '(' && ch != ')' && ch != '"' && ch != '\'';
@@ -1065,6 +1071,10 @@ MlValue exit(std::vector<MlValue> args, MlEnvironment &env) {
// Is not a special form, so we can evaluate our args.
eval_args(args, env);
std::lock_guard<std::mutex> lockGuard(register_mutex);
for(auto &t : threads_register)
t.detach();
std::exit(args.size() < 1 ? 0 : args[0].cast_to_int().as_int());
return MlValue(); // will not be called :-)
}
@@ -1306,6 +1316,40 @@ MlValue is_dir(std::vector<MlValue> args, MlEnvironment &env) {
return MlValue(is_path_dir(args[0].as_string()));
}
MlValue tcp_server(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env);
if (args.size() != 2)
throw MlError(MlValue("tcp-server", tcp_server), env, args.size() > 2 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
auto proccess_req = [&args, &env](const std::string &str) -> std::pair<bool, std::string> {
std::vector<MlValue> tmp {MlValue::string(str)};
MlValue result = args[1].apply(tmp, env);
// TODO more robust handling
if (result.is_list() && result.as_list().size() >= 2) {
std::vector<MlValue> list = result.as_list();
return std::make_pair(list[0].as_bool(), list[1].as_string());
} else {
return std::make_pair(false, result.as_string());
}
};
TcpNet server;
int r = server.server(args[0].as_int(), proccess_req);
return MlValue((long)r);
}
MlValue tcp_client(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env);
if (args.size() != 3)
throw MlError(MlValue("tcp-client", tcp_client), env, args.size() > 3 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
TcpNet tcpclient;
std::string response = tcpclient.client(args[0].as_string(), args[1].as_int(), args[2].as_string());
return MlValue::string(response);
}
// Read a file and execute its code
MlValue include(std::vector<MlValue> args, MlEnvironment &env) {
// Import is technically not a special form, it's more of a macro.
@@ -1895,11 +1939,6 @@ MlValue benchmark(std::vector<MlValue> args, MlEnvironment &env) {
}
std::mutex register_mutex;
std::vector<std::thread> threads_register;
std::vector<std::mutex> mutexes_register;
std::mutex interpreter_mutex;
MlValue thread_create(std::vector<MlValue> args, MlEnvironment &env) {
auto functor = [](std::vector<MlValue> args, MlEnvironment &env) -> void {
try {
@@ -1907,6 +1946,7 @@ MlValue thread_create(std::vector<MlValue> args, MlEnvironment &env) {
MlValue acc = args[i].eval(env);
} catch (std::exception &e) {
std::cerr << "thread exception: " << e.what() << std::endl;
throw e;
}
};
@@ -1953,7 +1993,9 @@ MlValue threads_join(std::vector<MlValue> args, MlEnvironment &env) {
if (args.size() != 0)
throw MlError(MlValue("threads-join", threads_join), env, TOO_MANY_ARGS);
std::lock_guard<std::mutex> lockGuard(register_mutex);
// here is a question about using lockGuard, when used it holds lockGuard locked until
// threads do not leave join
// std::lock_guard<std::mutex> lockGuard(register_mutex);
for (auto &th : threads_register)
if (th.joinable()) th.join();
@@ -2094,6 +2136,8 @@ MlValue MlEnvironment::get(const std::string &name) const {
if (name == "ls-dir") return MlValue("ls-dir", builtin::ls_dir);
if (name == "is-file?") return MlValue("is-file?", builtin::is_file);
if (name == "is-dir?") return MlValue("is-dir?", builtin::is_dir);
if (name == "tcp-server") return MlValue("tcp-client", builtin::tcp_server);
if (name == "tcp-client") return MlValue("tcp-client", builtin::tcp_client);
// parsing operations
if (name == "parse-csv") return MlValue("parse-csv", builtin::parse_csv);
@@ -2113,7 +2157,7 @@ MlValue MlEnvironment::get(const std::string &name) const {
if (name == "string-replace") return MlValue("string-replace", builtin::string_replace);
if (name == "string-replace-re") return MlValue("string-replace-re", builtin::string_replace_re);
if (name == "string-regex?") return MlValue("string-regex?", builtin::string_regex);
if (name == "string-regex-list") return MlValue("string-regex?", builtin::string_regex_list);
if (name == "string-regex-list") return MlValue("string-regex-list", builtin::string_regex_list);
if (name == "string-split") return MlValue("string-split", builtin::string_split);
if (name == "string-pad") return MlValue("string-pad", builtin::string_pad);
if (name == "string-rltrim") return MlValue("string-rltrim", builtin::string_rltrim);