Created
April 24, 2025 01:03
-
-
Save RadAd/3599dc0928c4e285b1339c818390ef3e to your computer and use it in GitHub Desktop.
Memory based file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "memfile.h" | |
#include <tchar.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <windows.h> | |
#include <io.h> | |
#include <fcntl.h> | |
#include <process.h> | |
typedef struct pipereadthreaddatatag | |
{ | |
FILE* fr; | |
mempipecb cb; | |
void* param; | |
} pipereadthreaddata; | |
static unsigned __stdcall pipereadthread(void* pArguments) | |
{ | |
pipereadthreaddata* data = (pipereadthreaddata*) pArguments ; | |
char buf[1024]; | |
size_t i; | |
while (i = fread(buf, sizeof(buf[0]), ARRAYSIZE(buf), data->fr)) | |
data->cb(buf, i, data->param); | |
free(data); | |
return 0; | |
} | |
static FILE* tofile(_In_ HANDLE hFile, _In_ int flags, _In_z_ LPCTSTR _Mode) | |
{ | |
const int fd = _open_osfhandle((intptr_t) hFile, flags); | |
if (fd < 0) | |
return NULL; | |
return _tfdopen(fd, _Mode); | |
} | |
int fpipe(FILE** pfr, FILE** pfw) | |
{ | |
const DWORD nSizePipe = 0; | |
HANDLE hReadPipe, hWritePipe; | |
if (!CreatePipe(&hReadPipe, &hWritePipe, NULL, nSizePipe)) | |
return EOF; | |
*pfr = tofile(hReadPipe, _O_RDONLY, _T("r")); | |
if (!*pfr) | |
{ | |
CloseHandle(hReadPipe); | |
CloseHandle(hWritePipe); | |
return EOF; | |
} | |
*pfw = tofile(hWritePipe, _O_WRONLY, _T("w")); | |
if (!*pfw) | |
{ | |
fclose(*pfr); | |
CloseHandle(hWritePipe); | |
return EOF; | |
} | |
return 0; | |
} | |
FILE* fmemopipe(HANDLE* phThread, mempipecb cb, void* param) | |
{ | |
const DWORD nSizePipe = 0; | |
const unsigned int nStackSizeThread = 0; | |
FILE* fr, * fw; | |
if (fpipe(&fr, &fw) != 0) | |
return NULL; | |
pipereadthreaddata* data = (pipereadthreaddata*) malloc(sizeof(pipereadthreaddata)); | |
if (!data) | |
{ | |
fclose(fr); | |
fclose(fw); | |
return NULL; | |
} | |
data->fr = fr; | |
data->cb = cb; | |
data->param = param; | |
HANDLE hThread = (HANDLE)_beginthreadex(NULL, nStackSizeThread, | |
pipereadthread, data, 0, NULL); | |
if (!hThread) | |
{ | |
free(data); | |
fclose(fw); | |
fclose(fr); | |
return NULL; | |
} | |
if (phThread) | |
*phThread = hThread; | |
return fw; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <stdio.h> | |
#include <windows.h> | |
typedef void(*mempipecb)(const void* buf, size_t size, void* param); | |
int fpipe(FILE** pfr, FILE** pfw); | |
FILE* fmemopipe(HANDLE* phThread, mempipecb cb, void* param); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <tchar.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <windows.h> | |
#include <assert.h> | |
#include "memfile.h" | |
#include "radvector.h" | |
void process(const void* buf, size_t size, void* param) | |
{ | |
vector* rdbuf = (vector*)param; | |
VectorAppend(rdbuf, buf, size); | |
} | |
int _tmain(const int argc, const TCHAR* const argv[]) | |
{ | |
HANDLE hThread = NULL; | |
vector readbuf = VectorCreate(1024); | |
FILE* f = fmemopipe(&hThread, process, &readbuf); | |
if (f) | |
{ | |
char buf[] = "hello"; | |
fwrite(buf, sizeof(buf[0]), ARRAYSIZE(buf), f); | |
fclose(f); | |
WaitForSingleObject(hThread, INFINITE); | |
CloseHandle(hThread); | |
assert(strcmp(buf, readbuf.buf) == 0); | |
} | |
return EXIT_SUCCESS; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <assert.h> | |
#include <stdbool.h> | |
typedef struct vectortag | |
{ | |
char* buf; | |
size_t size; | |
size_t capacity; | |
} vector; | |
bool VectorGrow(vector* v, const size_t newcapacity) | |
{ | |
assert(newcapacity > v->capacity); | |
char* newbuf = (char*)realloc(v->buf, newcapacity); | |
if (!newbuf) | |
return false; | |
v->buf = newbuf; | |
v->capacity = newcapacity; | |
assert(v->capacity >= v->size); | |
return true; | |
} | |
vector VectorCreate(size_t capacity) | |
{ | |
vector v; | |
v.buf = NULL; | |
v.size = 0; | |
v.capacity = 0; | |
VectorGrow(&v, capacity); | |
assert(v.capacity >= v.size); | |
return v; | |
} | |
void VectorFree(vector* v) | |
{ | |
free(v->buf); | |
} | |
bool VectorAppend(vector* v, const char* buf, size_t size) | |
{ | |
const size_t space = v->capacity - v->size; | |
if (space < size) | |
{ | |
if (!VectorGrow(v, v->capacity * 2)) | |
return false; | |
} | |
memcpy(v->buf + v->size, buf, size); | |
v->size += size; | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment