-
Notifications
You must be signed in to change notification settings - Fork 0
/
SODB.h
160 lines (138 loc) · 4.41 KB
/
SODB.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <memory.h>
#define SODBBool char
#define SODB_TRUE 1
#define SODB_FALSE 0
/*
SODB (Simple Object Data Base)
This database software is meant to be uber simple to
use and deploy. Being header only and compatible
with older c compilers means this should be uber
easy to port to nearly any platform.
LAYOUT:
The layout is simple, it stores flat struct objects of
any desired size and number. It assumes there's only
one object type. And that we are searching based on
index. Can only use uint32_t number of objects. File
sizes are expected to be uint32_t number of bytes big.
The header takes up 8 of these bytes. File size grows
with the data and there's no pre allocation.
HEADER:
The header layout is really basic and simple. The
first 32 bits are reserved for telling the object count.
The second 32 bits describe how big every object can be.
WARNING:
This is not designed or intended to be multithreaded.
There is no compression or encryption of any kind.
Endiness must be considered when moving the data from
one platform to another.
NOTE:
This is meant to be compatible with the psxe compiler
which is why variables are declared before code within
any scope. Also why there's a weird set of defines for
bools.
*/
uint32_t fileGetSize(FILE *fp){
uint32_t prev;
uint32_t size;
prev=ftell(fp);
fseek(fp, 0, SEEK_END);
size=ftell(fp);
fseek(fp,prev,SEEK_SET);
return size;
}
struct SODBHeader {
uint32_t count;
uint32_t sizeOfObject;
};
SODBBool SODBInit(char *fileName, uint32_t objectSize){
FILE *file = fopen(fileName, "w");
struct SODBHeader header = {0, objectSize};
if(!file){
printf("SODB Error: Couldn't open file ", fileName, "\n");
return SODB_FALSE;
}
fwrite(&header, sizeof(struct SODBHeader), 1, file);
fclose(file);
return SODB_TRUE;
}
SODBBool SODBIsValid(char *fileName){
FILE *file = fopen(fileName, "r+");
uint32_t fileSize;
struct SODBHeader header;
if(!file){
printf("SODB Error: Couldn't open file ", fileName, "\n");
return SODB_FALSE;
}
fileSize = fileGetSize(file);
if(fileSize < 8){
printf("SODB Error: File ", *fileName, " corrupt, not properly initialized\n");
fclose(file);
return SODB_FALSE;
}
fread(&header, 8, 1, file) ;
if(fileSize < header.count*header.sizeOfObject+8){
printf("SODB Error: index out of range\n");
fclose(file);
return SODB_FALSE;
}
fclose(file);
return SODB_TRUE;
}
SODBBool SODBGet(char *fileName, uint32_t index, void *outObjectBuffer){
{if(SODBIsValid(fileName) == SODB_FALSE) return SODB_TRUE;}
FILE *file = fopen(fileName, "r+");
struct SODBHeader header;
if(!file){
printf("SODB Error: Couldn't open file ", fileName, "\n");
return SODB_FALSE;
}
fread(&header, 8, 1, file);
if(index > header.count){
printf("SODB Error: index out of range\n");
fclose(file);
return SODB_FALSE;
}
fseek(file, 8+index*header.sizeOfObject, SEEK_SET);
fread(outObjectBuffer, header.sizeOfObject, 1, file);
fclose(file);
return SODB_TRUE;
}
SODBBool SODBReplace(char *fileName, uint32_t index, void *object){
{if(SODBIsValid(fileName) == SODB_FALSE) return SODB_TRUE;}
FILE *file = fopen(fileName, "r+");
struct SODBHeader header;
if(!file){
printf("SODB Error: Couldn't open file ", fileName, "\n");
return SODB_FALSE;
}
fread(&header, 8, 1, file);
if(index > header.count){
printf("SODB Error: index out of range\n");
fclose(file);
return SODB_FALSE;
}
fseek(file, 8+index*header.sizeOfObject, SEEK_SET);
fwrite(object, header.sizeOfObject, 1, file);
fclose(file);
return SODB_TRUE;
}
SODBBool SODBAppend(char *fileName, void *object){
{if(SODBIsValid(fileName) == SODB_FALSE) return SODB_FALSE;}
FILE *file = fopen(fileName, "r+");
struct SODBHeader header;
if(!file){
printf("SODB Error: Couldn't open file ", fileName, "\n");
return SODB_FALSE;
}
fread(&header, 8, 1, file);
fseek(file, 0, SEEK_SET);
header.count++;
fwrite(&header, sizeof(struct SODBHeader), 1, file);
fseek(file, 8+(header.count*header.sizeOfObject-header.sizeOfObject), SEEK_SET);
fwrite(object, header.sizeOfObject, 1, file);
fclose(file);
return SODB_TRUE;
}