/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: IPCHandle.cpp Date: 2022-4-13 Author: Reece ***/ #include #include "IPC.hpp" #include "IPCHandle.hpp" namespace Aurora::IO::IPC { #define AURORA_IPC_BRAND "AuroraIPC_" // A horribly inefficient parsable handle. // Dead simple to implement, it's 22:07, and i wanna sleep soon. // We should text serialize a bitmap later... IPCHandle::IPCHandle() { AuMemset(this, 0, sizeof(*this)); } void IPCHandle::NewId(bool a, bool b, bool c, bool d) { this->flags[0] = a; this->flags[1] = b; this->flags[2] = c; this->flags[3] = d; this->word = 0; NewId(); } void IPCHandle::NewId(AuUInt len) { AuMemset(this->flags, 0, sizeof(this->flags)); this->word = len; NewId(); } void IPCHandle::NewId() { #if defined(AURORA_IS_POSIX_DERIVED) while (!this->cookie) { this->cookie = AuRng::RngU32(); } this->pid = getpid(); #else auto temp = AuRng::ReadString(AuArraySize(this->path), AuRng::ERngStringCharacters::eAlphaNumericCharacters); AuMemcpy(this->path, temp.data(), temp.size()); #endif } bool IPCHandle::FromString(const AuString &in) { if (in.size() < 4) { return false; } this->word = 0; this->flags[0] = in[0] == 'Y'; this->flags[1] = in[1] == 'Y'; this->flags[2] = in[2] == 'Y'; this->flags[3] = in[3] == 'Y'; #if defined(AURORA_IS_MODERNNT_DERIVED) if (in.size() < 4 + 16) { return false; } AuMemcpy(this->path, &in[4], 16); if (in.size() > 4 + 16) { char *endPtr; auto word = strtoll(in.c_str() + 4 + 16, &endPtr, 10); if (errno == ERANGE) { return false; } if (*endPtr != '\00') { return false; } this->word = word; return true; } else { return true; } #endif #if defined(AURORA_IS_POSIX_DERIVED) char *endPtr; auto word = strtoll(in.c_str() + 4, &endPtr, 10); if (errno == ERANGE) { return false; } if (*endPtr != '_') { return false; } this->cookie = word; if (this->cookie == 0) { return false; } word = strtoll(endPtr + 1, &endPtr, 10); if (errno == ERANGE) { return false; } if (*endPtr != '_') { return false; } this->word = word; word = strtoll(endPtr + 1, &endPtr, 10); if (errno == ERANGE) { return false; } if (*endPtr != '\00') { return false; } this->pid = word; return true; #endif } AuString IPCHandle::ToString() const { AuString ret; #if defined(AURORA_IS_MODERNNT_DERIVED) if (!AuTryResize(ret, 4 + 16)) { return {}; } #endif #if defined(AURORA_IS_POSIX_DERIVED) if (!AuTryResize(ret, 4)) { return {}; } #endif ret[0] = this->flags[0] ? 'Y' : 'N'; ret[1] = this->flags[1] ? 'Y' : 'N'; ret[2] = this->flags[2] ? 'Y' : 'N'; ret[3] = this->flags[3] ? 'Y' : 'N'; #if defined(AURORA_IS_MODERNNT_DERIVED) AuMemcpy(&ret[4], this->path, 16); if (this->word) { ret += AuToString(this->word); } #endif #if defined(AURORA_IS_POSIX_DERIVED) ret += AuToString(this->cookie); ret += '_'; ret += AuToString(this->word); ret += '_'; ret += AuToString(this->pid); #endif return ret; } AuString IPCHandle::ToNTPath() const { if (this->flags[3]) { return "Global\\" AURORA_IPC_BRAND + AuString(this->path, this->path + 16); } else { return "Local\\" AURORA_IPC_BRAND + AuString(this->path, this->path + 16); } } AuUInt32 IPCHandle::ToUnixServerCookie() const { return this->cookie; } #if defined(AURORA_IS_POSIX_DERIVED) pid_t IPCHandle::ToUnixPid() const { return this->pid; } #endif }