summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/extract.hpp7
-rw-r--r--src/common/operators.hpp47
-rw-r--r--src/common/socket.cpp8
-rw-r--r--src/common/socket.hpp3
-rw-r--r--src/common/utils.cpp9
-rw-r--r--src/common/utils.hpp70
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