diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/eet/src/examples/eet-data-nested.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/eet/src/examples/eet-data-nested.c')
-rw-r--r-- | libraries/eet/src/examples/eet-data-nested.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/libraries/eet/src/examples/eet-data-nested.c b/libraries/eet/src/examples/eet-data-nested.c new file mode 100644 index 0000000..a6b0e12 --- /dev/null +++ b/libraries/eet/src/examples/eet-data-nested.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* | ||
2 | * build: gcc -o eet_data_nested eet-data-nested.c `pkg-config --cflags --libs eet eina` | ||
3 | */ | ||
4 | #include <Eina.h> | ||
5 | #include <Eet.h> | ||
6 | #include <stdio.h> | ||
7 | #include <limits.h> | ||
8 | #include <sys/types.h> | ||
9 | #include <sys/stat.h> | ||
10 | #include <unistd.h> | ||
11 | |||
12 | // The struct that will be loaded and saved. | ||
13 | // note that only the members described in the eet_data_descriptor | ||
14 | // will be automatically handled. The other members will have their | ||
15 | // space reserved and zeroed (as it uses calloc()), but not | ||
16 | // saved or loaded from eet files. | ||
17 | typedef struct | ||
18 | { | ||
19 | unsigned int version; // it is recommended to use versioned configuration! | ||
20 | const char *name; | ||
21 | int id; | ||
22 | int not_saved_value; // example of not saved data inside! | ||
23 | Eina_Bool enabled; | ||
24 | Eina_List *subs; | ||
25 | } My_Conf_Type; | ||
26 | |||
27 | typedef struct | ||
28 | { | ||
29 | const char *server; | ||
30 | int port; | ||
31 | } My_Conf_Subtype; | ||
32 | |||
33 | // string that represents the entry in eet file, you might like to have | ||
34 | // different profiles or so in the same file, this is possible with | ||
35 | // different strings | ||
36 | static const char MY_CONF_FILE_ENTRY[] = "config"; | ||
37 | |||
38 | // keep the descriptor static global, so it can be | ||
39 | // shared by different functions (load/save) of this and only this | ||
40 | // file. | ||
41 | static Eet_Data_Descriptor *_my_conf_descriptor; | ||
42 | static Eet_Data_Descriptor *_my_conf_sub_descriptor; | ||
43 | |||
44 | static void | ||
45 | _my_conf_descriptor_init(void) | ||
46 | { | ||
47 | Eet_Data_Descriptor_Class eddc; | ||
48 | |||
49 | // The class describe the functions to use to create the type and its | ||
50 | // full allocated size. | ||
51 | // | ||
52 | // Eina types are very convenient, so use them to create the descriptor, | ||
53 | // so we get eina_list, eina_hash and eina_stringshare automatically! | ||
54 | // | ||
55 | // The STREAM variant is better for configuration files as the values | ||
56 | // will likely change a lot. | ||
57 | // | ||
58 | // The other variant, FILE, is good for caches and things that are just | ||
59 | // appended, but needs to take care when changing strings and files must | ||
60 | // be kept open so mmap()ed strings will be kept alive. | ||
61 | EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Conf_Type); | ||
62 | _my_conf_descriptor = eet_data_descriptor_stream_new(&eddc); | ||
63 | |||
64 | EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Conf_Subtype); | ||
65 | _my_conf_sub_descriptor = eet_data_descriptor_stream_new(&eddc); | ||
66 | |||
67 | // Describe the members to be saved: | ||
68 | // Use a temporary macro so we don't type a lot, also avoid errors: | ||
69 | #define MY_CONF_ADD_BASIC(member, eet_type) \ | ||
70 | EET_DATA_DESCRIPTOR_ADD_BASIC \ | ||
71 | (_my_conf_descriptor, My_Conf_Type, # member, member, eet_type) | ||
72 | #define MY_CONF_SUB_ADD_BASIC(member, eet_type) \ | ||
73 | EET_DATA_DESCRIPTOR_ADD_BASIC \ | ||
74 | (_my_conf_sub_descriptor, My_Conf_Subtype, # member, member, eet_type) | ||
75 | |||
76 | MY_CONF_SUB_ADD_BASIC(server, EET_T_STRING); | ||
77 | MY_CONF_SUB_ADD_BASIC(port, EET_T_INT); | ||
78 | |||
79 | MY_CONF_ADD_BASIC(version, EET_T_UINT); | ||
80 | MY_CONF_ADD_BASIC(name, EET_T_STRING); | ||
81 | MY_CONF_ADD_BASIC(id, EET_T_INT); | ||
82 | MY_CONF_ADD_BASIC(enabled, EET_T_UCHAR); | ||
83 | |||
84 | // And add the sub descriptor as a linked list at 'subs' in the main struct | ||
85 | EET_DATA_DESCRIPTOR_ADD_LIST | ||
86 | (_my_conf_descriptor, My_Conf_Type, "subs", subs, _my_conf_sub_descriptor); | ||
87 | |||
88 | #undef MY_CONF_ADD_BASIC | ||
89 | #undef MY_CONF_SUB_ADD_BASIC | ||
90 | } /* _my_conf_descriptor_init */ | ||
91 | |||
92 | static void | ||
93 | _my_conf_descriptor_shutdown(void) | ||
94 | { | ||
95 | eet_data_descriptor_free(_my_conf_sub_descriptor); | ||
96 | eet_data_descriptor_free(_my_conf_descriptor); | ||
97 | } /* _my_conf_descriptor_shutdown */ | ||
98 | |||
99 | static My_Conf_Type * | ||
100 | _my_conf_new(void) | ||
101 | { | ||
102 | My_Conf_Type *my_conf = calloc(1, sizeof(My_Conf_Type)); | ||
103 | My_Conf_Subtype *sub; | ||
104 | if (!my_conf) | ||
105 | { | ||
106 | fprintf(stderr, "ERROR: could not calloc My_Conf_Type\n"); | ||
107 | return NULL; | ||
108 | } | ||
109 | |||
110 | my_conf->version = 0x112233; | ||
111 | my_conf->enabled = EINA_TRUE; | ||
112 | |||
113 | sub = calloc(1, sizeof(My_Conf_Subtype)); | ||
114 | if (sub) | ||
115 | { | ||
116 | sub->server = eina_stringshare_add("my-server.com"); | ||
117 | sub->port = 1234; | ||
118 | my_conf->subs = eina_list_append(my_conf->subs, sub); | ||
119 | } | ||
120 | |||
121 | return my_conf; | ||
122 | } /* _my_conf_new */ | ||
123 | |||
124 | static void | ||
125 | _my_conf_free(My_Conf_Type *my_conf) | ||
126 | { | ||
127 | My_Conf_Subtype *sub; | ||
128 | EINA_LIST_FREE(my_conf->subs, sub) | ||
129 | { | ||
130 | eina_stringshare_del(sub->server); | ||
131 | free(sub); | ||
132 | } | ||
133 | |||
134 | eina_stringshare_del(my_conf->name); | ||
135 | free(my_conf); | ||
136 | } /* _my_conf_free */ | ||
137 | |||
138 | static My_Conf_Type * | ||
139 | _my_conf_load(const char *filename) | ||
140 | { | ||
141 | My_Conf_Type *my_conf; | ||
142 | Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ); | ||
143 | if (!ef) | ||
144 | { | ||
145 | fprintf(stderr, "ERROR: could not open '%s' for read\n", filename); | ||
146 | return NULL; | ||
147 | } | ||
148 | |||
149 | my_conf = eet_data_read(ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY); | ||
150 | if (!my_conf) | ||
151 | goto end; | ||
152 | |||
153 | if (my_conf->version < 0x112233) | ||
154 | { | ||
155 | fprintf(stderr, | ||
156 | "WARNING: version %#x was too old, upgrading it to %#x\n", | ||
157 | my_conf->version, 0x112233); | ||
158 | |||
159 | my_conf->version = 0x112233; | ||
160 | my_conf->enabled = EINA_TRUE; | ||
161 | } | ||
162 | |||
163 | end: | ||
164 | eet_close(ef); | ||
165 | return my_conf; | ||
166 | } /* _my_conf_load */ | ||
167 | |||
168 | static Eina_Bool | ||
169 | _my_conf_save(const My_Conf_Type *my_conf, | ||
170 | const char *filename) | ||
171 | { | ||
172 | char tmp[PATH_MAX]; | ||
173 | Eet_File *ef; | ||
174 | Eina_Bool ret; | ||
175 | unsigned int i, len; | ||
176 | struct stat st; | ||
177 | |||
178 | len = eina_strlcpy(tmp, filename, sizeof(tmp)); | ||
179 | if (len + 12 >= (int)sizeof(tmp)) | ||
180 | { | ||
181 | fprintf(stderr, "ERROR: file name is too big: %s\n", filename); | ||
182 | return EINA_FALSE; | ||
183 | } | ||
184 | |||
185 | i = 0; | ||
186 | do | ||
187 | { | ||
188 | snprintf(tmp + len, 12, ".%u", i); | ||
189 | i++; | ||
190 | } | ||
191 | while (stat(tmp, &st) == 0); | ||
192 | |||
193 | ef = eet_open(tmp, EET_FILE_MODE_WRITE); | ||
194 | if (!ef) | ||
195 | { | ||
196 | fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp); | ||
197 | return EINA_FALSE; | ||
198 | } | ||
199 | |||
200 | ret = eet_data_write | ||
201 | (ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY, my_conf, EINA_TRUE); | ||
202 | eet_close(ef); | ||
203 | |||
204 | if (ret) | ||
205 | { | ||
206 | unlink(filename); | ||
207 | rename(tmp, filename); | ||
208 | } | ||
209 | |||
210 | return ret; | ||
211 | } /* _my_conf_save */ | ||
212 | |||
213 | int | ||
214 | main(int argc, | ||
215 | char *argv[]) | ||
216 | { | ||
217 | My_Conf_Type *my_conf; | ||
218 | const My_Conf_Subtype *sub; | ||
219 | const Eina_List *l; | ||
220 | int ret = 0; | ||
221 | |||
222 | if (argc != 3) | ||
223 | { | ||
224 | fprintf(stderr, "Usage:\n\t%s <input> <output>\n\n", argv[0]); | ||
225 | return -1; | ||
226 | } | ||
227 | |||
228 | eina_init(); | ||
229 | eet_init(); | ||
230 | _my_conf_descriptor_init(); | ||
231 | |||
232 | my_conf = _my_conf_load(argv[1]); | ||
233 | if (!my_conf) | ||
234 | { | ||
235 | printf("creating new configuration.\n"); | ||
236 | my_conf = _my_conf_new(); | ||
237 | if (!my_conf) | ||
238 | { | ||
239 | ret = -2; | ||
240 | goto end; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | printf("My_Conf_Type:\n" | ||
245 | "\tversion: %#x\n" | ||
246 | "\tname...: '%s'\n" | ||
247 | "\tid.....: %d\n" | ||
248 | "\tenabled: %hhu\n" | ||
249 | "\tsubs...:\n", | ||
250 | my_conf->version, | ||
251 | my_conf->name ? my_conf->name : "", | ||
252 | my_conf->id, | ||
253 | my_conf->enabled); | ||
254 | |||
255 | EINA_LIST_FOREACH(my_conf->subs, l, sub) | ||
256 | printf("\t\tserver: '%s', port: %d\n", | ||
257 | sub->server ? sub->server : "", | ||
258 | sub->port); | ||
259 | |||
260 | if (!_my_conf_save(my_conf, argv[2])) | ||
261 | ret = -3; | ||
262 | |||
263 | _my_conf_free(my_conf); | ||
264 | |||
265 | end: | ||
266 | _my_conf_descriptor_shutdown(); | ||
267 | eet_shutdown(); | ||
268 | eina_shutdown(); | ||
269 | |||
270 | return ret; | ||
271 | } /* main */ | ||
272 | |||