mirror of
https://github.com/thunderbrewhq/bc.git
synced 2026-02-03 16:39:08 +00:00
feat(memory): add helper macros to simplify allocating/deallocating objects
SMemAlloc and SMemFree can now be used indirectly by using the 'new' and 'delete' operators. This also means that any project linked against bc will import these operators. The following helper macros are now available for use by including 'bc/Memory.hpp' ALLOC(n) allocate n random bytes of memory ALLOC_ZERO(n) allocate n zeroed bytes of memory FREE(ptr) deallocate memory at ptr NEW(T) allocate an object of type T and call the object's constructor NEW_ZERO(T) allocate an object of type T with zeroed bytes and call the object's constructor DEL(ptr) call the object at ptr's destructor, and deallocate its memory
This commit is contained in:
parent
05db2d1723
commit
46e0a5a0c6
8 changed files with 173 additions and 122 deletions
|
|
@ -1,18 +0,0 @@
|
||||||
#include "bc/Memory.hpp"
|
|
||||||
#include "bc/memory/Storm.hpp"
|
|
||||||
|
|
||||||
void* Blizzard::Memory::Allocate(uint32_t bytes) {
|
|
||||||
return SMemAlloc(bytes, __FILE__, __LINE__, 0x0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* Blizzard::Memory::Allocate(uint32_t bytes, uint32_t flags, const char* filename, uint32_t linenumber, const char* a5) {
|
|
||||||
// TODO
|
|
||||||
// - determine purpose of a5
|
|
||||||
// - flags manipulation
|
|
||||||
|
|
||||||
return SMemAlloc(bytes, filename, linenumber, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Blizzard::Memory::Free(void* ptr) {
|
|
||||||
SMemFree(ptr);
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +1,7 @@
|
||||||
#ifndef BC_MEMORY_HPP
|
#ifndef BC_MEMORY_HPP
|
||||||
#define BC_MEMORY_HPP
|
#define BC_MEMORY_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
#include "bc/memory/Memory.hpp"
|
||||||
|
#include "bc/memory/Storm.hpp"
|
||||||
namespace Blizzard {
|
|
||||||
namespace Memory {
|
|
||||||
|
|
||||||
// Functions
|
|
||||||
void* Allocate(uint32_t bytes);
|
|
||||||
void* Allocate(uint32_t bytes, uint32_t flags, const char* filename, uint32_t linenumber, const char* a5);
|
|
||||||
void Free(void* ptr);
|
|
||||||
|
|
||||||
} // namespace Memory
|
|
||||||
} // namespace Blizzard
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
24
bc/memory/Memory.cpp
Normal file
24
bc/memory/Memory.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "bc/memory/Memory.hpp"
|
||||||
|
#include "bc/memory/Storm.hpp"
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace Memory {
|
||||||
|
|
||||||
|
void* Allocate(uint32_t bytes) {
|
||||||
|
return SMemAlloc(bytes, __FILE__, __LINE__, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Allocate(uint32_t bytes, uint32_t flags, const char* filename, uint32_t linenumber, const char* a5) {
|
||||||
|
// TODO
|
||||||
|
// - determine purpose of a5
|
||||||
|
// - flags manipulation
|
||||||
|
|
||||||
|
return SMemAlloc(bytes, filename, linenumber, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Free(void* ptr) {
|
||||||
|
SMemFree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Memory
|
||||||
|
} // namespace Blizzard
|
||||||
19
bc/memory/Memory.hpp
Normal file
19
bc/memory/Memory.hpp
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef BC_MEMORY_MEMORY_HPP
|
||||||
|
#define BC_MEMORY_MEMORY_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace Memory {
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
void* Allocate(uint32_t bytes);
|
||||||
|
|
||||||
|
void* Allocate(uint32_t bytes, uint32_t flags, const char* filename, uint32_t linenumber, const char* a5);
|
||||||
|
|
||||||
|
void Free(void* ptr);
|
||||||
|
|
||||||
|
} // namespace Memory
|
||||||
|
} // namespace Blizzard
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -2,6 +2,20 @@
|
||||||
|
|
||||||
constexpr size_t ALIGNMENT = 8;
|
constexpr size_t ALIGNMENT = 8;
|
||||||
|
|
||||||
|
void* operator new(size_t bytes) {
|
||||||
|
return SMemAlloc(bytes, "new", -1, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* operator new[](size_t bytes) {
|
||||||
|
return SMemAlloc(bytes, "new", -1, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void* ptr) {
|
||||||
|
if (ptr) {
|
||||||
|
SMemFree(ptr, "delete", -1, 0x0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void* SMemAlloc(size_t bytes, const char* filename, int32_t linenumber, uint32_t flags) {
|
void* SMemAlloc(size_t bytes, const char* filename, int32_t linenumber, uint32_t flags) {
|
||||||
size_t alignedBytes = (bytes + (ALIGNMENT - 1)) & ~(ALIGNMENT - 1);
|
size_t alignedBytes = (bytes + (ALIGNMENT - 1)) & ~(ALIGNMENT - 1);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,25 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <new>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#define ALLOC(n) SMemAlloc(static_cast<size_t>(n), __FILE__, __LINE__, 0x0)
|
||||||
|
#define ALLOC_ZERO(n) SMemAlloc(static_cast<size_t>(n), __FILE__, __LINE__, 0x8)
|
||||||
|
#define FREE(ptr) SMemFree(ptr, __FILE__, __LINE__, 0x0)
|
||||||
|
|
||||||
|
#define NEW(T, ...) (new (SMemAlloc(sizeof(T), __FILE__, __LINE__, 0)) T(__VA_ARGS__))
|
||||||
|
#define NEW_ZERO(T, ...) (new (SMemAlloc(sizeof(T), __FILE__, __LINE__, 0x8) T(__VA_ARGS__))
|
||||||
|
#define DEL(ptr) \
|
||||||
|
do { \
|
||||||
|
if (ptr) { \
|
||||||
|
using __storm_object = std::remove_pointer<std::decay<decltype(ptr)>::type>::type; \
|
||||||
|
(ptr)->~__storm_object(); \
|
||||||
|
::operator delete(ptr, __FILE__, __LINE__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
// allocation functions
|
||||||
|
|
||||||
void* SMemAlloc(size_t bytes, const char* filename, int32_t linenumber, uint32_t flags);
|
void* SMemAlloc(size_t bytes, const char* filename, int32_t linenumber, uint32_t flags);
|
||||||
|
|
||||||
|
|
@ -12,4 +31,24 @@ void SMemFree(void* ptr, const char* filename, int32_t linenumber, uint32_t flag
|
||||||
|
|
||||||
void* SMemReAlloc(void* ptr, size_t bytes, const char* filename, int32_t linenumber, uint32_t flags);
|
void* SMemReAlloc(void* ptr, size_t bytes, const char* filename, int32_t linenumber, uint32_t flags);
|
||||||
|
|
||||||
|
// global operators
|
||||||
|
|
||||||
|
void* operator new(size_t bytes);
|
||||||
|
|
||||||
|
void* operator new[](size_t bytes);
|
||||||
|
|
||||||
|
void operator delete(void* ptr);
|
||||||
|
|
||||||
|
inline void operator delete(void* ptr, const char* filename, int32_t linenumber) {
|
||||||
|
if (ptr) {
|
||||||
|
SMemFree(ptr, "delete", -1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator delete[](void* ptr, const char* filename, int32_t linenumber) {
|
||||||
|
if (ptr) {
|
||||||
|
SMemFree(ptr, "delete[]", -1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,12 @@
|
||||||
#include "bc/file/Defines.hpp"
|
#include "bc/file/Defines.hpp"
|
||||||
#if defined(WHOA_SYSTEM_LINUX) || defined(WHOA_SYSTEM_MAC)
|
#if defined(WHOA_SYSTEM_LINUX) || defined(WHOA_SYSTEM_MAC)
|
||||||
|
|
||||||
#include "bc/system/file/System_File.hpp"
|
|
||||||
#include "bc/system/file/Stacked.hpp"
|
|
||||||
#include "bc/Debug.hpp"
|
#include "bc/Debug.hpp"
|
||||||
#include "bc/File.hpp"
|
#include "bc/File.hpp"
|
||||||
#include "bc/Memory.hpp"
|
#include "bc/Memory.hpp"
|
||||||
#include "bc/memory/Storm.hpp"
|
|
||||||
#include "bc/String.hpp"
|
#include "bc/String.hpp"
|
||||||
|
#include "bc/system/file/Stacked.hpp"
|
||||||
|
#include "bc/system/file/System_File.hpp"
|
||||||
#include "bc/system/file/posix/Support.hpp"
|
#include "bc/system/file/posix/Support.hpp"
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
@ -25,8 +24,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WHOA_SYSTEM_MAC)
|
#if defined(WHOA_SYSTEM_MAC)
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -55,7 +54,7 @@ bool Close(FileParms* parms) {
|
||||||
BLIZZARD_ASSERT(file != nullptr);
|
BLIZZARD_ASSERT(file != nullptr);
|
||||||
|
|
||||||
::close(file->filefd);
|
::close(file->filefd);
|
||||||
SMemFree(file);
|
FREE(file);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -327,7 +326,7 @@ bool IsReadOnly(FileParms* parms) {
|
||||||
bool MakeAbsolutePath(FileParms* parms) {
|
bool MakeAbsolutePath(FileParms* parms) {
|
||||||
char namebuffer[BC_FILE_MAX_PATH];
|
char namebuffer[BC_FILE_MAX_PATH];
|
||||||
auto name = parms->buffersize > BC_FILE_MAX_PATH
|
auto name = parms->buffersize > BC_FILE_MAX_PATH
|
||||||
? static_cast<char*>(Blizzard::Memory::Allocate(parms->buffersize))
|
? static_cast<char*>(ALLOC(parms->buffersize))
|
||||||
: namebuffer;
|
: namebuffer;
|
||||||
|
|
||||||
*name = '\0';
|
*name = '\0';
|
||||||
|
|
@ -338,7 +337,7 @@ bool MakeAbsolutePath(FileParms* parms) {
|
||||||
Blizzard::String::Append(name, parms->name, parms->buffersize);
|
Blizzard::String::Append(name, parms->name, parms->buffersize);
|
||||||
char resultbuffer[BC_FILE_MAX_PATH];
|
char resultbuffer[BC_FILE_MAX_PATH];
|
||||||
auto result = parms->buffersize > BC_FILE_MAX_PATH
|
auto result = parms->buffersize > BC_FILE_MAX_PATH
|
||||||
? static_cast<char*>(Blizzard::Memory::Allocate(parms->buffersize))
|
? static_cast<char*>(ALLOC(parms->buffersize))
|
||||||
: resultbuffer;
|
: resultbuffer;
|
||||||
Blizzard::String::MakeUnivPath(name, result, parms->buffersize);
|
Blizzard::String::MakeUnivPath(name, result, parms->buffersize);
|
||||||
|
|
||||||
|
|
@ -391,7 +390,7 @@ bool MakeAbsolutePath(FileParms* parms) {
|
||||||
char canonicalbuffer[BC_FILE_MAX_PATH];
|
char canonicalbuffer[BC_FILE_MAX_PATH];
|
||||||
char resolvedbuffer[BC_FILE_MAX_PATH];
|
char resolvedbuffer[BC_FILE_MAX_PATH];
|
||||||
auto canonical = parms->buffersize > BC_FILE_MAX_PATH
|
auto canonical = parms->buffersize > BC_FILE_MAX_PATH
|
||||||
? static_cast<char*>(Blizzard::Memory::Allocate(parms->buffersize))
|
? static_cast<char*>(ALLOC(parms->buffersize))
|
||||||
: canonicalbuffer;
|
: canonicalbuffer;
|
||||||
auto cur = canonical;
|
auto cur = canonical;
|
||||||
|
|
||||||
|
|
@ -405,7 +404,7 @@ bool MakeAbsolutePath(FileParms* parms) {
|
||||||
auto v15 = (src + 1) - begin;
|
auto v15 = (src + 1) - begin;
|
||||||
Blizzard::String::Copy(cur, begin, v15 + 1);
|
Blizzard::String::Copy(cur, begin, v15 + 1);
|
||||||
|
|
||||||
auto resolved = parms->buffersize > BC_FILE_MAX_PATH ? static_cast<char*>(Blizzard::Memory::Allocate(parms->buffersize)) : resolvedbuffer;
|
auto resolved = parms->buffersize > BC_FILE_MAX_PATH ? static_cast<char*>(ALLOC(parms->buffersize)) : resolvedbuffer;
|
||||||
if (::realpath(canonical, resolved)) {
|
if (::realpath(canonical, resolved)) {
|
||||||
Blizzard::String::Copy(canonical, resolved, parms->buffersize);
|
Blizzard::String::Copy(canonical, resolved, parms->buffersize);
|
||||||
if (src[0] == '/' || src[0] == '\0' && src[-1] == '/') {
|
if (src[0] == '/' || src[0] == '\0' && src[-1] == '/') {
|
||||||
|
|
@ -536,9 +535,8 @@ bool Copy(FileParms* parms) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = Blizzard::File::GetFileInfo(src)->size;
|
auto size = Blizzard::File::GetFileInfo(src)->size;
|
||||||
auto copybuffersize = size > BC_SYSTEM_FILE_COPYBUFFER_SIZE ? BC_SYSTEM_FILE_COPYBUFFER_SIZE : size;
|
auto buffer = ALLOC(size > BC_SYSTEM_FILE_COPYBUFFER_SIZE ? BC_SYSTEM_FILE_COPYBUFFER_SIZE : size);
|
||||||
auto copybuffer = Blizzard::Memory::Allocate(copybuffersize);
|
|
||||||
|
|
||||||
int64_t offset = 0;
|
int64_t offset = 0;
|
||||||
|
|
||||||
|
|
@ -546,12 +544,12 @@ bool Copy(FileParms* parms) {
|
||||||
|
|
||||||
while (offset < size) {
|
while (offset < size) {
|
||||||
int32_t count = size - offset >= BC_SYSTEM_FILE_COPYBUFFER_SIZE ? BC_SYSTEM_FILE_COPYBUFFER_SIZE : size - offset;
|
int32_t count = size - offset >= BC_SYSTEM_FILE_COPYBUFFER_SIZE ? BC_SYSTEM_FILE_COPYBUFFER_SIZE : size - offset;
|
||||||
if (!Blizzard::File::Read(src, copybuffer, offset, &count)) {
|
if (!Blizzard::File::Read(src, buffer, offset, &count)) {
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Blizzard::File::Write(dst, copybuffer, offset, &count)) {
|
if (!Blizzard::File::Write(dst, buffer, offset, &count)) {
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -559,7 +557,7 @@ bool Copy(FileParms* parms) {
|
||||||
offset += static_cast<int64_t>(count);
|
offset += static_cast<int64_t>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
Blizzard::Memory::Free(copybuffer);
|
FREE(buffer);
|
||||||
Blizzard::File::Close(src);
|
Blizzard::File::Close(src);
|
||||||
Blizzard::File::Close(dst);
|
Blizzard::File::Close(dst);
|
||||||
if (result == false) {
|
if (result == false) {
|
||||||
|
|
@ -622,10 +620,10 @@ bool Open(FileParms* parms) {
|
||||||
|
|
||||||
if (System_File::s_EnableFileLocks) {
|
if (System_File::s_EnableFileLocks) {
|
||||||
if ((parms->mode & Blizzard::File::Mode::shareread) == 0 && (parms->mode & Blizzard::File::Mode::write) != 0) {
|
if ((parms->mode & Blizzard::File::Mode::shareread) == 0 && (parms->mode & Blizzard::File::Mode::write) != 0) {
|
||||||
if (!LockFileDescriptorForWrite(filefd)) {
|
if (!LockFileDescriptorForWrite(filefd)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parms->mode & Blizzard::File::Mode::append) {
|
if (parms->mode & Blizzard::File::Mode::append) {
|
||||||
|
|
@ -652,12 +650,11 @@ bool Open(FileParms* parms) {
|
||||||
auto file = parms->file;
|
auto file = parms->file;
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
auto namelength = Blizzard::String::Length(name.ToString()) + 1;
|
auto namesize = Blizzard::String::Length(name.ToString()) + 1;
|
||||||
file = reinterpret_cast<Blizzard::File::StreamRecord*>(SMemAlloc(sizeof(Blizzard::File::StreamRecord) + namelength, __FILE__, __LINE__, 0x8));
|
file = reinterpret_cast<Blizzard::File::StreamRecord*>(ALLOC_ZERO(sizeof(Blizzard::File::StreamRecord) + namesize));
|
||||||
auto filename = reinterpret_cast<char*>(file) + sizeof(Blizzard::File::StreamRecord);
|
auto filename = reinterpret_cast<char*>(file) + sizeof(Blizzard::File::StreamRecord);
|
||||||
file->name = filename;
|
file->name = filename;
|
||||||
Blizzard::String::Copy(filename, name.ToString(), namelength);
|
Blizzard::String::Copy(filename, name.ToString(), namesize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file->filefd = filefd;
|
file->filefd = filefd;
|
||||||
|
|
@ -763,8 +760,8 @@ bool SetAttributes(FileParms* parms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mode = parms->info->attributes & BC_FILE_ATTRIBUTE_READONLY
|
auto mode = parms->info->attributes & BC_FILE_ATTRIBUTE_READONLY
|
||||||
? info.st_mode & (S_IFSOCK | S_IFLNK | S_IFIFO | S_ISUID | S_ISGID | S_ISVTX | 0555)
|
? info.st_mode & (S_IFSOCK | S_IFLNK | S_IFIFO | S_ISUID | S_ISGID | S_ISVTX | 0555)
|
||||||
: info.st_mode | 0222;
|
: info.st_mode | 0222;
|
||||||
|
|
||||||
if (::chmod(PATH(parms->name), mode) != 0) {
|
if (::chmod(PATH(parms->name), mode) != 0) {
|
||||||
BC_FILE_SET_ERROR(8);
|
BC_FILE_SET_ERROR(8);
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,18 @@
|
||||||
#include "bc/file/Defines.hpp"
|
|
||||||
#if defined(WHOA_SYSTEM_WIN)
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
|
||||||
#include "bc/system/file/Stacked.hpp"
|
|
||||||
#include "bc/string/QuickFormat.hpp"
|
|
||||||
#include "bc/File.hpp"
|
|
||||||
#include "bc/Debug.hpp"
|
|
||||||
#include "bc/Memory.hpp"
|
#include "bc/Memory.hpp"
|
||||||
#include "bc/String.hpp"
|
|
||||||
#include "bc/Unicode.hpp"
|
|
||||||
#include "bc/File.hpp"
|
|
||||||
#include "bc/time/Time.hpp"
|
|
||||||
#include "bc/memory/Storm.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
|
||||||
|
#include "bc/File.hpp"
|
||||||
|
#include "bc/system/file/Stacked.hpp"
|
||||||
|
#include "bc/Debug.hpp"
|
||||||
|
#include "bc/String.hpp"
|
||||||
|
#include "bc/Unicode.hpp"
|
||||||
|
#include "bc/time/Time.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "bc/system/file/win/Support.hpp"
|
#include "bc/system/file/win/Support.hpp"
|
||||||
|
|
||||||
#define PATH(name) Blizzard::String::QuickNativePath<300UL>(name).ToString()
|
#define PATH(name) Blizzard::String::QuickNativePath<300UL>(name).ToString()
|
||||||
|
|
@ -27,9 +23,9 @@
|
||||||
high = static_cast<uint32_t>(qw >> 32); \
|
high = static_cast<uint32_t>(qw >> 32); \
|
||||||
low = static_cast<uint32_t>(qw)
|
low = static_cast<uint32_t>(qw)
|
||||||
|
|
||||||
#define BREAKFILEPOINTER(qw, high, low) \
|
#define BREAKFILEPOINTER(qw, high, low) \
|
||||||
high = static_cast<LONG>(qw >> 32); \
|
high = static_cast<LONG>(qw >> 32); \
|
||||||
low = static_cast<LONG>(qw)
|
low = static_cast<LONG>(qw)
|
||||||
|
|
||||||
namespace System_File {
|
namespace System_File {
|
||||||
|
|
||||||
|
|
@ -38,7 +34,7 @@ void FromNativeName(char* buffer, int32_t buffersize, const char* name) {
|
||||||
uint16_t widenamebuffer[300];
|
uint16_t widenamebuffer[300];
|
||||||
auto len = name ? Blizzard::String::Length(name) : 0;
|
auto len = name ? Blizzard::String::Length(name) : 0;
|
||||||
auto widename = len + 1 > 300
|
auto widename = len + 1 > 300
|
||||||
? static_cast<uint16_t*>(Blizzard::Memory::Allocate(2 * (len + 1)))
|
? new uint16_t[2 * (len + 1)]
|
||||||
: widenamebuffer;
|
: widenamebuffer;
|
||||||
|
|
||||||
widename[MultiByteToWideChar(CP_ACP, 0, name, len, reinterpret_cast<LPWSTR>(widename), len + 1)] = 0;
|
widename[MultiByteToWideChar(CP_ACP, 0, name, len, reinterpret_cast<LPWSTR>(widename), len + 1)] = 0;
|
||||||
|
|
@ -46,7 +42,7 @@ void FromNativeName(char* buffer, int32_t buffersize, const char* name) {
|
||||||
Blizzard::Unicode::ConvertUTF16to8(reinterpret_cast<uint8_t*>(buffer), buffersize, widenamebuffer, 0xFFFFFFFF, nullptr, nullptr);
|
Blizzard::Unicode::ConvertUTF16to8(reinterpret_cast<uint8_t*>(buffer), buffersize, widenamebuffer, 0xFFFFFFFF, nullptr, nullptr);
|
||||||
|
|
||||||
if (widenamebuffer != widename) {
|
if (widenamebuffer != widename) {
|
||||||
Blizzard::Memory::Free(widename);
|
delete widename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,13 +148,13 @@ void GetFileInfoByFile(Blizzard::File::StreamRecord* file) {
|
||||||
WIN32_FILE_ATTRIBUTE_DATA fileinfo;
|
WIN32_FILE_ATTRIBUTE_DATA fileinfo;
|
||||||
if (::GetFileAttributesEx(PATH(file->name), GetFileExInfoStandard, &fileinfo)) {
|
if (::GetFileAttributesEx(PATH(file->name), GetFileExInfoStandard, &fileinfo)) {
|
||||||
|
|
||||||
info->createtime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftCreationTime));
|
info->createtime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftCreationTime));
|
||||||
info->writetime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftLastWriteTime));
|
info->writetime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftLastWriteTime));
|
||||||
info->accesstime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftLastAccessTime));
|
info->accesstime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftLastAccessTime));
|
||||||
|
|
||||||
info->attributes = FromNativeAttributes(fileinfo.dwFileAttributes);
|
info->attributes = FromNativeAttributes(fileinfo.dwFileAttributes);
|
||||||
|
|
||||||
info->normal = info->attributes & BC_FILE_ATTRIBUTE_NORMAL != 0;
|
info->normal = (info->attributes & BC_FILE_ATTRIBUTE_NORMAL) != 0;
|
||||||
|
|
||||||
if (fileinfo.dwFileAttributes == 0xFFFFFFFF) {
|
if (fileinfo.dwFileAttributes == 0xFFFFFFFF) {
|
||||||
info->filetype = 0;
|
info->filetype = 0;
|
||||||
|
|
@ -209,7 +205,7 @@ bool Close(FileParms* parms) {
|
||||||
::CloseHandle(file->filehandle);
|
::CloseHandle(file->filehandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
SMemFree(file);
|
FREE(file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -314,7 +310,7 @@ bool GetFileInfo(FileParms* parms) {
|
||||||
|
|
||||||
info->size = MAKEU64(fileinfo.nFileSizeHigh, fileinfo.nFileSizeLow);
|
info->size = MAKEU64(fileinfo.nFileSizeHigh, fileinfo.nFileSizeLow);
|
||||||
|
|
||||||
info->createtime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftCreationTime));
|
info->createtime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftCreationTime));
|
||||||
info->writetime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftLastWriteTime));
|
info->writetime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftLastWriteTime));
|
||||||
info->accesstime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftLastAccessTime));
|
info->accesstime = Blizzard::Time::FromFileTime(MakeFileTime(fileinfo.ftLastAccessTime));
|
||||||
|
|
||||||
|
|
@ -322,7 +318,7 @@ bool GetFileInfo(FileParms* parms) {
|
||||||
|
|
||||||
info->attributes = FromNativeAttributes(fileinfo.dwFileAttributes);
|
info->attributes = FromNativeAttributes(fileinfo.dwFileAttributes);
|
||||||
|
|
||||||
info->normal = info->attributes & BC_FILE_ATTRIBUTE_NORMAL != 0;
|
info->normal = (info->attributes & BC_FILE_ATTRIBUTE_NORMAL) != 0;
|
||||||
|
|
||||||
if (fileinfo.dwFileAttributes == 0xFFFFFFFF) {
|
if (fileinfo.dwFileAttributes == 0xFFFFFFFF) {
|
||||||
info->filetype = 0;
|
info->filetype = 0;
|
||||||
|
|
@ -351,20 +347,15 @@ bool GetFreeSpace(FileParms* parms) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pathchars = (Blizzard::String::FindFilename(name) + 1) - name;
|
char path[PATH_MAX];
|
||||||
if (pathchars > 260) {
|
char shortpath[PATH_MAX];
|
||||||
pathchars = 260;
|
Blizzard::String::Copy(path, name, std::min(static_cast<int32_t>((Blizzard::String::FindFilename(name) + 1) - name), PATH_MAX));
|
||||||
}
|
|
||||||
|
|
||||||
char path[260];
|
|
||||||
char shortpath[260];
|
|
||||||
Blizzard::String::Copy(path, name, pathchars);
|
|
||||||
|
|
||||||
ULARGE_INTEGER freebytesavailable;
|
ULARGE_INTEGER freebytesavailable;
|
||||||
ULARGE_INTEGER totalbytesavailable;
|
ULARGE_INTEGER totalbytesavailable;
|
||||||
|
|
||||||
auto shortpathchars = ::GetShortPathName(PATH(path), shortpath, 260);
|
auto shortpathchars = ::GetShortPathName(PATH(path), shortpath, PATH_MAX);
|
||||||
if (shortpathchars && shortpathchars < 260) {
|
if (shortpathchars && shortpathchars < PATH_MAX) {
|
||||||
if (!GetDiskFreeSpaceEx(shortpath, &freebytesavailable, &totalbytesavailable, nullptr)) {
|
if (!GetDiskFreeSpaceEx(shortpath, &freebytesavailable, &totalbytesavailable, nullptr)) {
|
||||||
BC_FILE_SET_ERROR(8);
|
BC_FILE_SET_ERROR(8);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -403,7 +394,7 @@ bool GetPos(FileParms* parms) {
|
||||||
bool GetRootChars(FileParms* parms) {
|
bool GetRootChars(FileParms* parms) {
|
||||||
char pathbuffer[256];
|
char pathbuffer[256];
|
||||||
auto pathsize = Blizzard::String::Length(parms->name) + 1;
|
auto pathsize = Blizzard::String::Length(parms->name) + 1;
|
||||||
auto path = pathsize > 256 ? reinterpret_cast<char*>(Blizzard::Memory::Allocate(pathsize)) : pathbuffer;
|
auto path = pathsize > 256 ? new char[pathsize] : pathbuffer;
|
||||||
|
|
||||||
if (pathsize > 2) {
|
if (pathsize > 2) {
|
||||||
Blizzard::String::MakeUnivPath(parms->name, path, pathsize);
|
Blizzard::String::MakeUnivPath(parms->name, path, pathsize);
|
||||||
|
|
@ -417,7 +408,7 @@ bool GetRootChars(FileParms* parms) {
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
parms->offset = pathsize;
|
parms->offset = pathsize;
|
||||||
if (path != pathbuffer) {
|
if (path != pathbuffer) {
|
||||||
Blizzard::Memory::Free(path);
|
delete path;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -429,7 +420,7 @@ bool GetRootChars(FileParms* parms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path != pathbuffer) {
|
if (path != pathbuffer) {
|
||||||
Blizzard::Memory::Free(path);
|
delete path;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -487,9 +478,9 @@ bool CreateDirectory(FileParms* parms) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char pathbuffer[260];
|
char pathbuffer[PATH_MAX];
|
||||||
auto pathsize = Blizzard::String::Length(parms->name) + 1;
|
auto pathsize = Blizzard::String::Length(parms->name) + 1;
|
||||||
auto path = pathsize > 260 ? reinterpret_cast<char*>(Blizzard::Memory::Allocate(pathsize)) : pathbuffer;
|
auto path = pathsize > PATH_MAX ? new char[pathsize] : pathbuffer;
|
||||||
|
|
||||||
Blizzard::String::MakeBackslashPath(parms->name, path, pathsize);
|
Blizzard::String::MakeBackslashPath(parms->name, path, pathsize);
|
||||||
|
|
||||||
|
|
@ -502,21 +493,17 @@ bool CreateDirectory(FileParms* parms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parms->recurse) {
|
if (parms->recurse) {
|
||||||
char leadingpath[260];
|
char leadingpath[PATH_MAX];
|
||||||
|
|
||||||
for (auto s = path; *s && s < (s + Blizzard::String::Length(s)); s++) {
|
for (auto s = path; *s && s < (s + Blizzard::String::Length(s)); s++) {
|
||||||
while (*s && *s != '\\') {
|
while (*s && *s != '\\') {
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto leadingpathsize = (s - path) + 2;
|
if (Blizzard::String::Copy(leadingpath, path, std::min(static_cast<int32_t>(s - path) + 2, PATH_MAX))) {
|
||||||
if (leadingpathsize > 260) {
|
|
||||||
leadingpathsize = 260;
|
|
||||||
}
|
|
||||||
if (Blizzard::String::Copy(leadingpath, path, leadingpathsize)) {
|
|
||||||
BC_FILE_SET_ERROR(8);
|
BC_FILE_SET_ERROR(8);
|
||||||
if (path != pathbuffer) {
|
if (path != pathbuffer) {
|
||||||
Blizzard::Memory::Free(path);
|
delete path;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -532,7 +519,7 @@ bool CreateDirectory(FileParms* parms) {
|
||||||
|
|
||||||
if ((last_err != ERROR_ALREADY_EXISTS && last_err != ERROR_ACCESS_DENIED)) {
|
if ((last_err != ERROR_ALREADY_EXISTS && last_err != ERROR_ACCESS_DENIED)) {
|
||||||
if (path != pathbuffer) {
|
if (path != pathbuffer) {
|
||||||
Blizzard::Memory::Free(path);
|
delete path;
|
||||||
}
|
}
|
||||||
BC_FILE_SET_ERROR(8);
|
BC_FILE_SET_ERROR(8);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -541,7 +528,7 @@ bool CreateDirectory(FileParms* parms) {
|
||||||
auto directoryattributes = GetFileAttributes(directorypath.ToString());
|
auto directoryattributes = GetFileAttributes(directorypath.ToString());
|
||||||
if (directoryattributes == INVALID_FILE_ATTRIBUTES || (directoryattributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
if (directoryattributes == INVALID_FILE_ATTRIBUTES || (directoryattributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||||
if (path != pathbuffer) {
|
if (path != pathbuffer) {
|
||||||
Blizzard::Memory::Free(path);
|
delete path;
|
||||||
}
|
}
|
||||||
BC_FILE_SET_ERROR(8);
|
BC_FILE_SET_ERROR(8);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -553,14 +540,14 @@ bool CreateDirectory(FileParms* parms) {
|
||||||
auto last_err = ::GetLastError();
|
auto last_err = ::GetLastError();
|
||||||
bool result = last_err == ERROR_ALREADY_EXISTS || last_err == ERROR_ACCESS_DENIED;
|
bool result = last_err == ERROR_ALREADY_EXISTS || last_err == ERROR_ACCESS_DENIED;
|
||||||
if (path != pathbuffer) {
|
if (path != pathbuffer) {
|
||||||
Blizzard::Memory::Free(path);
|
delete path;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path != pathbuffer) {
|
if (path != pathbuffer) {
|
||||||
Blizzard::Memory::Free(path);
|
delete path;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -608,9 +595,8 @@ bool Copy(FileParms* parms) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = Blizzard::File::GetFileInfo(src)->size;
|
auto size = Blizzard::File::GetFileInfo(src)->size;
|
||||||
auto copybuffersize = size > BC_SYSTEM_FILE_COPYBUFFER_SIZE ? BC_SYSTEM_FILE_COPYBUFFER_SIZE : size;
|
auto buffer = ALLOC(size > BC_SYSTEM_FILE_COPYBUFFER_SIZE ? BC_SYSTEM_FILE_COPYBUFFER_SIZE : size);
|
||||||
auto copybuffer = Blizzard::Memory::Allocate(copybuffersize);
|
|
||||||
|
|
||||||
int64_t offset = 0;
|
int64_t offset = 0;
|
||||||
|
|
||||||
|
|
@ -618,12 +604,12 @@ bool Copy(FileParms* parms) {
|
||||||
|
|
||||||
while (offset < size) {
|
while (offset < size) {
|
||||||
auto count = static_cast<int32_t>(size - offset >= BC_SYSTEM_FILE_COPYBUFFER_SIZE ? BC_SYSTEM_FILE_COPYBUFFER_SIZE : size - offset);
|
auto count = static_cast<int32_t>(size - offset >= BC_SYSTEM_FILE_COPYBUFFER_SIZE ? BC_SYSTEM_FILE_COPYBUFFER_SIZE : size - offset);
|
||||||
if (!Blizzard::File::Read(src, copybuffer, offset, &count)) {
|
if (!Blizzard::File::Read(src, buffer, offset, &count)) {
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Blizzard::File::Write(dst, copybuffer, offset, &count)) {
|
if (!Blizzard::File::Write(dst, buffer, offset, &count)) {
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -631,7 +617,7 @@ bool Copy(FileParms* parms) {
|
||||||
offset += static_cast<int64_t>(count);
|
offset += static_cast<int64_t>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
Blizzard::Memory::Free(copybuffer);
|
FREE(buffer);
|
||||||
Blizzard::File::Close(src);
|
Blizzard::File::Close(src);
|
||||||
Blizzard::File::Close(dst);
|
Blizzard::File::Close(dst);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|
@ -675,13 +661,13 @@ bool Open(FileParms* parms) {
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
// alloc(sizeof(StreamRecord) + len(name) + 1)
|
// alloc(sizeof(StreamRecord) + len(name) + 1)
|
||||||
// block of memory holds file as well as C string of the filename
|
// block of memory holds file as well as C string of the filename
|
||||||
auto namesize = Blizzard::String::Length(name);
|
auto namesize = Blizzard::String::Length(name) + 1;
|
||||||
file = reinterpret_cast<Blizzard::File::StreamRecord*>(SMemAlloc(sizeof(Blizzard::File::StreamRecord) + 1 + namesize, __FILE__, __LINE__, 0x8));
|
file = reinterpret_cast<Blizzard::File::StreamRecord*>(ALLOC_ZERO(sizeof(Blizzard::File::StreamRecord) + namesize));
|
||||||
// set the name pointer inside of StreamRecord to point to the end of StreamRecord (i.e. the start of the name cstring in the memory block)
|
// set the name pointer inside of StreamRecord to point to the end of StreamRecord (i.e. the start of the name cstring in the memory block)
|
||||||
auto filename = reinterpret_cast<char*>(file) + sizeof(Blizzard::File::StreamRecord);
|
auto filename = reinterpret_cast<char*>(file) + sizeof(Blizzard::File::StreamRecord);
|
||||||
file->name = filename;
|
file->name = filename;
|
||||||
// copy name into memory block
|
// copy name into memory block
|
||||||
Blizzard::String::Copy(filename, name, namesize + 1);
|
Blizzard::String::Copy(filename, name, namesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
file->filehandle = filehandle;
|
file->filehandle = filehandle;
|
||||||
|
|
@ -707,15 +693,15 @@ bool RemoveDirectory(FileParms* parms) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char namebuffer[260];
|
char namebuffer[PATH_MAX];
|
||||||
auto namesize = Blizzard::String::Length(parms->name);
|
auto namesize = Blizzard::String::Length(parms->name) + 1;
|
||||||
auto name = namesize > 260 ? reinterpret_cast<char*>(Blizzard::Memory::Allocate(namesize)) : namebuffer;
|
auto name = namesize > PATH_MAX ? new char[namesize] : namebuffer;
|
||||||
Blizzard::String::MakeBackslashPath(parms->name, name, 260);
|
Blizzard::String::MakeBackslashPath(parms->name, name, PATH_MAX);
|
||||||
|
|
||||||
auto removed = ::RemoveDirectoryA(PATH(name));
|
auto removed = ::RemoveDirectoryA(PATH(name));
|
||||||
|
|
||||||
if (name != namebuffer) {
|
if (name != namebuffer) {
|
||||||
Blizzard::Memory::Free(name);
|
delete name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return removed != 0;
|
return removed != 0;
|
||||||
|
|
@ -762,6 +748,8 @@ bool SetEOF(FileParms* parms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetAttributes(FileParms* parms) {
|
bool SetAttributes(FileParms* parms) {
|
||||||
|
auto file = parms->file;
|
||||||
|
|
||||||
if (parms->setinfo & BC_SYSTEM_FILE_INFO_TIMES) {
|
if (parms->setinfo & BC_SYSTEM_FILE_INFO_TIMES) {
|
||||||
auto info = parms->info;
|
auto info = parms->info;
|
||||||
|
|
||||||
|
|
@ -769,7 +757,7 @@ bool SetAttributes(FileParms* parms) {
|
||||||
auto lastaccesstime = BreakFileTime(Blizzard::Time::ToFileTime(info->accesstime));
|
auto lastaccesstime = BreakFileTime(Blizzard::Time::ToFileTime(info->accesstime));
|
||||||
auto lastwritetime = BreakFileTime(Blizzard::Time::ToFileTime(info->writetime));
|
auto lastwritetime = BreakFileTime(Blizzard::Time::ToFileTime(info->writetime));
|
||||||
|
|
||||||
if (!::SetFileTime(parms->file->filehandle, &createtime, &lastaccesstime, &lastwritetime)) {
|
if (!::SetFileTime(file->filehandle, &createtime, &lastaccesstime, &lastwritetime)) {
|
||||||
BC_FILE_SET_ERROR(8);
|
BC_FILE_SET_ERROR(8);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -778,7 +766,7 @@ bool SetAttributes(FileParms* parms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parms->setinfo & BC_SYSTEM_FILE_INFO_ATTRIBUTES) {
|
if (parms->setinfo & BC_SYSTEM_FILE_INFO_ATTRIBUTES) {
|
||||||
if (!::SetFileAttributes(PATH(parms->file->name), ToNativeAttributes(parms->info->attributes))) {
|
if (!::SetFileAttributes(PATH(file->name), ToNativeAttributes(parms->info->attributes))) {
|
||||||
BC_FILE_SET_ERROR(8);
|
BC_FILE_SET_ERROR(8);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -802,9 +790,7 @@ bool SetPos(FileParms* parms) {
|
||||||
BREAKFILEPOINTER(parms->offset, distancetomovehigh, distancetomovelow);
|
BREAKFILEPOINTER(parms->offset, distancetomovehigh, distancetomovelow);
|
||||||
|
|
||||||
auto movemethod = static_cast<DWORD>(parms->whence);
|
auto movemethod = static_cast<DWORD>(parms->whence);
|
||||||
if (movemethod > FILE_END) {
|
movemethod = std::min(movemethod, static_cast<DWORD>(FILE_END));
|
||||||
movemethod = FILE_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (::SetFilePointer(file->filehandle, distancetomovelow, &distancetomovehigh, movemethod) == INVALID_SET_FILE_POINTER) {
|
if (::SetFilePointer(file->filehandle, distancetomovelow, &distancetomovehigh, movemethod) == INVALID_SET_FILE_POINTER) {
|
||||||
if (GetLastError()) {
|
if (GetLastError()) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue