AuroraRuntime/Source/IO/FS/FileAttrs.NT.cpp
Jamie Reece Wilson 83f34b0c47 [*] I was right. String views are [mostly] pointless (*)
03:28:55:638  17>2 of 53388 functions (<0.1%) were compiled, the rest were copied from previous compilation.
03:28:55:638  17>  0 functions were new in current compilation
03:28:55:638  17>  65 functions had inline decision re-evaluated but remain unchanged
03:28:56:749  17>Finished generating code

the header of const AuString & is the same as std::string_view therefore nothing changes. in fact, we still need to alloc strings a bunch of times for a zero terminated string. worse, <c++20 always allocs each time we want to access a hashmap with o(1) lookup, making small hashmaps kinda pointless when we always have to alloc+copy (thx std)

perhaps this will help some language binders
2024-04-19 05:58:08 +01:00

153 lines
4.1 KiB
C++

/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FileAttrs.NT.cpp
Date: 2023-2-4
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "FS.hpp"
#include "FileAttrs.NT.hpp"
namespace Aurora::IO::FS
{
AUKN_SYM AuList<AuString> FileAttrsList(const AuROString &path)
{
AuList<AuString> names;
WIN32_FIND_STREAM_DATA data;
if (path.empty())
{
SysPushErrorArg("Empty path provided");
return {};
}
auto pathex = NormalizePathRet(path);
if (pathex.empty())
{
return {};
}
auto win32Path = Locale::ConvertFromUTF8(pathex);
if (win32Path.empty())
{
return {};
}
if (!pFindFirstStreamW)
{
SysPushErrorUnavailableError();
return {};
}
auto hIterationHandle = pFindFirstStreamW(win32Path.c_str(),
FindStreamInfoStandard,
&data,
0);
if (hIterationHandle == INVALID_HANDLE_VALUE)
{
if (!AuFS::FileExists(pathex))
{
SysPushErrorResourceMissing("Missing file: {}", path);
return {};
}
SysPushErrorIO("Couldn't open a handle for: {}", path);
return {};
}
do
{
AuString currentName;
currentName = AuLocale::ConvertFromWChar(data.cStreamName, wcsnlen_s(data.cStreamName, AuArraySize(data.cStreamName)));
if (currentName.empty())
{
continue;
}
// meh, noise. doesnt prevent an explicit read for this attribute.
if (currentName == "::$DATA")
{
continue;
}
{
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/a82e9105-2405-4e37-b2c3-28c773902d85
// Seems like NTFS docs
// "A file's data is an attribute; the "Data Attribute" known as $DATA"
// ok, so, let's drop this suffix?
if (AuEndsWith(currentName, "$DATA"))
{
if (!AuTryResize(currentName, currentName.size() - 5))
{
SysPushErrorMemory();
continue;
}
}
}
int endRemoval = currentName.size() > 1 && currentName[currentName.size() - 1] == ':';
if (currentName[0] == ':')
{
auto endLen = currentName.size() - 1;
AuMemmove(currentName.data(), currentName.data() + 1, endLen);
currentName.resize(endLen - endRemoval);
}
else if (endRemoval)
{
currentName.pop_back();
}
names.push_back(currentName);
}
while (pFindNextStreamW(hIterationHandle, &data));
pFindClose(hIterationHandle);
return names;
}
AUKN_SYM AuResult<Memory::ByteBuffer> FileAttrsGet(const AuROString &path, const AuROString &attr)
{
try
{
AuByteBuffer temp;
if (!AuFS::ReadFile(AuString(path) + ":" + AuString(attr), temp))
{
return {};
}
return AuMove(temp);
}
catch (...)
{
return {};
}
}
AUKN_SYM bool FileAttrsSet(const AuROString &path, const AuROString &attr, const Memory::MemoryViewRead &view)
{
try
{
return AuFS::WriteFile(AuString(path) + ":" + AuString(attr), view);
}
catch (...)
{
return false;
}
}
AUKN_SYM bool FileAttrsDel(const AuROString &path, const AuROString &attr)
{
try
{
return AuFS::Remove(AuString(path) + ":" + AuString(attr)) || AuFS::FileExists(path);
}
catch (...)
{
return false;
}
}
}