6 #include "settings.h" |
6 #include "settings.h" |
7 |
7 |
8 typedef struct IniFile IniFile; |
8 typedef struct IniFile IniFile; |
9 typedef struct IniItem IniItem; |
9 typedef struct IniItem IniItem; |
10 typedef struct IniGroup IniGroup; |
10 typedef struct IniGroup IniGroup; |
11 typedef struct MemoryPool MemoryPool; |
11 typedef struct SettingsMemoryPool SettingsMemoryPool; |
12 |
12 |
13 static void pool_init(MemoryPool **pool); |
13 static void pool_init(SettingsMemoryPool **pool); |
14 static void *pool_alloc(MemoryPool **pool, uint size); |
14 static void *pool_alloc(SettingsMemoryPool **pool, uint size); |
15 static void *pool_strdup(MemoryPool **pool, const char *mem, uint size); |
15 static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size); |
16 static void pool_free(MemoryPool **pool); |
16 static void pool_free(SettingsMemoryPool **pool); |
17 |
17 |
18 struct MemoryPool { |
18 struct SettingsMemoryPool { |
19 uint pos,size; |
19 uint pos,size; |
20 MemoryPool *next; |
20 SettingsMemoryPool *next; |
21 byte mem[1]; |
21 byte mem[1]; |
22 }; |
22 }; |
23 |
23 |
24 static MemoryPool *pool_new(uint minsize) |
24 static SettingsMemoryPool *pool_new(uint minsize) |
25 { |
25 { |
26 MemoryPool *p; |
26 SettingsMemoryPool *p; |
27 if (minsize < 4096 - 12) minsize = 4096 - 12; |
27 if (minsize < 4096 - 12) minsize = 4096 - 12; |
28 |
28 |
29 p = malloc(sizeof(MemoryPool) - 1 + minsize); |
29 p = malloc(sizeof(SettingsMemoryPool) - 1 + minsize); |
30 p->pos = 0; |
30 p->pos = 0; |
31 p->size = minsize; |
31 p->size = minsize; |
32 p->next = NULL; |
32 p->next = NULL; |
33 return p; |
33 return p; |
34 } |
34 } |
35 |
35 |
36 static void pool_init(MemoryPool **pool) |
36 static void pool_init(SettingsMemoryPool **pool) |
37 { |
37 { |
38 *pool = pool_new(0); |
38 *pool = pool_new(0); |
39 } |
39 } |
40 |
40 |
41 static void *pool_alloc(MemoryPool **pool, uint size) |
41 static void *pool_alloc(SettingsMemoryPool **pool, uint size) |
42 { |
42 { |
43 uint pos; |
43 uint pos; |
44 MemoryPool *p = *pool; |
44 SettingsMemoryPool *p = *pool; |
45 |
45 |
46 size = (size + 3) & ~3; // align everything to a 32 bit boundary |
46 size = (size + 3) & ~3; // align everything to a 32 bit boundary |
47 |
47 |
48 // first check if there's memory in the next pool |
48 // first check if there's memory in the next pool |
49 if (p->next && p->next->pos + size <= p->next->size) { |
49 if (p->next && p->next->pos + size <= p->next->size) { |
50 p = p->next; |
50 p = p->next; |
51 // then check if there's not memory in the cur pool |
51 // then check if there's not memory in the cur pool |
52 } else if (p->pos + size > p->size) { |
52 } else if (p->pos + size > p->size) { |
53 MemoryPool *n = pool_new(size); |
53 SettingsMemoryPool *n = pool_new(size); |
54 *pool = n; |
54 *pool = n; |
55 n->next = p; |
55 n->next = p; |
56 p = n; |
56 p = n; |
57 } |
57 } |
58 |
58 |
59 pos = p->pos; |
59 pos = p->pos; |
60 p->pos += size; |
60 p->pos += size; |
61 return p->mem + pos; |
61 return p->mem + pos; |
62 } |
62 } |
63 |
63 |
64 static void *pool_strdup(MemoryPool **pool, const char *mem, uint size) |
64 static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size) |
65 { |
65 { |
66 byte *p = pool_alloc(pool, size + 1); |
66 byte *p = pool_alloc(pool, size + 1); |
67 p[size] = 0; |
67 p[size] = 0; |
68 memcpy(p, mem, size); |
68 memcpy(p, mem, size); |
69 return p; |
69 return p; |
70 } |
70 } |
71 |
71 |
72 static void pool_free(MemoryPool **pool) |
72 static void pool_free(SettingsMemoryPool **pool) |
73 { |
73 { |
74 MemoryPool *p = *pool, *n; |
74 SettingsMemoryPool *p = *pool, *n; |
75 *pool = NULL; |
75 *pool = NULL; |
76 while (p) { |
76 while (p) { |
77 n = p->next; |
77 n = p->next; |
78 free(p); |
78 free(p); |
79 p = n; |
79 p = n; |
96 IniFile *ini; |
96 IniFile *ini; |
97 IniGroupType type; // type of group |
97 IniGroupType type; // type of group |
98 }; |
98 }; |
99 |
99 |
100 struct IniFile { |
100 struct IniFile { |
101 MemoryPool *pool; |
101 SettingsMemoryPool *pool; |
102 IniGroup *group, **last_group; |
102 IniGroup *group, **last_group; |
103 char *comment; // last comment in file |
103 char *comment; // last comment in file |
104 }; |
104 }; |
105 |
105 |
106 // allocate an inifile object |
106 // allocate an inifile object |
107 static IniFile *ini_alloc(void) |
107 static IniFile *ini_alloc(void) |
108 { |
108 { |
109 IniFile *ini; |
109 IniFile *ini; |
110 MemoryPool *pool; |
110 SettingsMemoryPool *pool; |
111 pool_init(&pool); |
111 pool_init(&pool); |
112 ini = (IniFile*)pool_alloc(&pool, sizeof(IniFile)); |
112 ini = (IniFile*)pool_alloc(&pool, sizeof(IniFile)); |
113 ini->pool = pool; |
113 ini->pool = pool; |
114 ini->group = NULL; |
114 ini->group = NULL; |
115 ini->last_group = &ini->group; |
115 ini->last_group = &ini->group; |