
\begin{DoxyCodeInclude}
1 \textcolor{comment}{//Compile with:}
2 \textcolor{comment}{// gcc -o eet-data-file\_descriptor\_01 eet-data-file\_descriptor\_01.c `pkg-config --cflags --libs eet eina`}
3 
4 \textcolor{preprocessor}{#include <\hyperlink{Eina_8h}{Eina.h}>}
5 \textcolor{preprocessor}{#include <\hyperlink{Eet_8h}{Eet.h}>}
6 \textcolor{preprocessor}{#include <stdio.h>}
7 \textcolor{preprocessor}{#include <limits.h>}
8 \textcolor{preprocessor}{#include <sys/types.h>}
9 \textcolor{preprocessor}{#include <sys/stat.h>}
10 \textcolor{preprocessor}{#include <unistd.h>}
11 
12 \textcolor{comment}{// complex real-world structures based on elmdentica database}
13 \textcolor{keyword}{typedef} \textcolor{keyword}{struct}
14 \{
15    \textcolor{keyword}{const} \textcolor{keywordtype}{char}  *screen\_name;
16    \textcolor{keyword}{const} \textcolor{keywordtype}{char}  *name;
17    \textcolor{keyword}{const} \textcolor{keywordtype}{char}  *message;
18    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} id;
19    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} status\_id;
20    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} date;
21    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} timeline;
22 \} My\_Message;
23 
24 \textcolor{keyword}{typedef} \textcolor{keyword}{struct}
25 \{
26    \textcolor{keyword}{const} \textcolor{keywordtype}{char} *dm\_to;
27    \textcolor{keyword}{const} \textcolor{keywordtype}{char} *message;
28 \} My\_Post;
29 
30 \textcolor{keyword}{typedef} \textcolor{keyword}{struct}
31 \{
32    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} id;
33    \textcolor{keyword}{const} \textcolor{keywordtype}{char}  *name;
34    \hyperlink{struct__Eina__List}{Eina\_List}   *messages;
35    My\_Post     *posts;
36    \textcolor{keywordtype}{int}          posts\_count;
37 \} My\_Account;
38 
39 \textcolor{keyword}{typedef} \textcolor{keyword}{struct}
40 \{
41    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} version; \textcolor{comment}{// it is recommended to use versioned configuration!}
42    \hyperlink{group__Eina__Hash__Group_ga9a89d7d3ee260d3a60572ebf651b07e0}{Eina\_Hash}   *accounts;
43 \} My\_Cache;
44 
45 \textcolor{comment}{// string that represents the entry in eet file, you might like to have}
46 \textcolor{comment}{// different profiles or so in the same file, this is possible with}
47 \textcolor{comment}{// different strings}
48 \textcolor{keyword}{static} \textcolor{keyword}{const} \textcolor{keywordtype}{char} MY\_CACHE\_FILE\_ENTRY[] = \textcolor{stringliteral}{"cache"};
49 
50 \textcolor{comment}{// keep the descriptor static global, so it can be}
51 \textcolor{comment}{// shared by different functions (load/save) of this and only this}
52 \textcolor{comment}{// file.}
53 \textcolor{keyword}{static} \hyperlink{group__Eet__Data__Group_ga4baec0e840012480a0958c5c3bca276d}{Eet\_Data\_Descriptor} *\_my\_cache\_descriptor;
54 \textcolor{keyword}{static} \hyperlink{group__Eet__Data__Group_ga4baec0e840012480a0958c5c3bca276d}{Eet\_Data\_Descriptor} *\_my\_account\_descriptor;
55 \textcolor{keyword}{static} \hyperlink{group__Eet__Data__Group_ga4baec0e840012480a0958c5c3bca276d}{Eet\_Data\_Descriptor} *\_my\_message\_descriptor;
56 \textcolor{keyword}{static} \hyperlink{group__Eet__Data__Group_ga4baec0e840012480a0958c5c3bca276d}{Eet\_Data\_Descriptor} *\_my\_post\_descriptor;
57 
58 \textcolor{comment}{// keep file handle alive, so mmap()ed strings are all alive as well}
59 \textcolor{keyword}{static} \hyperlink{group__Eet__File__Group_ga8d9779184a9870c1a225f1f40c76e8a7}{Eet\_File} *\_my\_cache\_file = NULL;
60 \textcolor{keyword}{static} \hyperlink{group__Eet__File__Group_gaf0984c8280699ca5a3c4966f5580324c}{Eet\_Dictionary} *\_my\_cache\_dict = NULL;
61 
62 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
63 \_my\_cache\_descriptor\_init(\textcolor{keywordtype}{void})
64 \{
65    \hyperlink{struct__Eet__Data__Descriptor__Class}{Eet\_Data\_Descriptor\_Class} eddc;
66 
67    \textcolor{comment}{// The FILE variant is good for caches and things that are just}
68    \textcolor{comment}{// appended, but needs to take care when changing strings and files must}
69    \textcolor{comment}{// be kept open so mmap()ed strings will be kept alive.}
70    \hyperlink{group__Eet__Data__Group_ga0bf94c07d8e69cfaac8dd2d615d7542c}{EET\_EINA\_FILE\_DATA\_DESCRIPTOR\_CLASS\_SET}(&eddc, My\_Cache);
71    \_my\_cache\_descriptor = \hyperlink{group__Eet__Data__Group_ga2a7251edf1f60ced86c4860207331bb6}{eet\_data\_descriptor\_file\_new}(&eddc);
72 
73    \hyperlink{group__Eet__Data__Group_ga0bf94c07d8e69cfaac8dd2d615d7542c}{EET\_EINA\_FILE\_DATA\_DESCRIPTOR\_CLASS\_SET}(&eddc, My\_Account);
74    \_my\_account\_descriptor = \hyperlink{group__Eet__Data__Group_ga2a7251edf1f60ced86c4860207331bb6}{eet\_data\_descriptor\_file\_new}(&eddc);
75 
76    \hyperlink{group__Eet__Data__Group_ga0bf94c07d8e69cfaac8dd2d615d7542c}{EET\_EINA\_FILE\_DATA\_DESCRIPTOR\_CLASS\_SET}(&eddc, My\_Message);
77    \_my\_message\_descriptor = \hyperlink{group__Eet__Data__Group_ga2a7251edf1f60ced86c4860207331bb6}{eet\_data\_descriptor\_file\_new}(&eddc);
78 
79    \hyperlink{group__Eet__Data__Group_ga0bf94c07d8e69cfaac8dd2d615d7542c}{EET\_EINA\_FILE\_DATA\_DESCRIPTOR\_CLASS\_SET}(&eddc, My\_Post);
80    \_my\_post\_descriptor = \hyperlink{group__Eet__Data__Group_ga2a7251edf1f60ced86c4860207331bb6}{eet\_data\_descriptor\_file\_new}(&eddc);
81 
82    \textcolor{comment}{// Describe the members to be saved:}
83    \textcolor{comment}{// Use a temporary macro so we don't type a lot, also avoid errors:}
84 
85 \textcolor{preprocessor}{#define ADD\_BASIC(member, eet\_type) \(\backslash\)}
86 \textcolor{preprocessor}{  EET\_DATA\_DESCRIPTOR\_ADD\_BASIC     \(\backslash\)}
87 \textcolor{preprocessor}{    (\_my\_message\_descriptor, My\_Message, # member, member, eet\_type)}
88    ADD\_BASIC(screen\_name, \hyperlink{group__Eet__Data__Group_ga0d2cf409bf3f151156d74d18ac59e3d1}{EET\_T\_STRING});
89    ADD\_BASIC(name, \hyperlink{group__Eet__Data__Group_ga0d2cf409bf3f151156d74d18ac59e3d1}{EET\_T\_STRING});
90    ADD\_BASIC(message, \hyperlink{group__Eet__Data__Group_ga0d2cf409bf3f151156d74d18ac59e3d1}{EET\_T\_STRING});
91    ADD\_BASIC(\textcolor{keywordtype}{id}, \hyperlink{group__Eet__Data__Group_gacf6a3c9f06e10e20be5b02cd8c6a220b}{EET\_T\_UINT});
92    ADD\_BASIC(status\_id, \hyperlink{group__Eet__Data__Group_gacf6a3c9f06e10e20be5b02cd8c6a220b}{EET\_T\_UINT});
93    ADD\_BASIC(date, \hyperlink{group__Eet__Data__Group_gacf6a3c9f06e10e20be5b02cd8c6a220b}{EET\_T\_UINT});
94    ADD\_BASIC(timeline, \hyperlink{group__Eet__Data__Group_gacf6a3c9f06e10e20be5b02cd8c6a220b}{EET\_T\_UINT});
95 \textcolor{preprocessor}{#undef ADD\_BASIC}
96 
97 \textcolor{preprocessor}{#define ADD\_BASIC(member, eet\_type) \(\backslash\)}
98 \textcolor{preprocessor}{  EET\_DATA\_DESCRIPTOR\_ADD\_BASIC     \(\backslash\)}
99 \textcolor{preprocessor}{    (\_my\_post\_descriptor, My\_Post, # member, member, eet\_type)}
100    ADD\_BASIC(dm\_to, \hyperlink{group__Eet__Data__Group_ga0d2cf409bf3f151156d74d18ac59e3d1}{EET\_T\_STRING});
101    ADD\_BASIC(message, \hyperlink{group__Eet__Data__Group_ga0d2cf409bf3f151156d74d18ac59e3d1}{EET\_T\_STRING});
102 \textcolor{preprocessor}{#undef ADD\_BASIC}
103 
104 \textcolor{preprocessor}{#define ADD\_BASIC(member, eet\_type) \(\backslash\)}
105 \textcolor{preprocessor}{  EET\_DATA\_DESCRIPTOR\_ADD\_BASIC     \(\backslash\)}
106 \textcolor{preprocessor}{    (\_my\_account\_descriptor, My\_Account, # member, member, eet\_type)}
107    ADD\_BASIC(name, \hyperlink{group__Eet__Data__Group_ga0d2cf409bf3f151156d74d18ac59e3d1}{EET\_T\_STRING});
108    ADD\_BASIC(\textcolor{keywordtype}{id}, \hyperlink{group__Eet__Data__Group_gacf6a3c9f06e10e20be5b02cd8c6a220b}{EET\_T\_UINT});
109 \textcolor{preprocessor}{#undef ADD\_BASIC}
110 
111    \hyperlink{group__Eet__Data__Group_gabb4c7833ba053f2322e6b667a9ec7f04}{EET\_DATA\_DESCRIPTOR\_ADD\_LIST}
112      (\_my\_account\_descriptor, My\_Account, \textcolor{stringliteral}{"messages"}, messages,
113      \_my\_message\_descriptor);
114    \hyperlink{group__Eet__Data__Group_ga7adad32d2eba76566533353632f00ae4}{EET\_DATA\_DESCRIPTOR\_ADD\_VAR\_ARRAY}
115      (\_my\_account\_descriptor, My\_Account, \textcolor{stringliteral}{"posts"}, posts,
116      \_my\_post\_descriptor);
117 
118 \textcolor{preprocessor}{#define ADD\_BASIC(member, eet\_type) \(\backslash\)}
119 \textcolor{preprocessor}{  EET\_DATA\_DESCRIPTOR\_ADD\_BASIC     \(\backslash\)}
120 \textcolor{preprocessor}{    (\_my\_cache\_descriptor, My\_Cache, # member, member, eet\_type)}
121    ADD\_BASIC(version, \hyperlink{group__Eet__Data__Group_gacf6a3c9f06e10e20be5b02cd8c6a220b}{EET\_T\_UINT});
122 \textcolor{preprocessor}{#undef ADD\_BASIC}
123 
124    \hyperlink{group__Eet__Data__Group_gad5e348ead4ba0b441c1e020f9bf23365}{EET\_DATA\_DESCRIPTOR\_ADD\_HASH}
125      (\_my\_cache\_descriptor, My\_Cache, \textcolor{stringliteral}{"accounts"}, accounts,
126      \_my\_account\_descriptor);
127 \} \textcolor{comment}{/* \_my\_cache\_descriptor\_init */}
128 
129 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
130 \_my\_cache\_descriptor\_shutdown(\textcolor{keywordtype}{void})
131 \{
132    \hyperlink{group__Eet__Data__Group_ga3e2b601720973d0e1f4683768a593c4d}{eet\_data\_descriptor\_free}(\_my\_cache\_descriptor);
133    \hyperlink{group__Eet__Data__Group_ga3e2b601720973d0e1f4683768a593c4d}{eet\_data\_descriptor\_free}(\_my\_account\_descriptor);
134    \hyperlink{group__Eet__Data__Group_ga3e2b601720973d0e1f4683768a593c4d}{eet\_data\_descriptor\_free}(\_my\_message\_descriptor);
135    \hyperlink{group__Eet__Data__Group_ga3e2b601720973d0e1f4683768a593c4d}{eet\_data\_descriptor\_free}(\_my\_post\_descriptor);
136 \} \textcolor{comment}{/* \_my\_cache\_descriptor\_shutdown */}
137 
138 \textcolor{comment}{// need to check if the pointer came from mmaped area in eet\_dictionary}
139 \textcolor{comment}{// or it was allocated with eina\_stringshare\_add()}
140 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
141 \_eet\_string\_free(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str)
142 \{
143    \textcolor{keywordflow}{if} (!str)
144      \textcolor{keywordflow}{return};
145 
146    \textcolor{keywordflow}{if} ((\_my\_cache\_dict) && (\hyperlink{group__Eet__File__Group_ga53290da52edb929b85e51f25e79d27c8}{eet\_dictionary\_string\_check}(\_my\_cache\_dict, str)))
147      \textcolor{keywordflow}{return};
148 
149    \hyperlink{group__Eina__Stringshare__Group_ga4453d2aff2b325c7b45048f30df9b1f5}{eina\_stringshare\_del}(str);
150 \} \textcolor{comment}{/* \_eet\_string\_free */}
151 
152 \textcolor{keyword}{static} My\_Message *
153 \_my\_message\_new(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *message)
154 \{
155    My\_Message *msg = calloc(1, \textcolor{keyword}{sizeof}(My\_Message));
156    \textcolor{keywordflow}{if} (!msg)
157      \{
158         fprintf(stderr, \textcolor{stringliteral}{"ERROR: could not calloc My\_Message\(\backslash\)n"});
159         \textcolor{keywordflow}{return} NULL;
160      \}
161 
162    msg->message = \hyperlink{group__Eina__Stringshare__Group_gac7a3f073cafb7af63b2c7cc2eabd1c1f}{eina\_stringshare\_add}(message);
163    \textcolor{keywordflow}{return} msg;
164 \} \textcolor{comment}{/* \_my\_message\_new */}
165 
166 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
167 \_my\_message\_free(My\_Message *msg)
168 \{
169    \_eet\_string\_free(msg->screen\_name);
170    \_eet\_string\_free(msg->name);
171    \_eet\_string\_free(msg->message);
172    free(msg);
173 \} \textcolor{comment}{/* \_my\_message\_free */}
174 
175 \textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
176 \_my\_post\_add(My\_Account *acc,
177              \textcolor{keyword}{const} \textcolor{keywordtype}{char} *message)
178 \{
179    \textcolor{keywordtype}{int} new\_count = acc->posts\_count + 1;
180    My\_Post *post = realloc(acc->posts, new\_count * \textcolor{keyword}{sizeof}(My\_Post));
181    \textcolor{keywordflow}{if} (!post)
182      \{
183         fprintf(stderr, \textcolor{stringliteral}{"ERROR: could add My\_Post\(\backslash\)n"});
184         \textcolor{keywordflow}{return} \hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{EINA\_FALSE};
185      \}
186 
187    post[acc->posts\_count].message = \hyperlink{group__Eina__Stringshare__Group_gac7a3f073cafb7af63b2c7cc2eabd1c1f}{eina\_stringshare\_add}(message);
188    post[acc->posts\_count].dm\_to = NULL;
189    acc->posts\_count = new\_count;
190    acc->posts = post;
191    \textcolor{keywordflow}{return} \hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE};
192 \} \textcolor{comment}{/* \_my\_post\_new */}
193 
194 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
195 \_my\_post\_free(My\_Post *post)
196 \{
197    \_eet\_string\_free(post->dm\_to);
198    \_eet\_string\_free(post->message);
199 \} \textcolor{comment}{/* \_my\_post\_free */}
200 
201 \textcolor{keyword}{static} My\_Account *
202 \_my\_account\_new(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *name)
203 \{
204    My\_Account *acc = calloc(1, \textcolor{keyword}{sizeof}(My\_Account));
205    \textcolor{keywordflow}{if} (!acc)
206      \{
207         fprintf(stderr, \textcolor{stringliteral}{"ERROR: could not calloc My\_Account\(\backslash\)n"});
208         \textcolor{keywordflow}{return} NULL;
209      \}
210 
211    acc->name = \hyperlink{group__Eina__Stringshare__Group_gac7a3f073cafb7af63b2c7cc2eabd1c1f}{eina\_stringshare\_add}(name);
212    \textcolor{keywordflow}{return} acc;
213 \} \textcolor{comment}{/* \_my\_account\_new */}
214 
215 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
216 \_my\_account\_free(My\_Account *acc)
217 \{
218    My\_Message *m;
219    \textcolor{keywordtype}{int} i;
220 
221    \_eet\_string\_free(acc->name);
222 
223    \hyperlink{group__Eina__List__Group_gae27a2c686a0a11693f9b06957c9bba83}{EINA\_LIST\_FREE}(acc->messages, m)
224      \_my\_message\_free(m);
225 
226    for (i = 0; i < acc->posts\_count; i++)
227      \_my\_post\_free(&acc->posts[i]);
228    free(acc->posts);
229 
230    free(acc);
231 \} \textcolor{comment}{/* \_my\_account\_free */}
232 
233 static My\_Cache *
234 \_my\_cache\_new(\textcolor{keywordtype}{void})
235 \{
236    My\_Cache *my\_cache = calloc(1, \textcolor{keyword}{sizeof}(My\_Cache));
237    \textcolor{keywordflow}{if} (!my\_cache)
238      \{
239         fprintf(stderr, \textcolor{stringliteral}{"ERROR: could not calloc My\_Cache\(\backslash\)n"});
240         \textcolor{keywordflow}{return} NULL;
241      \}
242 
243    my\_cache->accounts = \hyperlink{group__Eina__Hash__Group_gaad2e43204f79ee5a8f19470ff5ba4ac8}{eina\_hash\_string\_small\_new}(NULL);
244 
245    my\_cache->version = 1;
246    \textcolor{keywordflow}{return} my\_cache;
247 \} \textcolor{comment}{/* \_my\_cache\_new */}
248 
249 \textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
250 \_my\_cache\_account\_free\_cb(\textcolor{keyword}{const} \hyperlink{group__Eina__Hash__Group_ga9a89d7d3ee260d3a60572ebf651b07e0}{Eina\_Hash} *hash EINA\_UNUSED,
251                           \textcolor{keyword}{const} \textcolor{keywordtype}{void}      *key EINA\_UNUSED,
252                           \textcolor{keywordtype}{void}            *data,
253                           \textcolor{keywordtype}{void}            *fdata EINA\_UNUSED)
254 \{
255    \_my\_account\_free(data);
256    \textcolor{keywordflow}{return} \hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE};
257 \}
258 
259 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
260 \_my\_cache\_free(My\_Cache *my\_cache)
261 \{
262    \hyperlink{group__Eina__Hash__Group_ga2c23f8425d3afcc61827ab67b46d7190}{eina\_hash\_foreach}(my\_cache->accounts, \_my\_cache\_account\_free\_cb, NULL);
263    \hyperlink{group__Eina__Hash__Group_gadb6acb720ce267cc1cd4f51893539f59}{eina\_hash\_free}(my\_cache->accounts);
264    free(my\_cache);
265 \} \textcolor{comment}{/* \_my\_cache\_free */}
266 
267 \textcolor{keyword}{static} My\_Account *
268 \_my\_cache\_account\_find(My\_Cache   *my\_cache,
269                        \textcolor{keyword}{const} \textcolor{keywordtype}{char} *name)
270 \{
271    \textcolor{keywordflow}{return} \hyperlink{group__Eina__Hash__Group_ga45703d00fbabffc86e6836ffe98a4c92}{eina\_hash\_find}(my\_cache->accounts, name);
272 \} \textcolor{comment}{/* \_my\_cache\_account\_find */}
273 
274 \textcolor{keyword}{static} My\_Cache *
275 \_my\_cache\_load(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *filename)
276 \{
277    My\_Cache *my\_cache;
278    \hyperlink{group__Eet__File__Group_ga8d9779184a9870c1a225f1f40c76e8a7}{Eet\_File} *ef = \hyperlink{group__Eet__File__Group_ga5f55956b860aa2c77af9b1a880c4c256}{eet\_open}(filename, \hyperlink{group__Eet__File__Group_ggaa8e1a7af50fefaf15eb2f69543d24998a416f7e9a76b8131a44bbeedb13060c81}{EET\_FILE\_MODE\_READ});
279    \textcolor{keywordflow}{if} (!ef)
280      \{
281         fprintf(stderr, \textcolor{stringliteral}{"ERROR: could not open '%s' for read\(\backslash\)n"}, filename);
282         \textcolor{keywordflow}{return} NULL;
283      \}
284 
285    my\_cache = \hyperlink{group__Eet__Data__Group_ga4d1807cbbc448304f22a8808318a3429}{eet\_data\_read}(ef, \_my\_cache\_descriptor, MY\_CACHE\_FILE\_ENTRY);
286    \textcolor{keywordflow}{if} (!my\_cache)
287      \{
288         \hyperlink{group__Eet__File__Group_ga1675fef1f6012c1e02ae313d13dc3e03}{eet\_close}(ef);
289         \textcolor{keywordflow}{return} NULL;
290      \}
291 
292    \textcolor{keywordflow}{if} (my\_cache->version < 1)
293      \{
294         fprintf(stderr,
295                 \textcolor{stringliteral}{"WARNING: version %#x was too old, upgrading it to %#x\(\backslash\)n"},
296                 my\_cache->version, 1);
297 
298         my\_cache->version = 1;
299      \}
300 
301    \textcolor{keywordflow}{if} (\_my\_cache\_file)
302      \hyperlink{group__Eet__File__Group_ga1675fef1f6012c1e02ae313d13dc3e03}{eet\_close}(\_my\_cache\_file);
303 
304    \_my\_cache\_file = ef;
305    \_my\_cache\_dict = \hyperlink{group__Eet__File__Group_gab45ad39596d2fb54a88fda93e7fa0b0f}{eet\_dictionary\_get}(ef);
306 
307    \textcolor{keywordflow}{return} my\_cache;
308 \} \textcolor{comment}{/* \_my\_cache\_load */}
309 
310 \textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
311 \_my\_cache\_save(\textcolor{keyword}{const} My\_Cache *my\_cache,
312                \textcolor{keyword}{const} \textcolor{keywordtype}{char}     *filename)
313 \{
314    \textcolor{keywordtype}{char} tmp[PATH\_MAX];
315    \hyperlink{group__Eet__File__Group_ga8d9779184a9870c1a225f1f40c76e8a7}{Eet\_File} *ef;
316    \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool} ret;
317    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} i, len;
318    \textcolor{keyword}{struct }stat st;
319 
320    len = \hyperlink{group__Eina__String__Group_ga6bda31d2e1b6d2737b7fe1784780cd2f}{eina\_strlcpy}(tmp, filename, \textcolor{keyword}{sizeof}(tmp));
321    \textcolor{keywordflow}{if} (len + 12 >= (\textcolor{keywordtype}{int})\textcolor{keyword}{sizeof}(tmp))
322      \{
323         fprintf(stderr, \textcolor{stringliteral}{"ERROR: file name is too big: %s\(\backslash\)n"}, filename);
324         \textcolor{keywordflow}{return} \hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{EINA\_FALSE};
325      \}
326 
327    i = 0;
328    \textcolor{keywordflow}{do}
329      \{
330         snprintf(tmp + len, 12, \textcolor{stringliteral}{".%u"}, i);
331         i++;
332      \}
333    \textcolor{keywordflow}{while} (stat(tmp, &st) == 0);
334 
335    ef = \hyperlink{group__Eet__File__Group_ga5f55956b860aa2c77af9b1a880c4c256}{eet\_open}(tmp, \hyperlink{group__Eet__File__Group_ggaa8e1a7af50fefaf15eb2f69543d24998a8f395f56fba48be007c65be51d799ee9}{EET\_FILE\_MODE\_WRITE});
336    \textcolor{keywordflow}{if} (!ef)
337      \{
338         fprintf(stderr, \textcolor{stringliteral}{"ERROR: could not open '%s' for write\(\backslash\)n"}, tmp);
339         \textcolor{keywordflow}{return} \hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{EINA\_FALSE};
340      \}
341 
342    ret = \hyperlink{group__Eet__Data__Group_gac66d1c49e3490bc5d803982d833ff8aa}{eet\_data\_write}
343        (ef, \_my\_cache\_descriptor, MY\_CACHE\_FILE\_ENTRY, my\_cache, \hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE});
344 
345    \textcolor{comment}{// VERY IMPORTANT NOTE:}
346    \textcolor{comment}{// after eet\_close(), all strings mmaped from file will be GONE, invalid!}
347    \textcolor{comment}{// you'll need to free the old cache and open the new one.}
348    \textcolor{comment}{// For cache this is okay, as you should be saving not so often or just}
349    \textcolor{comment}{// at end.}
350    \textcolor{comment}{//}
351    \textcolor{comment}{// This is a trade off, you save memory by using mmap()ed strings, but}
352    \textcolor{comment}{// you have to care about this.}
353    \hyperlink{group__Eet__File__Group_ga1675fef1f6012c1e02ae313d13dc3e03}{eet\_close}(ef);
354 
355    \textcolor{keywordflow}{if} (ret)
356      \{
357         unlink(filename);
358         rename(tmp, filename);
359      \}
360 
361    \textcolor{keywordflow}{return} ret;
362 \} \textcolor{comment}{/* \_my\_cache\_save */}
363 
364 \textcolor{keywordtype}{int}
365 main(\textcolor{keywordtype}{int}   argc,
366      \textcolor{keywordtype}{char} *argv[])
367 \{
368    My\_Cache *my\_cache;
369    \hyperlink{struct__Eina__Iterator}{Eina\_Iterator} *it;
370    My\_Account *acc;
371    \textcolor{keywordtype}{int} ret = 0;
372 
373    \textcolor{keywordflow}{if} (argc < 3)
374      \{
375         fprintf(stderr,
376                 \textcolor{stringliteral}{"Usage:\(\backslash\)n\(\backslash\)t%s <input> <output> [action] [action-params]\(\backslash\)n\(\backslash\)n"}
377                 \textcolor{stringliteral}{"Where actions and their parameters:\(\backslash\)n"}
378                 \textcolor{stringliteral}{"\(\backslash\)tacc <name>\(\backslash\)n"}
379                 \textcolor{stringliteral}{"\(\backslash\)tpost <account-name> <message>\(\backslash\)n"}
380                 \textcolor{stringliteral}{"\(\backslash\)tmessage <account-name> <message>\(\backslash\)n"}
381                 \textcolor{stringliteral}{"\(\backslash\)n"},
382                 argv[0]);
383         \textcolor{keywordflow}{return} -1;
384      \}
385 
386    \hyperlink{group__Eina__Main__Group_gabf448ada5bc81a07342b66c6f818ee5e}{eina\_init}();
387    \hyperlink{group__Eet__Group_ga9903687bfa20fe9a9e59d4c1d213e89a}{eet\_init}();
388    \_my\_cache\_descriptor\_init();
389 
390    my\_cache = \_my\_cache\_load(argv[1]);
391    \textcolor{keywordflow}{if} (!my\_cache)
392      \{
393         printf(\textcolor{stringliteral}{"creating new cache.\(\backslash\)n"});
394         my\_cache = \_my\_cache\_new();
395         \textcolor{keywordflow}{if} (!my\_cache)
396           \{
397              ret = -2;
398              \textcolor{keywordflow}{goto} end;
399           \}
400      \}
401 
402    \textcolor{keywordflow}{if} (argc > 3)
403      \{
404         \textcolor{keywordflow}{if} (strcmp(argv[3], \textcolor{stringliteral}{"acc"}) == 0)
405           \{
406              \textcolor{keywordflow}{if} (argc == 5)
407                \{
408                   My\_Account *acc\_ = \_my\_cache\_account\_find(my\_cache, argv[4]);
409                   \textcolor{keywordflow}{if} (!acc\_)
410                     \{
411                        acc\_ = \_my\_account\_new(argv[4]);
412                        \hyperlink{group__Eina__Hash__Group_ga50aa7d4303e5efbe8dc7f593b59b9f63}{eina\_hash\_direct\_add}(my\_cache->accounts, acc\_->name, acc);
413                     \}
414                   \textcolor{keywordflow}{else}
415                     fprintf(stderr, \textcolor{stringliteral}{"ERROR: account '%s' already exists.\(\backslash\)n"},
416                             argv[4]);
417                \}
418              \textcolor{keywordflow}{else}
419                fprintf(stderr,
420                        \textcolor{stringliteral}{"ERROR: wrong number of parameters (%d).\(\backslash\)n"},
421                        argc);
422           \}
423         \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (strcmp(argv[3], \textcolor{stringliteral}{"post"}) == 0)
424           \{
425              \textcolor{keywordflow}{if} (argc == 6)
426                \{
427                   My\_Account *acc\_ = \_my\_cache\_account\_find(my\_cache, argv[4]);
428                   \textcolor{keywordflow}{if} (acc\_)
429                     \{
430                        \_my\_post\_add(acc\_, argv[5]);
431                     \}
432                   \textcolor{keywordflow}{else}
433                     fprintf(stderr, \textcolor{stringliteral}{"ERROR: unknown account: '%s'\(\backslash\)n"}, argv[4]);
434                \}
435              \textcolor{keywordflow}{else}
436                fprintf(stderr,
437                        \textcolor{stringliteral}{"ERROR: wrong number of parameters (%d).\(\backslash\)n"},
438                        argc);
439           \}
440         \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (strcmp(argv[3], \textcolor{stringliteral}{"message"}) == 0)
441           \{
442              \textcolor{keywordflow}{if} (argc == 6)
443                \{
444                   My\_Account *acc\_ = \_my\_cache\_account\_find(my\_cache, argv[4]);
445                   \textcolor{keywordflow}{if} (acc\_)
446                     \{
447                        My\_Message *msg = \_my\_message\_new(argv[5]);
448                        acc\_->messages = \hyperlink{group__Eina__List__Group_ga92ec14d1a1040a361c4d8cd0ab7b0ecc}{eina\_list\_append}(acc\_->messages, msg);
449                     \}
450                   \textcolor{keywordflow}{else}
451                     fprintf(stderr, \textcolor{stringliteral}{"ERROR: unknown account: '%s'\(\backslash\)n"}, argv[4]);
452                \}
453              \textcolor{keywordflow}{else}
454                fprintf(stderr,
455                        \textcolor{stringliteral}{"ERROR: wrong number of parameters (%d).\(\backslash\)n"},
456                        argc);
457           \}
458         \textcolor{keywordflow}{else}
459           fprintf(stderr, \textcolor{stringliteral}{"ERROR: unknown action '%s'\(\backslash\)n"}, argv[2]);
460      \}
461 
462    printf(\textcolor{stringliteral}{"My\_Cache:\(\backslash\)n"}
463           \textcolor{stringliteral}{"\(\backslash\)tversion.: %#x\(\backslash\)n"}
464           \textcolor{stringliteral}{"\(\backslash\)taccounts: %u\(\backslash\)n"},
465           my\_cache->version,
466           \hyperlink{group__Eina__Hash__Group_ga9289542f6724083eab306e5bb3ab10b0}{eina\_hash\_population}(my\_cache->accounts));
467    it = \hyperlink{group__Eina__Hash__Group_ga5191350d6044d93b6518a957f12f5ac3}{eina\_hash\_iterator\_data\_new}(my\_cache->accounts);
468    \hyperlink{group__Eina__Iterator__Group_gad2f796ac4df0e500d25235c29821faa3}{EINA\_ITERATOR\_FOREACH}(it, acc)
469      \{
470         printf(\textcolor{stringliteral}{"\(\backslash\)t  > %-#8x '%.20s' stats: m=%u, p=%u\(\backslash\)n"},
471                acc->id, acc->name ? acc->name : \textcolor{stringliteral}{""},
472                \hyperlink{group__Eina__List__Group_ga301729054a498a2df09a5f1dd760697e}{eina\_list\_count}(acc->messages),
473                acc->posts\_count);
474 
475         \textcolor{keywordflow}{if} (\hyperlink{group__Eina__List__Group_ga301729054a498a2df09a5f1dd760697e}{eina\_list\_count}(acc->messages))
476           \{
477              \textcolor{keyword}{const} \hyperlink{struct__Eina__List}{Eina\_List} *l;
478              \textcolor{keyword}{const} My\_Message *msg;
479              printf(\textcolor{stringliteral}{"\(\backslash\)t  |messages:\(\backslash\)n"});
480 
481              \hyperlink{group__Eina__List__Group_gad02f746a08ee0b12b7ed66d4bc0d71d8}{EINA\_LIST\_FOREACH}(acc->messages, l, msg)
482                \{
483                   printf(\textcolor{stringliteral}{"\(\backslash\)t  |   %-8x '%s' [%s]: '%.20s'\(\backslash\)n"},
484                          msg->id,
485                          msg->name ? msg->name : \textcolor{stringliteral}{""},
486                          msg->screen\_name ? msg->screen\_name : \textcolor{stringliteral}{""},
487                          msg->message ? msg->message : \textcolor{stringliteral}{""});
488                \}
489           \}
490 
491         \textcolor{keywordflow}{if} (acc->posts\_count)
492           \{
493              \textcolor{keyword}{const} My\_Post *post;
494              \textcolor{keywordtype}{int} i;
495              printf(\textcolor{stringliteral}{"\(\backslash\)t  |posts:\(\backslash\)n"});
496 
497              \textcolor{keywordflow}{for} (i = 0; i < acc->posts\_count; i++)
498                \{
499                   post = &acc->posts[i];
500                   \textcolor{keywordflow}{if} (post->dm\_to)
501                     printf(\textcolor{stringliteral}{"\(\backslash\)t  |  @%s: '%.20s'\(\backslash\)n"}, post->dm\_to, post->message);
502                   \textcolor{keywordflow}{else}
503                     printf(\textcolor{stringliteral}{"\(\backslash\)t  |  '%.20s'\(\backslash\)n"}, post->message);
504                \}
505           \}
506 
507         printf(\textcolor{stringliteral}{"\(\backslash\)n"});
508      \}
509    \hyperlink{group__Eina__Iterator__Group_gaf9261991a4b05dc63e3401278a3281f8}{eina\_iterator\_free}(it);
510 
511    \textcolor{keywordflow}{if} (!\_my\_cache\_save(my\_cache, argv[2]))
512      ret = -3;
513 
514    \_my\_cache\_free(my\_cache);
515 
516 end:
517    \textcolor{keywordflow}{if} (\_my\_cache\_file)
518      \hyperlink{group__Eet__File__Group_ga1675fef1f6012c1e02ae313d13dc3e03}{eet\_close}(\_my\_cache\_file);
519    \_my\_cache\_descriptor\_shutdown();
520    \hyperlink{group__Eet__Group_gacbc7583179399d3b3e7b003e911f866f}{eet\_shutdown}();
521    \hyperlink{group__Eina__Main__Group_ga6741fcaba116e31e96ce14dcfa03f568}{eina\_shutdown}();
522 
523    \textcolor{keywordflow}{return} ret;
524 \} \textcolor{comment}{/* main */}
525 
\end{DoxyCodeInclude}
 