[ox] Add logconn for Bullock logging
This commit is contained in:
parent
e1fa48ea2f
commit
94cb2e982a
1
deps/ox/src/ox/CMakeLists.txt
vendored
1
deps/ox/src/ox/CMakeLists.txt
vendored
@ -5,6 +5,7 @@ add_subdirectory(clargs)
|
|||||||
add_subdirectory(claw)
|
add_subdirectory(claw)
|
||||||
add_subdirectory(event)
|
add_subdirectory(event)
|
||||||
add_subdirectory(fs)
|
add_subdirectory(fs)
|
||||||
|
add_subdirectory(logconn)
|
||||||
add_subdirectory(mc)
|
add_subdirectory(mc)
|
||||||
add_subdirectory(model)
|
add_subdirectory(model)
|
||||||
add_subdirectory(preloader)
|
add_subdirectory(preloader)
|
||||||
|
34
deps/ox/src/ox/logconn/CMakeLists.txt
vendored
Normal file
34
deps/ox/src/ox/logconn/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
OxLogConn
|
||||||
|
logconn.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set_property(
|
||||||
|
TARGET
|
||||||
|
OxLogConn
|
||||||
|
PROPERTY
|
||||||
|
POSITION_INDEPENDENT_CODE ON
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
OxLogConn PUBLIC
|
||||||
|
OxStd
|
||||||
|
OxMetalClaw
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
circularbuff.hpp
|
||||||
|
logconn.hpp
|
||||||
|
DESTINATION
|
||||||
|
include/ox/logconn
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS
|
||||||
|
OxLogConn
|
||||||
|
LIBRARY DESTINATION lib/ox
|
||||||
|
ARCHIVE DESTINATION lib/ox
|
||||||
|
)
|
99
deps/ox/src/ox/logconn/circularbuff.hpp
vendored
Normal file
99
deps/ox/src/ox/logconn/circularbuff.hpp
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 - 2022 gary@drinkingtea.net
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ox/std/assert.hpp>
|
||||||
|
#include <ox/std/buffer.hpp>
|
||||||
|
#include <ox/std/units.hpp>
|
||||||
|
|
||||||
|
namespace ox::detail {
|
||||||
|
|
||||||
|
class CirculerBuffer {
|
||||||
|
private:
|
||||||
|
std::size_t m_readPt = 0;
|
||||||
|
std::size_t m_writePt = 0;
|
||||||
|
ox::Buffer m_buff = ox::Buffer(ox::units::MB);
|
||||||
|
|
||||||
|
private:
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr auto avail() const noexcept {
|
||||||
|
if (m_writePt >= m_readPt) {
|
||||||
|
return m_buff.size() - (m_writePt - m_readPt);
|
||||||
|
} else {
|
||||||
|
return (m_buff.size() - m_writePt) - (m_buff.size() - m_readPt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr ox::Error put(char v) noexcept {
|
||||||
|
return write(&v, 1);
|
||||||
|
if (1 > avail()) {
|
||||||
|
return OxError(1, "Insufficient space in buffer");
|
||||||
|
}
|
||||||
|
m_buff[m_writePt] = v;
|
||||||
|
++m_writePt;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr ox::Error write(const char *buff, std::size_t sz) noexcept {
|
||||||
|
if (sz > avail()) {
|
||||||
|
return OxError(1, "Insufficient space in buffer");
|
||||||
|
}
|
||||||
|
// write seg 1
|
||||||
|
const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt);
|
||||||
|
ox_memcpy(&m_buff[m_writePt], &buff[0], seg1Sz);
|
||||||
|
m_writePt += sz;
|
||||||
|
if (seg1Sz != sz) {
|
||||||
|
m_writePt -= m_buff.size();
|
||||||
|
// write seg 2
|
||||||
|
const auto seg2Sz = sz - seg1Sz;
|
||||||
|
ox_memcpy(&m_buff[0], &buff[seg1Sz], seg2Sz);
|
||||||
|
oxAssert(m_buff[0] == buff[seg1Sz], "break");
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr ox::Error seekp(std::size_t bytesFwd) noexcept {
|
||||||
|
if (bytesFwd > avail()) {
|
||||||
|
return OxError(1, "Insufficient space in buffer to seek that far ahead");
|
||||||
|
}
|
||||||
|
m_writePt += bytesFwd;
|
||||||
|
if (m_writePt > m_buff.size()) {
|
||||||
|
m_writePt -= m_buff.size();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr ox::Error seekp(int, ios_base::seekdir) {
|
||||||
|
return OxError(1, "Unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr std::size_t tellp() const noexcept {
|
||||||
|
return m_buff.size() - avail();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr std::size_t read(char *out, std::size_t outSize) noexcept {
|
||||||
|
const auto bytesRead = ox::min(outSize, m_buff.size() - avail());
|
||||||
|
// read seg 1
|
||||||
|
const auto seg1Sz = ox::min(bytesRead, m_buff.size() - m_readPt);
|
||||||
|
ox_memcpy(&out[0], &m_buff[m_readPt], seg1Sz);
|
||||||
|
m_readPt += bytesRead;
|
||||||
|
if (seg1Sz != bytesRead) {
|
||||||
|
m_readPt -= m_buff.size();
|
||||||
|
// read seg 2
|
||||||
|
const auto seg2Sz = bytesRead - seg1Sz;
|
||||||
|
ox_memcpy(&out[seg1Sz], &m_buff[0], seg2Sz);
|
||||||
|
}
|
||||||
|
return bytesRead;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
90
deps/ox/src/ox/logconn/logconn.cpp
vendored
Normal file
90
deps/ox/src/ox/logconn/logconn.cpp
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 - 2022 gary@drinkingtea.net
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef OX_USE_STDLIB
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include <ox/std/bit.hpp>
|
||||||
|
|
||||||
|
#include "logconn.hpp"
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
|
||||||
|
using namespace trace;
|
||||||
|
|
||||||
|
LoggerConn::LoggerConn() noexcept: m_netThread([this]{this->msgSend();}) {
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerConn::~LoggerConn() noexcept {
|
||||||
|
m_running = false;
|
||||||
|
m_waitCond.notify_one();
|
||||||
|
m_netThread.join();
|
||||||
|
if (m_socket) {
|
||||||
|
close(m_socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ox::Error LoggerConn::initConn(const char *appName) noexcept {
|
||||||
|
sockaddr_in addr{};
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
addr.sin_port = htons(5590);
|
||||||
|
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
oxReturnError(OxError(connect(m_socket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))));
|
||||||
|
return sendInit({.appName = appName});
|
||||||
|
}
|
||||||
|
|
||||||
|
ox::Error LoggerConn::send(const char *buff, std::size_t len) const noexcept {
|
||||||
|
std::size_t totalSent = 0;
|
||||||
|
while (totalSent < len) {
|
||||||
|
//std::fprintf(stdout, "Sending %lu/%lu bytes on socket %d\n", len, totalSent, m_socket);
|
||||||
|
const auto sent = ::send(m_socket, buff, len, 0);
|
||||||
|
if (sent < 0) {
|
||||||
|
std::fprintf(stderr, "Could not send msg\n");
|
||||||
|
return OxError(1, "Could not send msg");
|
||||||
|
}
|
||||||
|
totalSent += static_cast<std::size_t>(sent);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
ox::Error LoggerConn::send(const TraceMsg &msg) noexcept {
|
||||||
|
return send(MsgId::TraceEvent, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ox::Error LoggerConn::sendInit(const InitTraceMsg &msg) noexcept {
|
||||||
|
return send(MsgId::Init, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoggerConn::msgSend() noexcept {
|
||||||
|
while (true) {
|
||||||
|
std::unique_lock lk(m_waitMut);
|
||||||
|
m_waitCond.wait(lk);
|
||||||
|
if (!m_running) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::lock_guard buffLk(m_buffMut);
|
||||||
|
while (true) {
|
||||||
|
ox::Array<char, ox::units::KB> tmp;
|
||||||
|
const auto read = m_buff.read(tmp.data(), tmp.size());
|
||||||
|
if (!read) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//std::printf("LoggerConn: sending %lu bytes\n", read);
|
||||||
|
oxIgnoreError(send(tmp.data(), read));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
78
deps/ox/src/ox/logconn/logconn.hpp
vendored
Normal file
78
deps/ox/src/ox/logconn/logconn.hpp
vendored
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 - 2022 gary@drinkingtea.net
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef OX_USE_STDLIB
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ox/mc/write.hpp>
|
||||||
|
#include <ox/std/trace.hpp>
|
||||||
|
|
||||||
|
#include "circularbuff.hpp"
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
|
||||||
|
#ifdef OX_USE_STDLIB
|
||||||
|
class LoggerConn: public trace::Logger {
|
||||||
|
private:
|
||||||
|
int m_socket = 0;
|
||||||
|
detail::CirculerBuffer m_buff;
|
||||||
|
std::thread m_netThread;
|
||||||
|
std::condition_variable m_waitCond;
|
||||||
|
std::mutex m_waitMut;
|
||||||
|
std::mutex m_buffMut;
|
||||||
|
bool m_running = true;
|
||||||
|
public:
|
||||||
|
LoggerConn() noexcept;
|
||||||
|
LoggerConn(const LoggerConn&) noexcept = delete;
|
||||||
|
~LoggerConn() noexcept override;
|
||||||
|
LoggerConn &operator=(const LoggerConn&) noexcept = delete;
|
||||||
|
ox::Error send(const trace::TraceMsg&) noexcept final;
|
||||||
|
ox::Error sendInit(const trace::InitTraceMsg&) noexcept final;
|
||||||
|
ox::Error initConn(const char *appName = "") noexcept;
|
||||||
|
ox::Error send(const char *buff, std::size_t len) const noexcept;
|
||||||
|
private:
|
||||||
|
void msgSend() noexcept;
|
||||||
|
ox::Error send(trace::MsgId msgId, const auto &msg) noexcept {
|
||||||
|
ox::Array<char, 10 * ox::units::KB> buff;
|
||||||
|
std::size_t sz = 0;
|
||||||
|
oxReturnError(ox::writeMC(&buff[0], buff.size(), &msg, &sz));
|
||||||
|
//std::printf("sz: %lu\n", sz);
|
||||||
|
oxRequire(szBuff, serialize(static_cast<uint32_t>(sz)));
|
||||||
|
std::unique_lock buffLk(m_buffMut);
|
||||||
|
oxReturnError(m_buff.put(static_cast<char>(msgId)));
|
||||||
|
oxReturnError(m_buff.write(szBuff.data(), szBuff.size()));
|
||||||
|
oxReturnError(m_buff.write(buff.data(), sz));
|
||||||
|
buffLk.unlock();
|
||||||
|
m_waitCond.notify_one();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
class LoggerConn: public trace::Logger {
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
constexpr LoggerConn() noexcept = default;
|
||||||
|
LoggerConn(const LoggerConn&) noexcept = delete;
|
||||||
|
constexpr ~LoggerConn() noexcept override = default;
|
||||||
|
LoggerConn &operator=(const LoggerConn&) noexcept = delete;
|
||||||
|
ox::Error send(const trace::TraceMsg&) noexcept final { return {}; }
|
||||||
|
static ox::Error initConn() noexcept { return {}; }
|
||||||
|
static ox::Error send(const char*, std::size_t) noexcept { return {}; }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
8
deps/ox/src/ox/mc/write.hpp
vendored
8
deps/ox/src/ox/mc/write.hpp
vendored
@ -41,7 +41,7 @@ class MetalClawWriter {
|
|||||||
public:
|
public:
|
||||||
constexpr MetalClawWriter(uint8_t *buff, std::size_t buffLen, int unionIdx = -1) noexcept;
|
constexpr MetalClawWriter(uint8_t *buff, std::size_t buffLen, int unionIdx = -1) noexcept;
|
||||||
|
|
||||||
constexpr ~MetalClawWriter() noexcept;
|
constexpr ~MetalClawWriter() noexcept = default;
|
||||||
|
|
||||||
constexpr Error field(const char*, CommonPtrWith<int8_t> auto *val) noexcept;
|
constexpr Error field(const char*, CommonPtrWith<int8_t> auto *val) noexcept;
|
||||||
constexpr Error field(const char*, CommonPtrWith<int16_t> auto *val) noexcept;
|
constexpr Error field(const char*, CommonPtrWith<int16_t> auto *val) noexcept;
|
||||||
@ -159,12 +159,6 @@ constexpr MetalClawWriter::MetalClawWriter(uint8_t *buff, std::size_t buffLen, i
|
|||||||
m_buff(buff) {
|
m_buff(buff) {
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr MetalClawWriter::~MetalClawWriter() noexcept {
|
|
||||||
if (m_field != m_fields) {
|
|
||||||
oxTrace("ox::mc::MetalClawWriter::error") << "MetalClawReader: incorrect fields number given";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<int8_t> auto *val) noexcept {
|
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<int8_t> auto *val) noexcept {
|
||||||
return appendInteger(*val);
|
return appendInteger(*val);
|
||||||
}
|
}
|
||||||
|
2
deps/ox/src/ox/model/CMakeLists.txt
vendored
2
deps/ox/src/ox/model/CMakeLists.txt
vendored
@ -46,4 +46,4 @@ install(TARGETS OxModel
|
|||||||
|
|
||||||
if(OX_RUN_TESTS)
|
if(OX_RUN_TESTS)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
endif()
|
endif()
|
||||||
|
2
deps/ox/src/ox/model/def.hpp
vendored
2
deps/ox/src/ox/model/def.hpp
vendored
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <ox/std/concepts.hpp>
|
#include <ox/std/concepts.hpp>
|
||||||
|
|
||||||
#define oxModelBegin(modelName) constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept { io->template setTypeInfo<modelName>();
|
#define oxModelBegin(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith<modelName> auto *o) noexcept { io->template setTypeInfo<modelName>();
|
||||||
#define oxModelEnd() return OxError(0); }
|
#define oxModelEnd() return OxError(0); }
|
||||||
#define oxModelField(fieldName) oxReturnError(io->field(#fieldName, &o->fieldName));
|
#define oxModelField(fieldName) oxReturnError(io->field(#fieldName, &o->fieldName));
|
||||||
#define oxModelFieldRename(serFieldName, objFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName));
|
#define oxModelFieldRename(serFieldName, objFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName));
|
||||||
|
1
deps/ox/src/ox/model/modelvalue.hpp
vendored
1
deps/ox/src/ox/model/modelvalue.hpp
vendored
@ -12,6 +12,7 @@
|
|||||||
#include <ox/std/serialize.hpp>
|
#include <ox/std/serialize.hpp>
|
||||||
#include <ox/std/string.hpp>
|
#include <ox/std/string.hpp>
|
||||||
#include <ox/std/trace.hpp>
|
#include <ox/std/trace.hpp>
|
||||||
|
#include <ox/std/typetraits.hpp>
|
||||||
#include <ox/std/types.hpp>
|
#include <ox/std/types.hpp>
|
||||||
#include <ox/std/utility.hpp>
|
#include <ox/std/utility.hpp>
|
||||||
#include <ox/std/vector.hpp>
|
#include <ox/std/vector.hpp>
|
||||||
|
2
deps/ox/src/ox/std/array.hpp
vendored
2
deps/ox/src/ox/std/array.hpp
vendored
@ -133,7 +133,7 @@ class Array {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T m_items[ArraySize];
|
T m_items[ArraySize]{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr Array() noexcept = default;
|
constexpr Array() noexcept = default;
|
||||||
|
2
deps/ox/src/ox/std/fmt.hpp
vendored
2
deps/ox/src/ox/std/fmt.hpp
vendored
@ -62,7 +62,7 @@ StringView toStringView(const std::string &s) noexcept {
|
|||||||
#if __has_include(<QString>)
|
#if __has_include(<QString>)
|
||||||
template<bool force = false>
|
template<bool force = false>
|
||||||
inline StringView toStringView(const QString &s) noexcept {
|
inline StringView toStringView(const QString &s) noexcept {
|
||||||
return s.toUtf8();
|
return s.toUtf8().data();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
20
deps/ox/src/ox/std/string.hpp
vendored
20
deps/ox/src/ox/std/string.hpp
vendored
@ -304,8 +304,8 @@ constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operat
|
|||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(char c) noexcept {
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(char c) noexcept {
|
||||||
char str[] = {c, 0};
|
ox::Array<char, 2> str{c, 0};
|
||||||
set(str);
|
set(str.data());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,23 +317,25 @@ constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operat
|
|||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(int64_t i) noexcept {
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(int64_t i) noexcept {
|
||||||
char str[65] = {};
|
ox::Array<char, 65> str{};
|
||||||
ox_itoa(i, str);
|
ox_itoa(i, str.data());
|
||||||
set(str);
|
set(str.data());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(uint64_t i) noexcept {
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(uint64_t i) noexcept {
|
||||||
char str[65] = {};
|
ox::Array<char, 65> str{};
|
||||||
ox_itoa(i, str);
|
ox_itoa(i, str.data());
|
||||||
set(str);
|
set(str.data());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(const BasicString &src) noexcept {
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(const BasicString &src) noexcept {
|
||||||
set(src);
|
if (this != &src) {
|
||||||
|
set(src);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
deps/ox/src/ox/std/stringview.hpp
vendored
8
deps/ox/src/ox/std/stringview.hpp
vendored
@ -43,6 +43,7 @@ class StringView {
|
|||||||
m_max = max;
|
m_max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr auto offset() const noexcept {
|
constexpr auto offset() const noexcept {
|
||||||
return m_offset;
|
return m_offset;
|
||||||
}
|
}
|
||||||
@ -220,6 +221,7 @@ class StringView {
|
|||||||
return m_str[m_len - 1];
|
return m_str[m_len - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr auto substr(std::size_t pos) const noexcept {
|
constexpr auto substr(std::size_t pos) const noexcept {
|
||||||
return StringView(m_str + pos, m_len - pos);
|
return StringView(m_str + pos, m_len - pos);
|
||||||
}
|
}
|
||||||
@ -228,11 +230,7 @@ class StringView {
|
|||||||
return m_str[i];
|
return m_str[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr auto operator=(const StringView &other) noexcept {
|
constexpr ox::StringView &operator=(const StringView &other) noexcept = default;
|
||||||
m_str = other.m_str;
|
|
||||||
m_len = other.m_len;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr auto operator==(const StringView &other) const noexcept {
|
constexpr auto operator==(const StringView &other) const noexcept {
|
||||||
if (other.len() != len()) {
|
if (other.len() != len()) {
|
||||||
|
26
deps/ox/src/ox/std/trace.cpp
vendored
26
deps/ox/src/ox/std/trace.cpp
vendored
@ -14,4 +14,30 @@ void init() {
|
|||||||
oxTraceInitHook();
|
oxTraceInitHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(Logger *logger) {
|
||||||
|
oxTraceInitHook();
|
||||||
|
setLogger(logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
class NullLogger: public Logger {
|
||||||
|
public:
|
||||||
|
ox::Error send(const TraceMsg&) noexcept final {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
ox::Error sendInit(const InitTraceMsg&) noexcept final {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static NullLogger defaultLogger;
|
||||||
|
static Logger *logger = &defaultLogger;
|
||||||
|
|
||||||
|
void setLogger(Logger *logger) noexcept {
|
||||||
|
trace::logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(const TraceMsg &msg) noexcept {
|
||||||
|
oxIgnoreError(logger->send(msg));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
80
deps/ox/src/ox/std/trace.hpp
vendored
80
deps/ox/src/ox/std/trace.hpp
vendored
@ -30,9 +30,35 @@ void oxTraceHook(const char *file, int line, const char *ch, const char *msg);
|
|||||||
|
|
||||||
namespace ox::trace {
|
namespace ox::trace {
|
||||||
|
|
||||||
|
enum class MsgId: char {
|
||||||
|
Init = 2,
|
||||||
|
TraceEvent = 1,
|
||||||
|
Json = '{',
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TraceMsgRcv {
|
||||||
|
static constexpr auto TypeName = "net.drinkingtea.ox.trace.TraceMsg";
|
||||||
|
static constexpr auto TypeVersion = 1;
|
||||||
|
BasicString<50> file = "";
|
||||||
|
int line = 0;
|
||||||
|
uint64_t time = 0;
|
||||||
|
BasicString<50> ch = "";
|
||||||
|
BasicString<100> msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr Error model(T *io, ox::CommonPtrWith<TraceMsgRcv> auto *obj) noexcept {
|
||||||
|
io->template setTypeInfo<TraceMsgRcv>();
|
||||||
|
oxReturnError(io->field("file", &obj->file));
|
||||||
|
oxReturnError(io->field("line", &obj->line));
|
||||||
|
oxReturnError(io->field("time", &obj->time));
|
||||||
|
oxReturnError(io->field("ch", &obj->ch));
|
||||||
|
oxReturnError(io->field("msg", &obj->msg));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
struct TraceMsg {
|
struct TraceMsg {
|
||||||
static constexpr auto TypeName = "net.drinkingtea.ox.trace.TraceMsg";
|
static constexpr auto TypeName = "net.drinkingtea.ox.trace.TraceMsg";
|
||||||
static constexpr auto Fields = 5;
|
|
||||||
static constexpr auto TypeVersion = 1;
|
static constexpr auto TypeVersion = 1;
|
||||||
const char *file = "";
|
const char *file = "";
|
||||||
int line = 0;
|
int line = 0;
|
||||||
@ -42,16 +68,58 @@ struct TraceMsg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr Error model(T *io, TraceMsg *obj) {
|
constexpr Error model(T *io, ox::CommonPtrWith<TraceMsg> auto *obj) noexcept {
|
||||||
io->template setTypeInfo<TraceMsg>();
|
io->template setTypeInfo<TraceMsg>();
|
||||||
oxReturnError(io->field("ch", &obj->ch));
|
oxReturnError(io->fieldCString("file", &obj->file));
|
||||||
oxReturnError(io->field("file", &obj->file));
|
|
||||||
oxReturnError(io->field("line", &obj->line));
|
oxReturnError(io->field("line", &obj->line));
|
||||||
oxReturnError(io->field("time", &obj->time));
|
oxReturnError(io->field("time", &obj->time));
|
||||||
|
oxReturnError(io->fieldCString("ch", &obj->ch));
|
||||||
oxReturnError(io->field("msg", &obj->msg));
|
oxReturnError(io->field("msg", &obj->msg));
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct InitTraceMsgRcv {
|
||||||
|
static constexpr auto TypeName = "net.drinkingtea.ox.trace.InitTraceMsg";
|
||||||
|
static constexpr auto TypeVersion = 1;
|
||||||
|
ox::String appName;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr Error model(T *io, ox::CommonPtrWith<InitTraceMsgRcv> auto *obj) noexcept {
|
||||||
|
io->template setTypeInfo<InitTraceMsgRcv>();
|
||||||
|
oxReturnError(io->field("appName", &obj->appName));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct InitTraceMsg {
|
||||||
|
static constexpr auto TypeName = "net.drinkingtea.ox.trace.InitTraceMsg";
|
||||||
|
static constexpr auto TypeVersion = 1;
|
||||||
|
const char *appName = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr Error model(T *io, ox::CommonPtrWith<InitTraceMsg> auto *obj) noexcept {
|
||||||
|
io->template setTypeInfo<InitTraceMsg>();
|
||||||
|
oxReturnError(io->fieldCString("appName", &obj->appName));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
public:
|
||||||
|
constexpr virtual ~Logger() noexcept = default;
|
||||||
|
virtual ox::Error send(const TraceMsg&) noexcept = 0;
|
||||||
|
virtual ox::Error sendInit(const InitTraceMsg&) noexcept = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param logger pointer to the new logger, does NOT take ownership
|
||||||
|
*/
|
||||||
|
void setLogger(Logger *logger) noexcept;
|
||||||
|
|
||||||
|
void send(const TraceMsg &msg) noexcept;
|
||||||
|
|
||||||
class OutStream {
|
class OutStream {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -109,6 +177,7 @@ class OutStream {
|
|||||||
|
|
||||||
inline ~OutStream() noexcept {
|
inline ~OutStream() noexcept {
|
||||||
oxTraceHook(m_msg.file, m_msg.line, m_msg.ch, m_msg.msg.c_str());
|
oxTraceHook(m_msg.file, m_msg.line, m_msg.ch, m_msg.msg.c_str());
|
||||||
|
send(m_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr OutStream &operator<<(Integer_c auto v) noexcept;
|
constexpr OutStream &operator<<(Integer_c auto v) noexcept;
|
||||||
@ -238,5 +307,6 @@ inline void logError(const char *file, int line, const Error &err) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
void init(Logger *logger);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
4
deps/ox/src/ox/std/tracehook.cpp
vendored
4
deps/ox/src/ox/std/tracehook.cpp
vendored
@ -72,13 +72,17 @@ void oxTraceHook([[maybe_unused]] const char *file, [[maybe_unused]] int line,
|
|||||||
std::cout << " " << file << ':' << line << "\n";
|
std::cout << " " << file << ':' << line << "\n";
|
||||||
} else if (ox_strcmp(ch, "debug") == 0 || ox_strcmp(ch, "info") == 0) {
|
} else if (ox_strcmp(ch, "debug") == 0 || ox_strcmp(ch, "info") == 0) {
|
||||||
printf("%s\n", msg);
|
printf("%s\n", msg);
|
||||||
|
fflush(stdout);
|
||||||
} else if (ox_strcmp(ch, "stdout") == 0) {
|
} else if (ox_strcmp(ch, "stdout") == 0) {
|
||||||
printf("%s", msg);
|
printf("%s", msg);
|
||||||
|
fflush(stdout);
|
||||||
} else if (ox_strcmp(ch, "stderr") == 0) {
|
} else if (ox_strcmp(ch, "stderr") == 0) {
|
||||||
printf("%s", msg);
|
printf("%s", msg);
|
||||||
|
fflush(stdout);
|
||||||
} else if (ox_strcmp(ch, "error") == 0) {
|
} else if (ox_strcmp(ch, "error") == 0) {
|
||||||
//std::cerr << "\033[31;1;1mERROR:\033[0m (" << file << ':' << line << "): " << msg << '\n';
|
//std::cerr << "\033[31;1;1mERROR:\033[0m (" << file << ':' << line << "): " << msg << '\n';
|
||||||
fprintf(stderr, "\033[31;1;1mERROR:\033[0m (%s:%d): %s\n", file, line, msg);
|
fprintf(stderr, "\033[31;1;1mERROR:\033[0m (%s:%d): %s\n", file, line, msg);
|
||||||
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (ox_strcmp(ch, "info") == 0) {
|
if (ox_strcmp(ch, "info") == 0) {
|
||||||
|
4
deps/ox/src/ox/std/types.hpp
vendored
4
deps/ox/src/ox/std/types.hpp
vendored
@ -15,6 +15,8 @@ using size_t = decltype(alignof(int));
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using size_t = decltype(alignof(int));
|
||||||
|
|
||||||
#if __has_include(<cstdint>)
|
#if __has_include(<cstdint>)
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -160,4 +162,4 @@ static_assert(sizeof(uint8_t) == 1, "uint8_t is wrong size");
|
|||||||
static_assert(sizeof(uint16_t) == 2, "uint16_t is wrong size");
|
static_assert(sizeof(uint16_t) == 2, "uint16_t is wrong size");
|
||||||
static_assert(sizeof(uint32_t) == 4, "uint32_t is wrong size");
|
static_assert(sizeof(uint32_t) == 4, "uint32_t is wrong size");
|
||||||
static_assert(sizeof(uint64_t) == 8, "uint64_t is wrong size");
|
static_assert(sizeof(uint64_t) == 8, "uint64_t is wrong size");
|
||||||
static_assert(sizeof(uintptr_t) == sizeof(void*), "uintptr_t is wrong size");
|
static_assert(sizeof(uintptr_t) == sizeof(void*), "uintptr_t is wrong size");
|
||||||
|
Loading…
Reference in New Issue
Block a user