diff --git a/build.ps1 b/build.ps1 index 5eec485..3773f28 100644 --- a/build.ps1 +++ b/build.ps1 @@ -107,8 +107,8 @@ $compiler_args += $flag_compile, $unit $compiler_args | ForEach-Object { Write-Host $_ } write-host -# $compiler_args += ( $flag_define + "DEMO_STR_SLICE" ) -# $compiler_args += ( $flag_define + "DEMO_STR_SLICE" ) +# $compiler_args += ( $flag_define + 'DEMO_STR_SLICE' ) +# $compiler_args += ( $flag_define + 'DEMO__FILE_READ_CONTENTS_V1' ) # Compile the unit & $compiler $compiler_args diff --git a/demo.str_cache.c b/demo.str_cache.c index 6e4745a..c9c0efe 100644 --- a/demo.str_cache.c +++ b/demo.str_cache.c @@ -9,8 +9,9 @@ Because of this, definitions will be kept on a need-to-have basis to target only We will not use nearly any libraries and will be targeting only Windows 11 x64 using MSVC. Even so the constructs defined and their dependencies can be properly abstracted into a ergonomic library for multiple targets with enough time and pain. -AI prompting will be used as a search engine I'll be provding the prompts used to gather specific vendor API information thats not-memorized. -If the prompt fails it will be noted and I'll fallback to traditional search engines to derive a reference to a specific vendor API document. +Definitions are defined linearly on the file on-demand as needed. Since the file is to be read linearly. +This will cause non-categorical organization so it will be more difficult to sift through if you wanted +to see definitions related to a sepecific kind of data or operation (strings, memory, etc). */ #if 0 int main() @@ -82,8 +83,10 @@ typedef ptrdiff_t SSIZE; // Functional style cast #define cast(type, data) ((type)(data)) +#define nullptr cast(void*, 0) + // Enforces size querying uses SSIZE type. -#define size_of(data) cast(SSIZE, data) +#define size_of(data) cast(SSIZE, sizeof(data)) /* The first construct we'll utilize is a String Slice. @@ -102,7 +105,7 @@ struct Str8 { // For now this string can visualized using a debugger. // #define DEMO__STR_SLICE -#ifdef DEMO__STR_SLICE +#ifdef DEMO__STR_SLICE int main() { Str8 first = lit("Our first string as a slice"); @@ -126,17 +129,20 @@ It will return a result in a composite struct: FileOpResult; which may be expand typedef struct FileOpResult FileOpResult; typedef struct Opts__read_file_contents Opts__read_file_contents; -void file__read_contents(FileOpResult* result, Str8 path, Opts__read_file_contents* opts); -FileOpResult file_read_contents ( Str8 path, Opts__read_file_contents* opts); +void api_file_read_contents(FileOpResult* result, Str8 path, Opts__read_file_contents* opts); +FileOpResult file__read_contents ( Str8 path, Opts__read_file_contents* opts); + +#define file_read_contents(path, opts) file__read_contents(path, & (Opts__read_file_contents){0} ) /* The above is a pattern that can be provided so that whether or not the result is formatted and provided to the user via the stack is entirely optional. +It also allows for default parameters to be defined conviently. */ // Now for our "Version 1" #define DEMO__FILE_READ_CONTENTS_V1 -#ifdef DEMO__FILE_READ_CONTENTS_V1 +#ifdef DEMO__FILE_READ_CONTENTS_V1 /* The file contents will be returned in bytes. @@ -171,11 +177,28 @@ struct Opts__read_file_contents // We'll utilize the ReadFile procedure within the WinAPI: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile #include "fileapi.h" +#if 0 +BOOL ReadFile( + [in] HANDLE hFile, + [out] LPVOID lpBuffer, + [in] DWORD nNumberOfBytesToRead, + [out, optional] LPDWORD lpNumberOfBytesRead, + [in, out, optional] LPOVERLAPPED lpOverlapped +); +// In order to read a file we need a handle to a valid filesystem entity to read from: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea +HANDLE CreateFileA( + [in] LPCSTR lpFileName, + [in] DWORD dwDesiredAccess, + [in] DWORD dwShareMode, + [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes, + [in] DWORD dwCreationDisposition, + [in] DWORD dwFlagsAndAttributes, + [in, optional] HANDLE hTemplateFile +); +#endif -#endif DEMO__FILE_READ_CONTENTS_V1 - - +// We need to covert our string slice to a c-string for CreateFileA's path input. #define KILOBTYES(n) (cast(SSIZE, n) << 10) #define MEGABYTES(n) (cast(SSIZE, n) << 20) @@ -189,5 +212,60 @@ They will having the following format: typedef U8 FMem_KB [ ]; */ -typedef U8 FMem_1KB [ KILOBTYES(1) ]; +typedef U8 FMem_16KB [ KILOBTYES(16) ]; +#define typeof __typeof__ +#define fmem_slice(mem) (SliceMem) { mem, size_of(mem) } + +// We'll be using an intrinsic for copying memory: +void* memory_copy(void* dest, const void* src, size_t count) +{ + if (dest == NULL || src == NULL || count == 0) { + return NULL; + } + + __movsb((unsigned char*)dest, (const unsigned char*)src, count); + return dest; +} + +// Assumes memory is zeroed. +char const* str8_to_cstr_capped(Str8 content, SliceMem mem) +{ + assert(mem.len >= content.len); + memory_copy(mem.ptr, content.ptr, content.ptr); + return mem.ptr; +} + +void api_file_read_contents(FileOpResult* result, Str8 path, Opts__read_file_contents* opts) +{ + FMem_16KB scratch = {0}; + char const* path_cstr = str8_to_cstr_capped(path, fmem_slice(scratch) ); + + HANDLE id_file = CreateFileA( + path_cstr, + + ); + + // BOOL op_result = ReadFile( + // id_file, + // buffer, + // to_read, + // read_amount, + // nullptr + // ); + + return + /* + TODO(Ed): You are here + */ +} + +#endif DEMO__FILE_READ_CONTENTS_V1 + +// Version agnostic code: +inline +FileOpResult file__read_contents(Str8 path, Opts__read_file_contents* opts) { + FileOpResult result; + api_file_read_contents(& result, path, opts); + return result; +}