/*
Copyright 2006-2026 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see .
*/
#include "logring.h"
#include
#include
/**
@brief LogRing::LogRing
Preallocates all kCapacityEntries slots up front -- the only
allocation this class ever does.
*/
LogRing::LogRing()
{
m_entries.resize(kCapacityEntries);
}
/**
@brief LogRing::append
@param line one already-formatted log line (no further formatting
is done here). Truncated to kEntryBytes - 1 bytes if longer, with a
trailing marker, so the stored entry is always a complete,
independently-readable line.
*/
void LogRing::append(const QByteArray &line)
{
static const char kMarker[] = "...[ring-truncated]\n";
const int marker_len = static_cast(sizeof(kMarker)) - 1;
QMutexLocker locker(&m_mutex);
Entry &slot = m_entries[static_cast(m_next_index)];
if (line.size() < kEntryBytes) {
std::memcpy(slot.data, line.constData(), static_cast(line.size()));
slot.length = line.size();
} else {
const int keep = kEntryBytes - marker_len;
std::memcpy(slot.data, line.constData(), static_cast(keep));
std::memcpy(slot.data + keep, kMarker, static_cast(marker_len));
slot.length = kEntryBytes;
}
m_next_index = (m_next_index + 1) % kCapacityEntries;
if (m_count < kCapacityEntries) {
++m_count;
}
}
/**
@brief LogRing::snapshot
@return the entries currently held, oldest first. Safe to call from
normal (non-signal) code only.
*/
QVector LogRing::snapshot() const
{
QMutexLocker locker(&m_mutex);
QVector result;
result.reserve(m_count);
const int start = (m_count < kCapacityEntries) ? 0 : m_next_index;
for (int i = 0; i < m_count; ++i) {
const Entry &slot = m_entries[static_cast((start + i) % kCapacityEntries)];
result.append(QByteArray(slot.data, slot.length));
}
return result;
}
void LogRing::clear()
{
QMutexLocker locker(&m_mutex);
m_next_index = 0;
m_count = 0;
}