Skip to content

Commit 542c2f8

Browse files
committed
Add Persistence file
1 parent 9ceca1c commit 542c2f8

File tree

2 files changed

+263
-0
lines changed

2 files changed

+263
-0
lines changed

include/persistence.h

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
#ifndef PERSISTENCE_H
2+
#define PERSISTENCE_H
3+
4+
#include "stdio.h"
5+
6+
template<typename T>
7+
struct persist_t {
8+
int id;
9+
T persist_struct;
10+
};
11+
12+
template<typename T>
13+
struct persists_t {
14+
int size;
15+
persist_t<T> *persist_array;
16+
};
17+
18+
template<class retT>
19+
class Persistence
20+
{
21+
public:
22+
Persistence(int id);
23+
24+
~Persistence();
25+
26+
static void set_location(std::string location);
27+
28+
int get_id(void);
29+
30+
std::string get_string_id(void);
31+
32+
int read_persists(persists_t<retT> **persists);
33+
34+
int write_persists(persists_t<retT> *persists);
35+
36+
int get_persist(persist_t<retT> **persist, int entry_id);
37+
38+
int get_persist(retT **persist_struct, int entry_id);
39+
40+
int remove_persist(int entry_id);
41+
42+
int add_persist(persist_t<retT> *persist);
43+
44+
int add_persist(retT *persist_struct, int entry_id);
45+
46+
private:
47+
bool _entry_exists(persists_t<retT> *persists, int entry_id);
48+
int _id;
49+
static std::string _location;
50+
};
51+
52+
template<class retT>
53+
Persistence<retT>::Persistence(int id)
54+
{
55+
_id = id;
56+
}
57+
58+
template<class retT>
59+
Persistence<retT>::~Persistence() {}
60+
61+
template<class retT>
62+
void Persistence<retT>::set_location(std::string location) {
63+
Persistence<retT>::_location = std::string(location);
64+
}
65+
66+
template<class retT>
67+
int Persistence<retT>::get_id(void) {
68+
return _id;
69+
}
70+
71+
template<class retT>
72+
std::string Persistence<retT>::get_string_id(void) {
73+
int length = std::snprintf( nullptr, 0, "%i", _id );
74+
assert( length >= 0 );
75+
76+
char* buf = new char[length + 1];
77+
std::snprintf( buf, length + 1, "%i", _id );
78+
79+
std::string str( buf );
80+
delete[] buf;
81+
return str;
82+
}
83+
84+
template<class retT>
85+
int Persistence<retT>::read_persists(persists_t<retT> **persists)
86+
{
87+
int size = 0;
88+
std::string file_location = Persistence<retT>::_location + get_string_id();
89+
FILE *fp = fopen(file_location.c_str(), "r");
90+
if(!fp) {
91+
*persists = new persists_t<retT>({.size=0, .persist_array=nullptr});
92+
return 0;
93+
}
94+
fseek(fp, 0, SEEK_SET);
95+
fread(&size, sizeof(int), 1, fp);
96+
if(size>0) {
97+
fseek(fp, sizeof(int), SEEK_SET);
98+
persist_t<retT> *persist_array = new persist_t<retT>[size];
99+
fread(persist_array, sizeof(persist_t<retT>)*size, 1, fp);
100+
*persists = new persists_t<retT>({.size=size, .persist_array=persist_array});
101+
} else {
102+
*persists = new persists_t<retT>({.size=size, .persist_array=nullptr});
103+
}
104+
fclose(fp);
105+
return 0;
106+
}
107+
108+
template<class retT>
109+
int Persistence<retT>::write_persists(persists_t<retT> *persists)
110+
{
111+
std::string file_location = Persistence<retT>::_location + get_string_id();
112+
FILE *fp = fopen(file_location.c_str(), "w");
113+
if(!fp) {
114+
return -1;
115+
}
116+
fseek(fp, 0, SEEK_SET);
117+
fwrite(&(persists->size), sizeof(int), 1, fp);
118+
fseek(fp, sizeof(int), SEEK_SET);
119+
fwrite(persists->persist_array, sizeof(persist_t<retT>)*persists->size, 1, fp);
120+
fclose(fp);
121+
return 0;
122+
}
123+
124+
template<class retT>
125+
int Persistence<retT>::get_persist(persist_t<retT> **persist, int entry_id)
126+
{
127+
persists_t<retT> *persists;
128+
int err = read_persists(&persists);
129+
if(err) {
130+
return err;
131+
}
132+
for (int i=0; i<persists->size; i++) {
133+
if((persists->persist_array)[i].id == entry_id) {
134+
*persist = new persist_t<retT>((persists->persist_array)[i]);
135+
break;
136+
}
137+
}
138+
delete persists->persist_array;
139+
delete persists;
140+
return 0;
141+
}
142+
143+
template<class retT>
144+
int Persistence<retT>::get_persist(retT **persist_struct, int entry_id)
145+
{
146+
persist_t<retT> *persist;
147+
int err = get_persist(&persist, entry_id);
148+
if(err) {
149+
return err;
150+
}
151+
if(persist != nullptr) {
152+
*persist_struct = new retT(persist->persist_struct);
153+
delete persist;
154+
}
155+
return 0;
156+
}
157+
158+
template<class retT>
159+
int Persistence<retT>::remove_persist(int entry_id)
160+
{
161+
persists_t<retT> *persists;
162+
int err = read_persists(&persists);
163+
if(err) {
164+
return err;
165+
}
166+
int new_size=0;
167+
if(_entry_exists(persists, entry_id)) {
168+
new_size = persists->size - 1;
169+
} else {
170+
return 0;
171+
}
172+
persist_t<retT> *persist_array = new persist_t<retT>[new_size];
173+
for (int i=0; i<persists->size; i++) {
174+
if((persists->persist_array)[i].id == entry_id) {
175+
176+
continue;
177+
}
178+
memcpy(&persist_array[i], &(persists->persist_array)[i], sizeof(persist_t<retT>));
179+
}
180+
delete persists->persist_array;
181+
delete persists;
182+
persists = new persists_t<retT>({.size=new_size, .persist_array=persist_array});
183+
err = write_persists(persists);
184+
delete persists->persist_array;
185+
delete persists;
186+
return err;
187+
}
188+
189+
template<class retT>
190+
int Persistence<retT>::add_persist(persist_t<retT> *persist)
191+
{
192+
persists_t<retT> *persists;
193+
int err = read_persists(&persists);
194+
if(err) {
195+
return err;
196+
}
197+
int size=0;
198+
if(_entry_exists(persists, persist->id)) {
199+
size = persists->size;
200+
} else {
201+
size = persists->size + 1;
202+
}
203+
persist_t<retT> *persist_array = new persist_t<retT>[size];
204+
for (int i=0; i<persists->size;i++) {
205+
if((persists->persist_array)[i].id == persist->id) {
206+
continue;
207+
}
208+
memcpy(&persist_array[i], &(persists->persist_array)[i], sizeof(persist_t<retT>));
209+
}
210+
memcpy(&persist_array[size-1], persist, sizeof(persist_t<retT>));
211+
delete persists->persist_array;
212+
delete persists;
213+
persists = new persists_t<retT>({.size=size, .persist_array=persist_array});
214+
err = write_persists(persists);
215+
delete persists->persist_array;
216+
delete persists;
217+
return err;
218+
}
219+
220+
template<class retT>
221+
int Persistence<retT>::add_persist(retT *persist_struct, int entry_id)
222+
{
223+
persist_t<retT> persist({.id=entry_id, .persist_struct=*persist_struct});
224+
return add_persist(&persist);
225+
}
226+
227+
template<class retT>
228+
bool Persistence<retT>::_entry_exists(persists_t<retT> *persists, int entry_id)
229+
{
230+
for (int i=0; i<persists->size;i++) {
231+
if((persists->persist_array)[i].id == entry_id) {
232+
return true;
233+
}
234+
}
235+
return false;
236+
}
237+
238+
template<class retT>
239+
std::string Persistence<retT>::_location = "";
240+
241+
#endif

library.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "Persistence",
3+
"version": "0.1.0",
4+
"description": "Persistence Library",
5+
"keywords": "Persistence",
6+
"repository":
7+
{
8+
"type": "git",
9+
"url": "https://github.com/jaster-prj/Persistence.git"
10+
},
11+
"authors":
12+
[
13+
{
14+
"name": "Tobias Jaster",
15+
"email": "[email protected]",
16+
"maintainer": true
17+
}
18+
],
19+
"license": "MIT",
20+
"frameworks": "*",
21+
"platforms": "*"
22+
}

0 commit comments

Comments
 (0)