#pragma once #include "defines.hpp" template class MaxLengthCString { public: MaxLengthCString() : m_strPos(0), m_boundsExceeded(false) { m_str[0] = '\0'; } inline void operator+=(char const* rhs) { write(rhs, strlen(rhs)); } void write(char const* data, size_t len) { if (m_boundsExceeded || m_strPos + len >= N) { m_boundsExceeded = true; return; } memcpy(m_str + m_strPos, data, len); m_strPos += len; m_str[m_strPos] = '\0'; } void write(char c) { if (m_boundsExceeded || m_strPos + 1 >= N) { m_boundsExceeded = true; return; } m_str[m_strPos] = c; m_strPos++; } void write_num(size_t num) { size_t d = 1; while (num / 10 >= d) d *= 10; while (num > 0) { char c = '0' + (num / d); write(c); num %= d; d /= 10; } } char const* get_str() { return m_str; }; bool boundsExceeded() { return m_boundsExceeded; }; private: char m_str[N]; size_t m_strPos; bool m_boundsExceeded; }; template class BufFileWriter { public: inline BufFileWriter(int fd_) : m_writeBufPos(0), m_fd(fd_) {} ~BufFileWriter() { flush(); } void write(char const* data, size_t len) { while (len > 0) { size_t to_add = std::min(len, (size_t)BUFSIZE - m_writeBufPos); memcpy(m_writeBuf + m_writeBufPos, data, to_add); data += to_add; len -= to_add; m_writeBufPos += to_add; if (m_writeBufPos == BUFSIZE) flush(); } } inline void write(char c) { if (m_writeBufPos == BUFSIZE) flush(); m_writeBuf[m_writeBufPos] = c; m_writeBufPos++; } inline void operator+=(char const* str) { write(str, strlen(str)); } inline void operator+=(std::string_view str) { write(str.data(), str.size()); } inline void operator+=(char c) { write(c); } void writeNum(size_t num) { size_t d = 1; while (num / 10 >= d) d *= 10; while (num > 0) { char c = '0' + (num / d); write(c); num %= d; d /= 10; } } void writeCmdOutput(const char* cmd) { int pipefd[2]; if (pipe(pipefd) < 0) { *this += " failmsg(pipefd[1]); failmsg += " 0) { write(readbuf, len); } if (len < 0) { *this += "