AuroraRuntime/Source/IO/IPC/IPCHandle.cpp

224 lines
4.5 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IPCHandle.cpp
Date: 2022-4-13
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#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
}