
\begin{DoxyCodeInclude}
1 \textcolor{comment}{//Compile with:}
2 \textcolor{comment}{// gcc -o eet-data-nested eet-data-nested.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}{// The struct that will be loaded and saved.}
13 \textcolor{comment}{// note that only the members described in the eet\_data\_descriptor}
14 \textcolor{comment}{// will be automatically handled. The other members will have their}
15 \textcolor{comment}{// space reserved and zeroed (as it uses calloc()), but not}
16 \textcolor{comment}{// saved or loaded from eet files.}
17 \textcolor{keyword}{typedef} \textcolor{keyword}{struct}
18 \{
19    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} version; \textcolor{comment}{// it is recommended to use versioned configuration!}
20    \textcolor{keyword}{const} \textcolor{keywordtype}{char}  *name;
21    \textcolor{keywordtype}{int}          id;
22    \textcolor{keywordtype}{int}          not\_saved\_value; \textcolor{comment}{// example of not saved data inside!}
23    \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}    enabled;
24    \hyperlink{struct__Eina__List}{Eina\_List}   *subs;
25 \} My\_Conf\_Type;
26 
27 \textcolor{keyword}{typedef} \textcolor{keyword}{struct}
28 \{
29    \textcolor{keyword}{const} \textcolor{keywordtype}{char} *server;
30    \textcolor{keywordtype}{int}         port;
31 \} My\_Conf\_Subtype;
32 
33 \textcolor{comment}{// string that represents the entry in eet file, you might like to have}
34 \textcolor{comment}{// different profiles or so in the same file, this is possible with}
35 \textcolor{comment}{// different strings}
36 \textcolor{keyword}{static} \textcolor{keyword}{const} \textcolor{keywordtype}{char} MY\_CONF\_FILE\_ENTRY[] = \textcolor{stringliteral}{"config"};
37 
38 \textcolor{comment}{// keep the descriptor static global, so it can be}
39 \textcolor{comment}{// shared by different functions (load/save) of this and only this}
40 \textcolor{comment}{// file.}
41 \textcolor{keyword}{static} \hyperlink{group__Eet__Data__Group_ga4baec0e840012480a0958c5c3bca276d}{Eet\_Data\_Descriptor} *\_my\_conf\_descriptor;
42 \textcolor{keyword}{static} \hyperlink{group__Eet__Data__Group_ga4baec0e840012480a0958c5c3bca276d}{Eet\_Data\_Descriptor} *\_my\_conf\_sub\_descriptor;
43 
44 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
45 \_my\_conf\_descriptor\_init(\textcolor{keywordtype}{void})
46 \{
47    \hyperlink{struct__Eet__Data__Descriptor__Class}{Eet\_Data\_Descriptor\_Class} eddc;
48 
49    \textcolor{comment}{// The class describe the functions to use to create the type and its}
50    \textcolor{comment}{// full allocated size.}
51    \textcolor{comment}{//}
52    \textcolor{comment}{// Eina types are very convenient, so use them to create the descriptor,}
53    \textcolor{comment}{// so we get eina\_list,  eina\_hash and eina\_stringshare automatically!}
54    \textcolor{comment}{//}
55    \textcolor{comment}{// The STREAM variant is better for configuration files as the values}
56    \textcolor{comment}{// will likely change a lot.}
57    \textcolor{comment}{//}
58    \textcolor{comment}{// The other variant, FILE, is good for caches and things that are just}
59    \textcolor{comment}{// appended, but needs to take care when changing strings and files must}
60    \textcolor{comment}{// be kept open so mmap()ed strings will be kept alive.}
61    \hyperlink{group__Eet__Data__Group_ga941b1fcd6c6c72221d9390f9a0ed751c}{EET\_EINA\_STREAM\_DATA\_DESCRIPTOR\_CLASS\_SET}(&eddc, My\_Conf\_Type);
62    \_my\_conf\_descriptor = \hyperlink{group__Eet__Data__Group_gae300b4a97dbaab30a200edbb97f108c1}{eet\_data\_descriptor\_stream\_new}(&eddc);
63 
64    \hyperlink{group__Eet__Data__Group_ga941b1fcd6c6c72221d9390f9a0ed751c}{EET\_EINA\_STREAM\_DATA\_DESCRIPTOR\_CLASS\_SET}(&eddc, 
      My\_Conf\_Subtype);
65    \_my\_conf\_sub\_descriptor = \hyperlink{group__Eet__Data__Group_gae300b4a97dbaab30a200edbb97f108c1}{eet\_data\_descriptor\_stream\_new}(&eddc);
66 
67    \textcolor{comment}{// Describe the members to be saved:}
68    \textcolor{comment}{// Use a temporary macro so we don't type a lot, also avoid errors:}
69 \textcolor{preprocessor}{#define MY\_CONF\_ADD\_BASIC(member, eet\_type) \(\backslash\)}
70 \textcolor{preprocessor}{  EET\_DATA\_DESCRIPTOR\_ADD\_BASIC             \(\backslash\)}
71 \textcolor{preprocessor}{    (\_my\_conf\_descriptor, My\_Conf\_Type, # member, member, eet\_type)}
72 \textcolor{preprocessor}{#define MY\_CONF\_SUB\_ADD\_BASIC(member, eet\_type) \(\backslash\)}
73 \textcolor{preprocessor}{  EET\_DATA\_DESCRIPTOR\_ADD\_BASIC                 \(\backslash\)}
74 \textcolor{preprocessor}{    (\_my\_conf\_sub\_descriptor, My\_Conf\_Subtype, # member, member, eet\_type)}
75 
76    MY\_CONF\_SUB\_ADD\_BASIC(server, \hyperlink{group__Eet__Data__Group_ga0d2cf409bf3f151156d74d18ac59e3d1}{EET\_T\_STRING});
77    MY\_CONF\_SUB\_ADD\_BASIC(port, \hyperlink{group__Eet__Data__Group_ga4e196733795867f14c6e387af7287baa}{EET\_T\_INT});
78 
79    MY\_CONF\_ADD\_BASIC(version, \hyperlink{group__Eet__Data__Group_gacf6a3c9f06e10e20be5b02cd8c6a220b}{EET\_T\_UINT});
80    MY\_CONF\_ADD\_BASIC(name, \hyperlink{group__Eet__Data__Group_ga0d2cf409bf3f151156d74d18ac59e3d1}{EET\_T\_STRING});
81    MY\_CONF\_ADD\_BASIC(\textcolor{keywordtype}{id}, \hyperlink{group__Eet__Data__Group_ga4e196733795867f14c6e387af7287baa}{EET\_T\_INT});
82    MY\_CONF\_ADD\_BASIC(enabled, \hyperlink{group__Eet__Data__Group_ga09a1341cc158fda0ba60ad2386ecd795}{EET\_T\_UCHAR});
83 
84    \textcolor{comment}{// And add the sub descriptor as a linked list at 'subs' in the main struct}
85    \hyperlink{group__Eet__Data__Group_gabb4c7833ba053f2322e6b667a9ec7f04}{EET\_DATA\_DESCRIPTOR\_ADD\_LIST}
86      (\_my\_conf\_descriptor, My\_Conf\_Type, \textcolor{stringliteral}{"subs"}, subs, \_my\_conf\_sub\_descriptor);
87 
88 \textcolor{preprocessor}{#undef MY\_CONF\_ADD\_BASIC}
89 \textcolor{preprocessor}{#undef MY\_CONF\_SUB\_ADD\_BASIC}
90 \} \textcolor{comment}{/* \_my\_conf\_descriptor\_init */}
91 
92 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
93 \_my\_conf\_descriptor\_shutdown(\textcolor{keywordtype}{void})
94 \{
95    \hyperlink{group__Eet__Data__Group_ga3e2b601720973d0e1f4683768a593c4d}{eet\_data\_descriptor\_free}(\_my\_conf\_sub\_descriptor);
96    \hyperlink{group__Eet__Data__Group_ga3e2b601720973d0e1f4683768a593c4d}{eet\_data\_descriptor\_free}(\_my\_conf\_descriptor);
97 \} \textcolor{comment}{/* \_my\_conf\_descriptor\_shutdown */}
98 
99 \textcolor{keyword}{static} My\_Conf\_Type *
100 \_my\_conf\_new(\textcolor{keywordtype}{void})
101 \{
102    My\_Conf\_Type *my\_conf = calloc(1, \textcolor{keyword}{sizeof}(My\_Conf\_Type));
103    My\_Conf\_Subtype *sub;
104    \textcolor{keywordflow}{if} (!my\_conf)
105      \{
106         fprintf(stderr, \textcolor{stringliteral}{"ERROR: could not calloc My\_Conf\_Type\(\backslash\)n"});
107         \textcolor{keywordflow}{return} NULL;
108      \}
109 
110    my\_conf->version = 0x112233;
111    my\_conf->enabled = \hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE};
112 
113    sub = calloc(1, \textcolor{keyword}{sizeof}(My\_Conf\_Subtype));
114    \textcolor{keywordflow}{if} (sub)
115      \{
116         sub->server = \hyperlink{group__Eina__Stringshare__Group_gac7a3f073cafb7af63b2c7cc2eabd1c1f}{eina\_stringshare\_add}(\textcolor{stringliteral}{"my-server.com"});
117         sub->port = 1234;
118         my\_conf->subs = \hyperlink{group__Eina__List__Group_ga92ec14d1a1040a361c4d8cd0ab7b0ecc}{eina\_list\_append}(my\_conf->subs, sub);
119      \}
120 
121    \textcolor{keywordflow}{return} my\_conf;
122 \} \textcolor{comment}{/* \_my\_conf\_new */}
123 
124 \textcolor{keyword}{static} \textcolor{keywordtype}{void}
125 \_my\_conf\_free(My\_Conf\_Type *my\_conf)
126 \{
127    My\_Conf\_Subtype *sub;
128    \hyperlink{group__Eina__List__Group_gae27a2c686a0a11693f9b06957c9bba83}{EINA\_LIST\_FREE}(my\_conf->subs, sub)
129      \{
130         \hyperlink{group__Eina__Stringshare__Group_ga4453d2aff2b325c7b45048f30df9b1f5}{eina\_stringshare\_del}(sub->server);
131         free(sub);
132      \}
133 
134    \hyperlink{group__Eina__Stringshare__Group_ga4453d2aff2b325c7b45048f30df9b1f5}{eina\_stringshare\_del}(my\_conf->name);
135    free(my\_conf);
136 \} \textcolor{comment}{/* \_my\_conf\_free */}
137 
138 \textcolor{keyword}{static} My\_Conf\_Type *
139 \_my\_conf\_load(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *filename)
140 \{
141    My\_Conf\_Type *my\_conf;
142    \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});
143    \textcolor{keywordflow}{if} (!ef)
144      \{
145         fprintf(stderr, \textcolor{stringliteral}{"ERROR: could not open '%s' for read\(\backslash\)n"}, filename);
146         \textcolor{keywordflow}{return} NULL;
147      \}
148 
149    my\_conf = \hyperlink{group__Eet__Data__Group_ga4d1807cbbc448304f22a8808318a3429}{eet\_data\_read}(ef, \_my\_conf\_descriptor, MY\_CONF\_FILE\_ENTRY);
150    \textcolor{keywordflow}{if} (!my\_conf)
151      \textcolor{keywordflow}{goto} end;
152 
153    \textcolor{keywordflow}{if} (my\_conf->version < 0x112233)
154      \{
155         fprintf(stderr,
156                 \textcolor{stringliteral}{"WARNING: version %#x was too old, upgrading it to %#x\(\backslash\)n"},
157                 my\_conf->version, 0x112233);
158 
159         my\_conf->version = 0x112233;
160         my\_conf->enabled = \hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE};
161      \}
162 
163 end:
164    \hyperlink{group__Eet__File__Group_ga1675fef1f6012c1e02ae313d13dc3e03}{eet\_close}(ef);
165    \textcolor{keywordflow}{return} my\_conf;
166 \} \textcolor{comment}{/* \_my\_conf\_load */}
167 
168 \textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
169 \_my\_conf\_save(\textcolor{keyword}{const} My\_Conf\_Type *my\_conf,
170               \textcolor{keyword}{const} \textcolor{keywordtype}{char}         *filename)
171 \{
172    \textcolor{keywordtype}{char} tmp[PATH\_MAX];
173    \hyperlink{group__Eet__File__Group_ga8d9779184a9870c1a225f1f40c76e8a7}{Eet\_File} *ef;
174    \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool} ret;
175    \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} i, len;
176    \textcolor{keyword}{struct }stat st;
177 
178    len = \hyperlink{group__Eina__String__Group_ga6bda31d2e1b6d2737b7fe1784780cd2f}{eina\_strlcpy}(tmp, filename, \textcolor{keyword}{sizeof}(tmp));
179    \textcolor{keywordflow}{if} (len + 12 >= (\textcolor{keywordtype}{int})\textcolor{keyword}{sizeof}(tmp))
180      \{
181         fprintf(stderr, \textcolor{stringliteral}{"ERROR: file name is too big: %s\(\backslash\)n"}, filename);
182         \textcolor{keywordflow}{return} \hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{EINA\_FALSE};
183      \}
184 
185    i = 0;
186    \textcolor{keywordflow}{do}
187      \{
188         snprintf(tmp + len, 12, \textcolor{stringliteral}{".%u"}, i);
189         i++;
190      \}
191    \textcolor{keywordflow}{while} (stat(tmp, &st) == 0);
192 
193    ef = \hyperlink{group__Eet__File__Group_ga5f55956b860aa2c77af9b1a880c4c256}{eet\_open}(tmp, \hyperlink{group__Eet__File__Group_ggaa8e1a7af50fefaf15eb2f69543d24998a8f395f56fba48be007c65be51d799ee9}{EET\_FILE\_MODE\_WRITE});
194    \textcolor{keywordflow}{if} (!ef)
195      \{
196         fprintf(stderr, \textcolor{stringliteral}{"ERROR: could not open '%s' for write\(\backslash\)n"}, tmp);
197         \textcolor{keywordflow}{return} \hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{EINA\_FALSE};
198      \}
199 
200    ret = \hyperlink{group__Eet__Data__Group_gac66d1c49e3490bc5d803982d833ff8aa}{eet\_data\_write}
201        (ef, \_my\_conf\_descriptor, MY\_CONF\_FILE\_ENTRY, my\_conf, \hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE});
202    \hyperlink{group__Eet__File__Group_ga1675fef1f6012c1e02ae313d13dc3e03}{eet\_close}(ef);
203 
204    \textcolor{keywordflow}{if} (ret)
205      \{
206         unlink(filename);
207         \hyperlink{evil__stdio_8h_ab92755272ef649e2c6e74ab80def85be}{rename}(tmp, filename);
208      \}
209 
210    \textcolor{keywordflow}{return} ret;
211 \} \textcolor{comment}{/* \_my\_conf\_save */}
212 
213 \textcolor{keywordtype}{int}
214 main(\textcolor{keywordtype}{int}   argc,
215      \textcolor{keywordtype}{char} *argv[])
216 \{
217    My\_Conf\_Type *my\_conf;
218    \textcolor{keyword}{const} My\_Conf\_Subtype *sub;
219    \textcolor{keyword}{const} \hyperlink{struct__Eina__List}{Eina\_List} *l;
220    \textcolor{keywordtype}{int} ret = 0;
221 
222    \textcolor{keywordflow}{if} (argc != 3)
223      \{
224         fprintf(stderr, \textcolor{stringliteral}{"Usage:\(\backslash\)n\(\backslash\)t%s <input> <output>\(\backslash\)n\(\backslash\)n"}, argv[0]);
225         \textcolor{keywordflow}{return} -1;
226      \}
227 
228    \hyperlink{group__Eina__Main__Group_gabf448ada5bc81a07342b66c6f818ee5e}{eina\_init}();
229    \hyperlink{group__Eet__Group_ga9903687bfa20fe9a9e59d4c1d213e89a}{eet\_init}();
230    \_my\_conf\_descriptor\_init();
231 
232    my\_conf = \_my\_conf\_load(argv[1]);
233    \textcolor{keywordflow}{if} (!my\_conf)
234      \{
235         printf(\textcolor{stringliteral}{"creating new configuration.\(\backslash\)n"});
236         my\_conf = \_my\_conf\_new();
237         \textcolor{keywordflow}{if} (!my\_conf)
238           \{
239              ret = -2;
240              \textcolor{keywordflow}{goto} end;
241           \}
242      \}
243 
244    printf(\textcolor{stringliteral}{"My\_Conf\_Type:\(\backslash\)n"}
245           \textcolor{stringliteral}{"\(\backslash\)tversion: %#x\(\backslash\)n"}
246           \textcolor{stringliteral}{"\(\backslash\)tname...: '%s'\(\backslash\)n"}
247           \textcolor{stringliteral}{"\(\backslash\)tid.....: %d\(\backslash\)n"}
248           \textcolor{stringliteral}{"\(\backslash\)tenabled: %hhu\(\backslash\)n"}
249           \textcolor{stringliteral}{"\(\backslash\)tsubs...:\(\backslash\)n"},
250           my\_conf->version,
251           my\_conf->name ? my\_conf->name : \textcolor{stringliteral}{""},
252           my\_conf->id,
253           my\_conf->enabled);
254 
255    \hyperlink{group__Eina__List__Group_gad02f746a08ee0b12b7ed66d4bc0d71d8}{EINA\_LIST\_FOREACH}(my\_conf->subs, l, sub)
256      printf("\(\backslash\)t\(\backslash\)tserver: '%s', port: %d\(\backslash\)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    \hyperlink{group__Eet__Group_gacbc7583179399d3b3e7b003e911f866f}{eet\_shutdown}();
268    \hyperlink{group__Eina__Main__Group_ga6741fcaba116e31e96ce14dcfa03f568}{eina\_shutdown}();
269 
270    return ret;
271 \} \textcolor{comment}{/* main */}
272 
\end{DoxyCodeInclude}
 