svn update: 51457 (latest:51480)
[framework/uifw/eet.git] / src / examples / eet-data-simple.c
1 #include <Eina.h>
2 #include <Eet.h>
3 #include <stdio.h>
4 #include <limits.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <unistd.h>
8
9 // The struct that will be loaded and saved.
10 // note that only the members described in the eet_data_descriptor
11 // will be automatically handled. The other members will have their
12 // space reserved and zeroed (as it uses calloc()), but not
13 // saved or loaded from eet files.
14 typedef struct
15 {
16    unsigned int version; // it is recommended to use versioned configuration!
17    const char * name;
18    int          id;
19    int          not_saved_value; // example of not saved data inside!
20    Eina_Bool    enabled;
21 } My_Conf_Type;
22
23 // string that represents the entry in eet file, you might like to have
24 // different profiles or so in the same file, this is possible with
25 // different strings
26 static const char MY_CONF_FILE_ENTRY[] = "config";
27
28 // keep the descriptor static global, so it can be
29 // shared by different functions (load/save) of this and only this
30 // file.
31 static Eet_Data_Descriptor * _my_conf_descriptor;
32
33 static void
34 _my_conf_descriptor_init(void)
35 {
36    Eet_Data_Descriptor_Class eddc;
37
38    // The class describe the functions to use to create the type and its
39    // full allocated size.
40    //
41    // Eina types are very convenient, so use them to create the descriptor,
42    // so we get eina_list,  eina_hash and eina_stringshare automatically!
43    //
44    // The STREAM variant is better for configuration files as the values
45    // will likely change a lot.
46    //
47    // The other variant, FILE, is good for caches and things that are just
48    // appended, but needs to take care when changing strings and files must
49    // be kept open so mmap()ed strings will be kept alive.
50    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Conf_Type);
51    _my_conf_descriptor = eet_data_descriptor_stream_new(&eddc);
52
53    // Describe the members to be saved:
54    // Use a temporary macro so we don't type a lot, also avoid errors:
55 #define MY_CONF_ADD_BASIC(member, eet_type)\
56    EET_DATA_DESCRIPTOR_ADD_BASIC\
57       (_my_conf_descriptor, My_Conf_Type, # member, member, eet_type)
58
59    MY_CONF_ADD_BASIC(version, EET_T_UINT);
60    MY_CONF_ADD_BASIC(name,    EET_T_STRING);
61    MY_CONF_ADD_BASIC(id,      EET_T_INT);
62    MY_CONF_ADD_BASIC(enabled, EET_T_UCHAR);
63
64 #undef MY_CONF_ADD_BASIC
65 } /* _my_conf_descriptor_init */
66
67 static void
68 _my_conf_descriptor_shutdown(void)
69 {
70    eet_data_descriptor_free(_my_conf_descriptor);
71 } /* _my_conf_descriptor_shutdown */
72
73 static My_Conf_Type *
74 _my_conf_new(void)
75 {
76    My_Conf_Type * my_conf = calloc(1, sizeof(My_Conf_Type));
77    if (!my_conf)
78      {
79         fprintf(stderr, "ERROR: could not calloc My_Conf_Type\n");
80         return NULL;
81      }
82
83    my_conf->version = 0x112233;
84    my_conf->enabled = EINA_TRUE;
85    return my_conf;
86 } /* _my_conf_new */
87
88 static void
89 _my_conf_free(My_Conf_Type * my_conf)
90 {
91    eina_stringshare_del(my_conf->name);
92    free(my_conf);
93 } /* _my_conf_free */
94
95 static My_Conf_Type *
96 _my_conf_load(const char * filename)
97 {
98    My_Conf_Type * my_conf;
99    Eet_File * ef = eet_open(filename, EET_FILE_MODE_READ);
100    if (!ef)
101      {
102         fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
103         return NULL;
104      }
105
106    my_conf = eet_data_read(ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY);
107    if (!my_conf)
108       goto end;
109
110    if (my_conf->version < 0x112233)
111      {
112         fprintf(stderr,
113                 "WARNING: version %#x was too old, upgrading it to %#x\n",
114                 my_conf->version, 0x112233);
115
116         my_conf->version = 0x112233;
117         my_conf->enabled = EINA_TRUE;
118      }
119
120 end:
121    eet_close(ef);
122    return my_conf;
123 } /* _my_conf_load */
124
125 static Eina_Bool
126 _my_conf_save(const My_Conf_Type * my_conf, const char * filename)
127 {
128    char tmp[PATH_MAX];
129    Eet_File * ef;
130    Eina_Bool ret;
131    unsigned int i, len;
132    struct stat st;
133
134    len = eina_strlcpy(tmp, filename, sizeof(tmp));
135    if (len + 12 >= (int)sizeof(tmp))
136      {
137         fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
138         return EINA_FALSE;
139      }
140
141    i = 0;
142    do
143      {
144         snprintf(tmp + len, 12, ".%u", i);
145         i++;
146      }
147    while (stat(tmp, &st) == 0);
148
149    ef = eet_open(tmp, EET_FILE_MODE_WRITE);
150    if (!ef)
151      {
152         fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
153         return EINA_FALSE;
154      }
155
156    ret = eet_data_write
157          (ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY, my_conf, EINA_TRUE);
158    eet_close(ef);
159
160    if (ret)
161      {
162         unlink(filename);
163         rename(tmp, filename);
164      }
165
166    return ret;
167 } /* _my_conf_save */
168
169 int main(int argc, char * argv[])
170 {
171    My_Conf_Type * my_conf;
172    int ret = 0;
173
174    if (argc != 3)
175      {
176         fprintf(stderr, "Usage:\n\t%s <input> <output>\n\n", argv[0]);
177         return -1;
178      }
179
180    eina_init();
181    eet_init();
182    _my_conf_descriptor_init();
183
184    my_conf = _my_conf_load(argv[1]);
185    if (!my_conf)
186      {
187         printf("creating new configuration.\n");
188         my_conf = _my_conf_new();
189         if (!my_conf)
190           {
191              ret = -2;
192              goto end;
193           }
194      }
195
196    printf("My_Conf_Type:\n"
197           "\tversion: %#x\n"
198           "\tname...: '%s'\n"
199           "\tid.....: %d\n"
200           "\tenabled: %hhu\n",
201           my_conf->version,
202           my_conf->name ? my_conf->name : "",
203           my_conf->id,
204           my_conf->enabled);
205
206    if (!_my_conf_save(my_conf, argv[2]))
207       ret = -3;
208
209    _my_conf_free(my_conf);
210
211 end:
212    _my_conf_descriptor_shutdown();
213    eet_shutdown();
214    eina_shutdown();
215
216    return ret;
217 } /* main */
218