diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/extract.hpp | 7 | ||||
-rw-r--r-- | src/common/operators.hpp | 47 | ||||
-rw-r--r-- | src/common/socket.cpp | 8 | ||||
-rw-r--r-- | src/common/socket.hpp | 3 | ||||
-rw-r--r-- | src/common/utils.cpp | 9 | ||||
-rw-r--r-- | src/common/utils.hpp | 70 |
6 files changed, 134 insertions, 10 deletions
diff --git a/src/common/extract.hpp b/src/common/extract.hpp index 3198d5d..ae1a74b 100644 --- a/src/common/extract.hpp +++ b/src/common/extract.hpp @@ -25,6 +25,7 @@ #include "const_array.hpp" #include "mmo.hpp" +#include "utils.hpp" template<class T, typename=typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, char>::value>::type> bool extract(const_string str, T *iv) @@ -58,6 +59,12 @@ bool extract(const_string str, T *iv) } } +inline +bool extract(const_string str, TimeT *tv) +{ + return extract(str, &tv->value); +} + // extra typename=void to workaround some duplicate overload rule template<class T, typename=typename std::enable_if<std::is_enum<T>::value>::type, typename=void> bool extract(const_string str, T *iv) diff --git a/src/common/operators.hpp b/src/common/operators.hpp new file mode 100644 index 0000000..3d44b81 --- /dev/null +++ b/src/common/operators.hpp @@ -0,0 +1,47 @@ +#ifndef OPERATORS_HPP +#define OPERATORS_HPP + +namespace _operators +{ + class Comparable {}; + + template<class T> + bool operator == (T l, T r) + { + return l.value == r.value; + } + + template<class T> + bool operator != (T l, T r) + { + return l.value != r.value; + } + + template<class T> + bool operator < (T l, T r) + { + return l.value < r.value; + } + + template<class T> + bool operator <= (T l, T r) + { + return l.value <= r.value; + } + + template<class T> + bool operator > (T l, T r) + { + return l.value > r.value; + } + + template<class T> + bool operator >= (T l, T r) + { + return l.value >= r.value; + } +} + +using _operators::Comparable; + +#endif // OPERATORS_HPP diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 96de47c..a8c1eee 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -161,7 +161,7 @@ void connect_client(int listen_fd) session[fd]->func_send = send_from_fifo; session[fd]->func_parse = default_func_parse; session[fd]->client_addr = client_address; - session[fd]->created = time(NULL); + session[fd]->created = TimeT::now(); session[fd]->connected = 0; currentuse++; @@ -213,7 +213,7 @@ int make_listen_port(uint16_t port) CREATE(session[fd], struct socket_data, 1); session[fd]->func_recv = connect_client; - session[fd]->created = time(NULL); + session[fd]->created = TimeT::now(); session[fd]->connected = 1; currentuse++; @@ -265,7 +265,7 @@ int make_connection(uint32_t ip, uint16_t port) session[fd]->func_recv = recv_to_fifo; session[fd]->func_send = send_from_fifo; session[fd]->func_parse = default_func_parse; - session[fd]->created = time(NULL); + session[fd]->created = TimeT::now(); session[fd]->connected = 1; currentuse++; @@ -377,7 +377,7 @@ void do_parsepacket(void) if (!session[i]) continue; if (!session[i]->connected - && time(NULL) - session[i]->created > CONNECT_TIMEOUT) + && static_cast<time_t>(TimeT::now()) - static_cast<time_t>(session[i]->created) > CONNECT_TIMEOUT) { PRINTF("Session #%d timed out\n", i); session[i]->eof = 1; diff --git a/src/common/socket.hpp b/src/common/socket.hpp index c5db89c..d7c6b9c 100644 --- a/src/common/socket.hpp +++ b/src/common/socket.hpp @@ -7,6 +7,7 @@ # include <cstdio> +# include "utils.hpp" # include "timer.t.hpp" // Struct declaration @@ -14,7 +15,7 @@ struct socket_data { /// Checks whether a newly-connected socket actually does anything - time_t created; + TimeT created; bool connected; /// Flag needed since structure must be freed in a server-dependent manner diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 33a96b4..49dce34 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -125,16 +125,17 @@ bool split_key_value(const std::string& line, std::string *w1, std::string *w2) static_assert(sizeof(timestamp_seconds_buffer) == 20, "seconds buffer"); static_assert(sizeof(timestamp_milliseconds_buffer) == 24, "millis buffer"); -void stamp_time(timestamp_seconds_buffer& out, time_t *t) +void stamp_time(timestamp_seconds_buffer& out, TimeT *t) { - time_t when = t ? *t : time(NULL); - strftime(out, 20, "%Y-%m-%d %H:%M:%S", gmtime(&when)); + struct tm when = t ? *t : TimeT::now(); + strftime(out, 20, "%Y-%m-%d %H:%M:%S", &when); } void stamp_time(timestamp_milliseconds_buffer& out) { struct timeval tv; gettimeofday(&tv, NULL); - strftime(out, 20, "%Y-%m-%d %H:%M:%S", gmtime(&tv.tv_sec)); + struct tm when = TimeT(tv.tv_sec); + strftime(out, 20, "%Y-%m-%d %H:%M:%S", &when); sprintf(out + 19, ".%03d", int(tv.tv_usec / 1000)); } diff --git a/src/common/utils.hpp b/src/common/utils.hpp index a9d0244..0de8d81 100644 --- a/src/common/utils.hpp +++ b/src/common/utils.hpp @@ -9,6 +9,7 @@ #include <string> #include "const_array.hpp" +#include "operators.hpp" #include "utils2.hpp" /* @@ -62,11 +63,78 @@ void strzcpy(char *dest, const char *src, size_t n) } } +// Exists in place of time_t, to give it a predictable printf-format. +// (on x86 and amd64, time_t == long, but not on x32) +static_assert(sizeof(long long) >= sizeof(time_t), "long long >= time_t"); +struct TimeT : Comparable +{ + long long value; + + // conversion + TimeT(time_t t=0) : value(t) {} + TimeT(struct tm t) : value(timegm(&t)) {} + operator time_t() { return value; } + operator struct tm() { return *gmtime(&value); } + + explicit operator bool() { return value; } + bool operator !() { return !value; } + + // prevent surprises + template<class T> + TimeT(T) = delete; + template<class T> + operator T() = delete; + + static + TimeT now() + { + // poisoned, but this is still in header-land + return time(NULL); + } + + bool error() + { + return value == -1; + } + bool okay() + { + return !error(); + } +}; + +inline +long long convert_for_printf(TimeT t) +{ + return t.value; +} + +inline +long long& convert_for_scanf(TimeT& t) +{ + return t.value; +} + typedef char timestamp_seconds_buffer[20]; typedef char timestamp_milliseconds_buffer[24]; -void stamp_time(timestamp_seconds_buffer&, time_t *t=nullptr); +void stamp_time(timestamp_seconds_buffer&, TimeT *t=nullptr); void stamp_time(timestamp_milliseconds_buffer&); void log_with_timestamp(FILE *out, const_string line); +#define TIMESTAMP_DUMMY "YYYY-MM-DD HH:MM:SS" +static_assert(sizeof(TIMESTAMP_DUMMY) == sizeof(timestamp_seconds_buffer), + "timestamp size"); +#define WITH_TIMESTAMP(str) str TIMESTAMP_DUMMY +// str: prefix: YYYY-MM-DD HH:MM:SS +// sizeof: 01234567890123456789012345678 +// str + sizeof: ^ +// -1: ^ +#define REPLACE_TIMESTAMP(str, t) \ + stamp_time( \ + reinterpret_cast<timestamp_seconds_buffer *>( \ + str + sizeof(str) \ + )[-1], \ + &t \ + ) + #endif //UTILS_HPP |