Remove HANDLE from zoned chunk storage headers

This commit is contained in:
notmatthewbeshay 2026-03-09 23:57:50 +11:00
parent 37d9439be3
commit 22757b4b51
6 changed files with 127 additions and 45 deletions

View file

@ -2,6 +2,47 @@
#include "../Files/File.h"
#include "NbtSlotFile.h"
namespace
{
std::FILE *OpenBinaryFileForReadWrite(const File &file)
{
#if defined(_WIN32)
std::FILE *stream = _wfopen(file.getPath().c_str(), L"r+b");
if (stream == NULL)
{
stream = _wfopen(file.getPath().c_str(), L"w+b");
}
#else
const std::string nativePath = wstringtofilename(file.getPath());
std::FILE *stream = std::fopen(nativePath.c_str(), "r+b");
if (stream == NULL)
{
stream = std::fopen(nativePath.c_str(), "w+b");
}
#endif
return stream;
}
bool SeekFile(std::FILE *file, __int64 offset)
{
#if defined(_WIN32)
return _fseeki64(file, offset, SEEK_SET) == 0;
#else
return fseeko(file, static_cast<off_t>(offset), SEEK_SET) == 0;
#endif
}
bool ReadExact(std::FILE *file, void *buffer, std::size_t size)
{
return std::fread(buffer, 1, size, file) == size;
}
bool WriteExact(std::FILE *file, const void *buffer, std::size_t size)
{
return std::fwrite(buffer, 1, size, file) == size;
}
}
byteArray NbtSlotFile::READ_BUFFER(1024*1024);
__int64 NbtSlotFile::largest = 0;
@ -14,12 +55,12 @@ NbtSlotFile::NbtSlotFile(File file)
if ( !file.exists() || file.length() )
{
raf = CreateFile(wstringtofilename(file.getPath()), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
raf = OpenBinaryFileForReadWrite(file);
writeHeader();
}
else
{
raf = CreateFile(wstringtofilename(file.getPath()), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
raf = OpenBinaryFileForReadWrite(file);
}
readHeader();
@ -29,12 +70,11 @@ NbtSlotFile::NbtSlotFile(File file)
fileSlotMap[i] = new std::vector<int>;
}
DWORD numberofBytesRead;
for (int fileSlot = 0; fileSlot < totalFileSlots; fileSlot++)
{
seekSlotHeader(fileSlot);
short slot;
ReadFile(raf,&slot,2,&numberofBytesRead,NULL);
ReadExact(raf, &slot, sizeof(slot));
if (slot == 0)
{
freeFileSlots.push_back(fileSlot);
@ -49,42 +89,39 @@ NbtSlotFile::NbtSlotFile(File file)
void NbtSlotFile::readHeader()
{
DWORD numberOfBytesRead;
SetFilePointer(raf,0,0,FILE_BEGIN);
SeekFile(raf, 0);
int magic;
ReadFile(raf,&magic,4,&numberOfBytesRead,NULL);
ReadExact(raf, &magic, sizeof(magic));
// if (magic != MAGIC_NUMBER) throw new IOException("Bad magic number: " + magic); // 4J - TODO
short version;
ReadFile(raf,&version,2,&numberOfBytesRead,NULL);
ReadExact(raf, &version, sizeof(version));
// if (version != 0) throw new IOException("Bad version number: " + version); // 4J - TODO
ReadFile(raf,&totalFileSlots,4,&numberOfBytesRead,NULL);
ReadExact(raf, &totalFileSlots, sizeof(totalFileSlots));
}
void NbtSlotFile::writeHeader()
{
DWORD numberOfBytesWritten;
short version = 0;
SetFilePointer(raf,0,0,FILE_BEGIN);
WriteFile(raf,&MAGIC_NUMBER,4,&numberOfBytesWritten,NULL);
WriteFile(raf,&version,2,&numberOfBytesWritten,NULL);
WriteFile(raf,&totalFileSlots,4,&numberOfBytesWritten,NULL);
SeekFile(raf, 0);
WriteExact(raf, &MAGIC_NUMBER, sizeof(MAGIC_NUMBER));
WriteExact(raf, &version, sizeof(version));
WriteExact(raf, &totalFileSlots, sizeof(totalFileSlots));
}
void NbtSlotFile::seekSlotHeader(int fileSlot)
{
int target = FILE_HEADER_SIZE + fileSlot * (FILE_SLOT_SIZE + FILE_SLOT_HEADER_SIZE);
SetFilePointer(raf,target,0,FILE_BEGIN);
SeekFile(raf, target);
}
void NbtSlotFile::seekSlot(int fileSlot)
{
int target = FILE_HEADER_SIZE + fileSlot * (FILE_SLOT_SIZE + FILE_SLOT_HEADER_SIZE);
SetFilePointer(raf,target+FILE_SLOT_HEADER_SIZE,0,FILE_BEGIN);
SeekFile(raf, target + FILE_SLOT_HEADER_SIZE);
}
std::vector<CompoundTag *> *NbtSlotFile::readAll(int slot)
{
DWORD numberOfBytesRead;
std::vector<CompoundTag *> *tags = new std::vector<CompoundTag *>;
std::vector<int> *fileSlots = fileSlotMap[slot];
int skipped = 0;
@ -101,12 +138,12 @@ std::vector<CompoundTag *> *NbtSlotFile::readAll(int slot)
{
seekSlotHeader(c);
short oldSlot;
ReadFile(raf,&oldSlot,2,&numberOfBytesRead,NULL);
ReadExact(raf, &oldSlot, sizeof(oldSlot));
short size;
ReadFile(raf,&size,2,&numberOfBytesRead,NULL);
ReadFile(raf,&continuesAt,4,&numberOfBytesRead,NULL);
ReadExact(raf, &size, sizeof(size));
ReadExact(raf, &continuesAt, sizeof(continuesAt));
int lastSlot;
ReadFile(raf,&lastSlot,4,&numberOfBytesRead,NULL);
ReadExact(raf, &lastSlot, sizeof(lastSlot));
seekSlot(c);
if (expectedSlot > 0 && oldSlot == -expectedSlot)
@ -117,7 +154,7 @@ std::vector<CompoundTag *> *NbtSlotFile::readAll(int slot)
// if (oldSlot != expectedSlot) throw new IOException("Wrong slot! Got " + oldSlot + ", expected " + expectedSlot); // 4J - TODO
ReadFile(raf,READ_BUFFER.data + pos,size,&numberOfBytesRead,NULL);
ReadExact(raf, READ_BUFFER.data + pos, size);
if (continuesAt >= 0)
{
@ -161,7 +198,6 @@ int NbtSlotFile::getFreeSlot()
}
void NbtSlotFile::replaceSlot(int slot, std::vector<CompoundTag *> *tags)
{
DWORD numberOfBytesWritten;
toReplace = fileSlotMap[slot];
fileSlotMap[slot] = new std::vector<int>();
@ -210,13 +246,13 @@ void NbtSlotFile::replaceSlot(int slot, std::vector<CompoundTag *> *tags)
}
seekSlotHeader(fileSlot);
WriteFile(raf,&currentSlot,2,&numberOfBytesWritten,NULL);
WriteFile(raf,&toWrite,2,&numberOfBytesWritten,NULL);
WriteFile(raf,&nextFileSlot,4,&numberOfBytesWritten,NULL);
WriteFile(raf,&lastFileSlot,4,&numberOfBytesWritten,NULL);
WriteExact(raf, &currentSlot, sizeof(currentSlot));
WriteExact(raf, &toWrite, sizeof(toWrite));
WriteExact(raf, &nextFileSlot, sizeof(nextFileSlot));
WriteExact(raf, &lastFileSlot, sizeof(lastFileSlot));
seekSlot(fileSlot);
WriteFile(raf,compressed.data+pos,toWrite,&numberOfBytesWritten,NULL);
WriteExact(raf, compressed.data + pos, toWrite);
if (remaining > 0)
{
@ -237,7 +273,7 @@ void NbtSlotFile::replaceSlot(int slot, std::vector<CompoundTag *> *tags)
seekSlotHeader(c);
short zero = 0;
WriteFile(raf,&zero,2,&numberOfBytesWritten,NULL);
WriteExact(raf, &zero, sizeof(zero));
}
toReplace->clear();
@ -246,5 +282,9 @@ void NbtSlotFile::replaceSlot(int slot, std::vector<CompoundTag *> *tags)
void NbtSlotFile::close()
{
CloseHandle(raf);
if (raf != NULL)
{
std::fclose(raf);
raf = NULL;
}
}

View file

@ -1,4 +1,6 @@
#pragma once
#include <cstdio>
#include "CompoundTag.h"
#include "../../Level/Storage/ZonedChunkStorage.h"
#include "../../Headers/com.mojang.nbt.h"
@ -14,7 +16,7 @@ private:
static const int FILE_SLOT_HEADER_SIZE = 12;
static const int FILE_SLOT_SIZE = 500;
HANDLE raf;
std::FILE *raf;
std::vector<int> **fileSlotMap;
int fileSlotMapLength;
std::vector<int> freeFileSlots;

View file

@ -3,6 +3,28 @@
#include "../../IO/Files/File.h"
#include "ZoneFile.h"
namespace
{
std::FILE *OpenBinaryFileForReadWrite(const File &file)
{
#if defined(_WIN32)
std::FILE *stream = _wfopen(file.getPath().c_str(), L"r+b");
if (stream == NULL)
{
stream = _wfopen(file.getPath().c_str(), L"w+b");
}
#else
const std::string nativePath = wstringtofilename(file.getPath());
std::FILE *stream = std::fopen(nativePath.c_str(), "r+b");
if (stream == NULL)
{
stream = std::fopen(nativePath.c_str(), "w+b");
}
#endif
return stream;
}
}
const int ZoneFile::slotsLength = ZonedChunkStorage::CHUNKS_PER_ZONE * ZonedChunkStorage::CHUNKS_PER_ZONE;
@ -23,7 +45,7 @@ ZoneFile::ZoneFile(__int64 key, File file, File entityFile) : slots(slotsLength)
// this.entityFile = new NbtSlotFile(entityFile);
// }
channel = CreateFile(wstringtofilename(file.getPath()), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
channel = OpenBinaryFileForReadWrite(file);
// 4J - try/catch removed
// try {
readHeader();
@ -71,7 +93,11 @@ void ZoneFile::writeHeader()
void ZoneFile::close()
{
CloseHandle(channel);
if (channel != NULL)
{
std::fclose(channel);
channel = NULL;
}
entityFile->close();
}
@ -89,4 +115,4 @@ ZoneIo *ZoneFile::getZoneIo(int slot)
bool ZoneFile::containsSlot(int slot)
{
return slots[slot] > 0;
}
}

View file

@ -1,4 +1,6 @@
#pragma once
#include <cstdio>
#include "ZonedChunkStorage.h"
#include "../../IO/NBT/NbtSlotFile.h"
#include "ZoneIO.h"
@ -20,7 +22,7 @@ public:
__int64 lastUse;
private:
HANDLE channel;
std::FILE *channel;
public:
__int64 key;

View file

@ -2,7 +2,19 @@
#include "../../IO/Streams/ByteBuffer.h"
#include "ZoneIO.h"
ZoneIo::ZoneIo(HANDLE channel, __int64 pos)
namespace
{
bool SeekFile(std::FILE *file, __int64 offset)
{
#if defined(_WIN32)
return _fseeki64(file, offset, SEEK_SET) == 0;
#else
return fseeko(file, static_cast<off_t>(offset), SEEK_SET) == 0;
#endif
}
}
ZoneIo::ZoneIo(std::FILE *channel, __int64 pos)
{
this->channel = channel;
this->pos = pos;
@ -21,23 +33,21 @@ void ZoneIo::write(byteArray bb, int size)
void ZoneIo::write(ByteBuffer *bb, int size)
{
DWORD numberOfBytesWritten;
SetFilePointer(channel,(int)pos,NULL,NULL);
WriteFile(channel,bb->getBuffer(), bb->getSize(),&numberOfBytesWritten,NULL);
SeekFile(channel, pos);
std::fwrite(bb->getBuffer(), 1, bb->getSize(), channel);
pos += size;
}
ByteBuffer *ZoneIo::read(int size)
{
DWORD numberOfBytesRead;
byteArray bb = byteArray(size);
SetFilePointer(channel,(int)pos,NULL,NULL);
SeekFile(channel, pos);
ByteBuffer *buff = ByteBuffer::wrap(bb);
// 4J - to investigate - why is this buffer flipped before anything goes in it?
buff->order(ZonedChunkStorage::BYTEORDER);
buff->position(size);
buff->flip();
ReadFile(channel, buff->getBuffer(), buff->getSize(), &numberOfBytesRead, NULL);
std::fread(buff->getBuffer(), 1, buff->getSize(), channel);
pos += size;
return buff;
}
@ -45,4 +55,4 @@ ByteBuffer *ZoneIo::read(int size)
void ZoneIo::flush()
{
// 4J - was channel.force(false);
}
}

View file

@ -1,4 +1,6 @@
#pragma once
#include <cstdio>
#include "ZonedChunkStorage.h"
class ByteBuffer;
@ -6,11 +8,11 @@ class ByteBuffer;
class ZoneIo
{
private:
HANDLE channel;
std::FILE *channel;
__int64 pos;
public:
ZoneIo(HANDLE channel, __int64 pos);
ZoneIo(std::FILE *channel, __int64 pos);
void write(byteArray bb, int size);
void write(ByteBuffer *bb, int size);
ByteBuffer *read(int size);