mirror of https://github.com/flysand7/ciabatta.git
Implement caching for file streams
This commit is contained in:
parent
1e58a85f02
commit
c2cc9e5129
|
@ -239,6 +239,7 @@ size_t strnlen_s(const char *s, size_t maxsize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strdup(const char *str1) {
|
char *strdup(const char *str1) {
|
||||||
|
if(str1 == NULL) return NULL;
|
||||||
size_t len = strlen(str1);
|
size_t len = strlen(str1);
|
||||||
char *copy = calloc(len+1, 1);
|
char *copy = calloc(len+1, 1);
|
||||||
strcpy(copy, str1);
|
strcpy(copy, str1);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
|
||||||
|
#define __STDC_WANT_LIB_EXT2__ 1
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <win.h>
|
#include <win.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@ -7,6 +9,7 @@
|
||||||
#include <threads.h>
|
#include <threads.h>
|
||||||
#include <uchar.h>
|
#include <uchar.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
enum str_type {
|
enum str_type {
|
||||||
STR_R,
|
STR_R,
|
||||||
|
@ -33,6 +36,7 @@ struct FILE {
|
||||||
str_mode mode;
|
str_mode mode;
|
||||||
int buftype;
|
int buftype;
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
|
int bufidx;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
mbstate_t mbstate;
|
mbstate_t mbstate;
|
||||||
mtx_t lock;
|
mtx_t lock;
|
||||||
|
@ -59,13 +63,20 @@ static inline FILE *new_file(
|
||||||
) {
|
) {
|
||||||
FILE *file = malloc(sizeof(FILE));
|
FILE *file = malloc(sizeof(FILE));
|
||||||
if(file == NULL) return NULL;
|
if(file == NULL) return NULL;
|
||||||
|
mtx_init(&file->lock, mtx_recursive);
|
||||||
file->handle = handle;
|
file->handle = handle;
|
||||||
file->name = name; // TODO: strdup this
|
file->name = strdup(name);
|
||||||
file->type = type;
|
file->type = type;
|
||||||
file->flags = flags;
|
file->flags = flags;
|
||||||
file->mode = mode;
|
file->mode = mode;
|
||||||
|
// Buffer for cache
|
||||||
|
file->buftype = buftype;
|
||||||
|
file->bufsize = bufsize;
|
||||||
|
file->buffer = buffer;
|
||||||
|
file->bufidx = 0;
|
||||||
|
// Multibyte state
|
||||||
file->mbstate = (mbstate_t){0};
|
file->mbstate = (mbstate_t){0};
|
||||||
mtx_init(&file->lock, mtx_recursive);
|
// Append to list of all streams
|
||||||
if(file_list_last != NULL) {
|
if(file_list_last != NULL) {
|
||||||
file_list_last->next = file;
|
file_list_last->next = file;
|
||||||
file->prev = file_list_last;
|
file->prev = file_list_last;
|
||||||
|
@ -86,9 +97,8 @@ static inline void dispose_file(FILE *file) {
|
||||||
// Only close the file if it's not a standard handle
|
// Only close the file if it's not a standard handle
|
||||||
if(file->name) {
|
if(file->name) {
|
||||||
CloseHandle(file->handle);
|
CloseHandle(file->handle);
|
||||||
//TODO: free(file->name);
|
free(file->name);
|
||||||
}
|
}
|
||||||
// TODO: flush streams
|
|
||||||
FILE *prev = file->prev;
|
FILE *prev = file->prev;
|
||||||
FILE *next = file->next;
|
FILE *next = file->next;
|
||||||
if(prev != NULL) prev->next = next;
|
if(prev != NULL) prev->next = next;
|
||||||
|
@ -128,6 +138,7 @@ int setvbuf(
|
||||||
int mode,
|
int mode,
|
||||||
size_t size
|
size_t size
|
||||||
) {
|
) {
|
||||||
|
mtx_lock(&stream->lock);
|
||||||
if(mode == _IONBF) {
|
if(mode == _IONBF) {
|
||||||
stream->buftype = mode;
|
stream->buftype = mode;
|
||||||
stream->buffer = NULL;
|
stream->buffer = NULL;
|
||||||
|
@ -146,24 +157,52 @@ int setvbuf(
|
||||||
stream->buftype = mode;
|
stream->buftype = mode;
|
||||||
stream->buffer = buf;
|
stream->buffer = buf;
|
||||||
stream->bufsize = size;
|
stream->bufsize = size;
|
||||||
|
mtx_unlock(&stream->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setbuf(FILE *restrict stream, char *restrict buf) {
|
||||||
|
int mode = _IOFBF;
|
||||||
|
if(buf == NULL) {
|
||||||
|
mode = _IONBF;
|
||||||
|
}
|
||||||
|
setvbuf(stream, buf, mode, BUFSIZ);
|
||||||
|
}
|
||||||
|
|
||||||
int fflush(FILE *stream) {
|
int fflush(FILE *stream) {
|
||||||
if(stream->mode == _IOFBF) {
|
mtx_lock(&stream->lock);
|
||||||
|
if(stream->buftype != _IONBF) {
|
||||||
|
DWORD written;
|
||||||
|
BOOL ok = WriteFile(
|
||||||
|
stream->handle,
|
||||||
|
stream->buffer,
|
||||||
|
stream->bufidx,
|
||||||
|
&written,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if(!ok) {
|
||||||
|
errno = EIO;
|
||||||
|
return EOF;
|
||||||
}
|
}
|
||||||
else if(stream->mode == _IONBF) {
|
stream->bufidx = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
mtx_unlock(&stream->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fputc(int c, FILE *stream) {
|
static int try_fputc(FILE *stream, char c) {
|
||||||
mtx_lock(&stream->lock);
|
if(stream->buftype != _IONBF) {
|
||||||
|
stream->buffer[stream->bufidx++] = c;
|
||||||
|
if(stream->bufidx > stream->bufsize) {
|
||||||
|
return fflush(stream);
|
||||||
|
}
|
||||||
|
if(stream->buftype == _IOLBF && c == '\n') {
|
||||||
|
return fflush(stream);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
DWORD written;
|
DWORD written;
|
||||||
BOOL ok = WriteFile(stream->handle, &c, 1, &written, NULL);
|
BOOL ok = WriteFile(stream->handle, &c, 1, &written, NULL);
|
||||||
mtx_unlock(&stream->lock);
|
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return EOF;
|
return EOF;
|
||||||
|
@ -171,9 +210,28 @@ int fputc(int c, FILE *stream) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setbuf(FILE *restrict stream, char *restrict buf) {
|
static int try_fputs(FILE *stream, char *str, size_t len) {
|
||||||
if(buf != NULL)
|
for(size_t i = 0; i != len; ++i) {
|
||||||
setvbuf(stream, buf, _IOFBF, BUFSIZ);
|
int cw = try_fputc(stream, str[i]);
|
||||||
else
|
if(cw == EOF) return EOF;
|
||||||
setvbuf(stream, buf, _IONBF, BUFSIZ);
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fputc(int c, FILE *stream) {
|
||||||
|
mtx_lock(&stream->lock);
|
||||||
|
int res = try_fputc(stream, c);
|
||||||
|
mtx_unlock(&stream->lock);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fputs(const char *restrict s, FILE *stream) {
|
||||||
|
mtx_lock(&stream->lock);
|
||||||
|
while(*s) {
|
||||||
|
int res = try_fputc(stream, *s);
|
||||||
|
if(res == EOF) return EOF;
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
mtx_unlock(&stream->lock);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
for(int i = 0; i != 512; ++i)
|
||||||
fputc('Z', stdout);
|
fputc('Z', stdout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue